July 15, 2026 · The MCPCloud team
Taming MCP context bloat with wrapper discovery
Registering hundreds of tools floods the context window with schemas the model never calls. Wrapper discovery trades a round-trip for the budget back.
Every tool an MCP server registers costs context before the conversation starts. The name, the description, and the full JSON Schema for every parameter all ride along in tools/list, and most clients put all of it in front of the model on every turn — whether the session touches three of those tools or none of them.
For a hand-built server with eight tools, that is noise. For a server generated from a real API spec, it is the dominant cost. Ingest a large vendor API and even an aggressively curated surface lands at dozens of tools, each carrying a schema with nested objects, enums, and per-field descriptions. The model pays for all of it up front, and it pays again on every request. The schemas it never uses are pure overhead.
The problem in one sentence
tools/list is an eager protocol: it ships every schema whether or not the conversation will ever need it.
Two discovery modes
Every server MCPCloud generates ships with a per-server discovery mode, switchable from the server’s overview page. There are exactly two:
- All tools — “Register every tool on the server. Clients see the full list in tools/list.” The default, and the standard MCP behavior.
- Wrapper (search) — “Expose three tools — searchTools, getToolDefinition, useTool. Schemas are fetched on demand to cut token usage on large servers.”
In wrapper mode the server registers exactly three protocol-level tools, and the real catalog sits behind them. Here is what the model actually sees — these are the deployed descriptions, verbatim:
{
"tools": [
{
"name": "searchTools",
"title": "Search tools",
"description": "Find tools on this server by keyword or /regex/. Returns matching tool names and summaries WITHOUT their full input schemas, to save tokens. Call getToolDefinition for a tool's input schema, then useTool to run it."
},
{
"name": "getToolDefinition",
"title": "Get tool definition",
"description": "Fetch the full definition (input schema, description) for one tool by exact name. Discover names with searchTools first."
},
{
"name": "useTool",
"title": "Use tool",
"description": "Execute a tool by exact name with its arguments. Get the argument shape from getToolDefinition first."
}
]
}The flow is search, fetch, execute. The descriptions chain into each other deliberately, and the error paths close the loop: call useTool or getToolDefinition with a name that does not exist and the error text points back to searchTools. A model that wanders off the happy path gets steered back onto it by the tool results themselves.
How the search works
searchTools runs Okapi BM25 keyword ranking (standard k1 = 1.5, b = 0.75 parameters) over each tool’s name, title, description, and semantic tags. The index is built in-process from a catalog embedded in the server bundle itself — no external search service, no extra network hop, no cold dependency — and memoized after the first query. The search is hybrid: a /pattern/flags query switches to regex matching, an empty query returns a plain directory listing of the first N tools, and a substring fallback catches exact-name lookups that BM25 scoring misses.
Keyword search rather than embeddings is a deliberate choice. It is deterministic, dependency-free, and runs anywhere the generated server runs. It also means discovery quality rides on description quality — which is exactly what the ingestion-time enrichment pass is for. A catalog of well-written, well-tagged descriptions is a good BM25 corpus almost by accident.
The trade-offs, honestly
What you save: the per-turn cost of every schema the session never touches. In wrapper mode the model carries three small tool definitions instead of the whole catalog, and pulls a full schema only for the tools it actually decides to use. On a large server where a typical session exercises a handful of tools, the schemas are most of the listing payload — that is the bulk of what wrapper mode removes. We have not published benchmark numbers, and the honest answer is that the saving scales with your tool count and schema size: a 200-tool server saves a lot, a 10-tool server saves close to nothing.
What you pay: up to two extra round-trips (search, then fetch the definition) before the first real call, and a layer of indirection the model has to reason through. Clients and UIs that key off tools/list — command palettes, static tool pickers, allowlist tooling — see three generic tools instead of your catalog. And a mediocre search query can surface the wrong tool where a full listing would have put the right one directly in front of the model.
- Prefer All tools when the server is small — the product nudges you toward wrapper mode at 20 tools and up, because below that the listing cost rarely dominates.
- Prefer All tools for deterministic pipelines that call known tool names on a fixed path — discovery is pure overhead when nothing needs discovering.
- Prefer Wrapper (search) for large generated servers, exploratory agent sessions, and multi-server setups where several catalogs would otherwise stack in one context window.
Flipping the switch
Discovery mode is a one-click setting on the server’s overview page, and it applies on the next deploy or bundle regeneration — the mode is compiled into the generated server, not proxied at request time. Wrapper discovery is currently in beta while we finish live-deployment verification; the runtime behavior described above is what ships in generated bundles today.
The takeaway
Pay for schemas when the conversation needs them, not on every turn. For large servers, lazy discovery is the difference between a usable catalog and a context-window tax.
If you want to see the difference on your own API, paste a spec at mcpcloud.sh — the free tier goes from import to a live deployment, and the discovery-mode switch is on every generated server. Because the server keeps running on the platform, the choice is measurable, not theoretical: per-tool usage in the dashboard shows exactly which tools your sessions touch — and which schemas you were paying for out of habit.