2026.09.9
Pre-releaseBreaking
-
Make discovery a tool, and generate the surface from one catalogue (06945d2d)
The MCP tool listing is sent to a model on every conversation that touches
Studio, before it has asked for anything. It is now 1696 tokens across 13 tools,
down from 2115 across 14 — a fifth off every session — and it gained a discovery
tool while shrinking.studio_helpis the new route to the detail the schemas leave out. Call it with
no topic for an index of every tool, or with a tool name for that tool's accepted
values, JSON body shapes and semantics.ADR-0050 had put that detail in the
studio://toolsresource, on the reasoning
that a host fetches a resource once and keeps it. That is true of hosts that read
resources.resourcesis an optional server capability and nothing in the MCP
specification obliges a client to callresources/read— ever. On a host that
skips them, ADR-0050 did not make discovery progressive; it made it absent, and a
model was left inferring valid values by triggering rejections. Tools are the one
part of MCP every host implements, so the detail moved behind one.studio://tools
remains as a generated mirror that nothing depends on.Because that channel is now reliable, every other schema dropped the hedging text
it carried in case the resource was never read — spelled defaults, type codes,
"see studio://tools" pointers. The help tool costs about thirty-five tokens and
licensed stripping several hundred, which is why the listing is smaller despite
being one tool larger.Rejections now name
studio_helpalongside the values they would have accepted,
so a wrong guess is a recovery rather than a retry loop.The server
instructionsblock is generated from the same catalogue instead of
being retyped inapplication.yml. The hand-written one had already drifted: it
omittedqueue_lifecycleandmessage_bodyand never named a discovery route.
Under a host that searches tools rather than sending the whole listing, that text
is the only thing guaranteed to be read, so a stale copy did not merely go out of
date — it told a model that two capabilities the product has did not exist. The
build now fails when a registered tool is missing from the catalogue.Two further checks are enforced: no tool may declare itself both read-only and
destructive, and a tool's declared posture must match the catalogue's. A host
gates a whole tool on onedestructiveHint, so a read reachable through a tool
that can purge would make every read prompt the operator — which is how an
operator is trained to reflex-approve the purge.The budget ceilings ratchet down with the win rather than banking it as headroom:
per-tool 200 → 175, average 160 → 135, calibrated against a measured run.
Added
-
Make discovery a tool, and generate the surface from one catalogue (06945d2d)
The MCP tool listing is sent to a model on every conversation that touches
Studio, before it has asked for anything. It is now 1696 tokens across 13 tools,
down from 2115 across 14 — a fifth off every session — and it gained a discovery
tool while shrinking.studio_helpis the new route to the detail the schemas leave out. Call it with
no topic for an index of every tool, or with a tool name for that tool's accepted
values, JSON body shapes and semantics.ADR-0050 had put that detail in the
studio://toolsresource, on the reasoning
that a host fetches a resource once and keeps it. That is true of hosts that read
resources.resourcesis an optional server capability and nothing in the MCP
specification obliges a client to callresources/read— ever. On a host that
skips them, ADR-0050 did not make discovery progressive; it made it absent, and a
model was left inferring valid values by triggering rejections. Tools are the one
part of MCP every host implements, so the detail moved behind one.studio://tools
remains as a generated mirror that nothing depends on.Because that channel is now reliable, every other schema dropped the hedging text
it carried in case the resource was never read — spelled defaults, type codes,
"see studio://tools" pointers. The help tool costs about thirty-five tokens and
licensed stripping several hundred, which is why the listing is smaller despite
being one tool larger.Rejections now name
studio_helpalongside the values they would have accepted,
so a wrong guess is a recovery rather than a retry loop.The server
instructionsblock is generated from the same catalogue instead of
being retyped inapplication.yml. The hand-written one had already drifted: it
omittedqueue_lifecycleandmessage_bodyand never named a discovery route.
Under a host that searches tools rather than sending the whole listing, that text
is the only thing guaranteed to be read, so a stale copy did not merely go out of
date — it told a model that two capabilities the product has did not exist. The
build now fails when a registered tool is missing from the catalogue.Two further checks are enforced: no tool may declare itself both read-only and
destructive, and a tool's declared posture must match the catalogue's. A host
gates a whole tool on onedestructiveHint, so a read reachable through a tool
that can purge would make every read prompt the operator — which is how an
operator is trained to reflex-approve the purge.The budget ceilings ratchet down with the win rather than banking it as headroom:
per-tool 200 → 175, average 160 → 135, calibrated against a measured run.