Defer Oversized MCP Tool Schemas by Size - #16179
Open
aligulzar729 wants to merge 3 commits into
Open
aligulzar729 wants to merge 3 commits into
aligulzar729 wants to merge 3 commits into
Conversation
aligulzar729
force-pushed
the
feat/mcp-defer-schema-size
branch
from
September 22, 2026 03:32
d2f239c to
85856a7
Compare
aligulzar729
force-pushed
the
feat/mcp-defer-schema-size
branch
from
September 22, 2026 04:01
85856a7 to
bbc923b
Compare
aligulzar729
force-pushed
the
feat/mcp-defer-schema-size
branch
from
September 22, 2026 04:08
bbc923b to
f7ab8dc
Compare
Collaborator
|
@aligulzar729 thanks for the PRs! Will review when I get a chance |
aligulzar729
force-pushed
the
feat/mcp-defer-schema-size
branch
from
September 24, 2026 03:23
0c0593a to
6616e6d
Compare
aligulzar729
force-pushed
the
feat/mcp-defer-schema-size
branch
from
September 24, 2026 04:30
2c07bd3 to
9d4b1b3
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
What this changes: an MCP tool whose argument schema is larger than
mcpSettings.deferSchemaCharscharacters of JSON starts deferred, so the model sees only its name and pulls the schema in throughtool_searchwhen it needs it. It needs the agentsdeferred_toolscapability. Default0, which is off. No network call, no new dependency.I run a self-hosted instance with a large MCP catalog. A few tools dominate it: two tools from one server serialize to about 287,000 characters each against descriptions of 150 and 261 characters, roughly two thirds of the whole tool surface, paid on every turn.
Measured on my own catalog: 8 connected servers, 202 tools, 239,613 tokens of definitions, of which 92.6% is argument schemas. Everything else, which is what a turn still pays once schemas are withheld, is 17,822 tokens: the names and descriptions the model needs to decide whether to call a tool, plus the JSON scaffolding around each definition.
One server with 12 tools is 67% of the catalog, and one schema inside it is 79,699 tokens on its own. Capping by size removes that without touching the other 190 tools.
Deferred loading already solves this, but only per tool and by hand, so you have to find the expensive ones before you can hide any of them.
mcpSettings.deferSchemaCharsapplies it by measured size instead. Default0disables the rule, so nothing changes for an instance that does not set it.Related to #13951 and #15713, which default deferral by server and by agent. This defers by cost, and the precedence chain is compatible with both.
How it works
A per-tool toggle always wins, in either direction, so the rule is safe to set instance-wide. The size is counted in characters, which is closer to the tokens it saves than bytes would be. Applied in both registry branches, so agents with no
tool_optionsare covered too.Agent builder.
GET /api/mcp/toolsmarks each tool the rule would defer withdeferredBySize: true. In the tool dialog that tool's existing defer toggle shows as on, with the tooltip "Deferred automatically because this tool's schema is larger than the server's size limit. Click to keep it loaded instead." Switching it off storesdefer_loading: false, which keeps the tool loaded; switching it back on clears that, so the tool follows the rule again. Tools the rule does not touch store exactly what they did before, and "Defer all tools" counts size-deferred tools as deferred. No new component: it reusesOptionToggle, its pressed style andTooltipAnchor, with one new English string.Testing
How the catalog was measured: a read-only script against my own instance reading
GET /api/mcp/serversand summing, per tool,name.length + description.length + JSON.stringify(parameters).length. Tokens are characters / 3.6. Server names are anonymized above; the shape is what matters.Added 16 cases to
classification.spec.ts: rule off reproducing current behavior, an explicitfalsepinning a large tool open, an explicittruehiding a small one, unrelatedtool_optionsstill falling under the rule, an unserializable schema counted as weightless, andbuildToolClassificationfor an agent with notool_options(the oversized tool defers and bringstool_search; withdeferred_toolsoff every tool stays callable).useMCPToolOptions.spec.tscovers the builder states in the table above, including "Defer all", andmcp.spec.jschecks thatGET /api/mcp/toolsmarks only the oversized tool.cd packages/api && npx jest src/tools/classification src/tools/definitionspasses 98,cd api && npx jest server/services/__tests__/ToolServicepasses 140,cd api && npx jest server/routes/__tests__/mcp.spec.js -t "GET /tools"passes 9, andcd client && npx jest src/hooks/Agents/__tests__/useMCPToolOptions.spec.ts src/components/SidePanel/Agentspasses 574. Checked in the browser against a 25-tool Playwright server withdeferSchemaChars: 300.npx tsc --noEmitclean forpackages/api,data-provideranddata-schemas, andnpm run typecheckclean forclient.Risk / compatibility
No-op by default. One
JSON.stringifyper MCP tool at registry build.Type of change
Checklist