Back to Blog
DevelopmentSep 12, 202612 min read

MCP Context Bloat: The 67,000 Tokens You Pay Before "Hello"

NT

Nikhil Tiwari

MCP Playground

๐Ÿ“– TL;DR

  • Seven MCP servers consume 67,300 tokens of tool definitions โ€” 33.7% of a 200K context window โ€” before the user types anything.
  • GitHub's MCP server alone measures around 18,000 tokens. Notion is roughly 9,000. Filesystem about 3,500.
  • Every tool schema is re-sent on every request. Tools you never call still bill you, every turn.
  • Anthropic's Tool Search Tool cut token usage about 85% and raised tool-selection accuracy.
  • Cloudflare's Code Mode reported roughly 99.9% input-token reduction on a 2,500-endpoint API.
  • The pattern behind all of them is the same: defer the schema until the model reaches for the tool.
  • Server authors own a real share of this. Fewer, better tools beat more tools.

I connected five MCP servers to an agent and watched the first request cost real money before the model read a single word of the prompt.

Nothing was broken. That was the bill for saying hello.

MCP context bloat is the tax you pay for every tool you enabled and never called. Tool definitions go into the system prompt. The system prompt is re-sent every turn. The model pays attention to all of it.

The measured numbers are worse than most people guess. Seven MCP servers add up to 67,300 tokens โ€” a third of a 200K window โ€” sitting there before the conversation starts.

The good news is that 2026 produced three real fixes, with published numbers behind them. Tool search. Code mode. And a set of server-side changes you control without touching the client.

I'll go through what each one actually does, the exact API shapes, where they break, and how to measure your own servers in about ten minutes.

If MCP itself is new to you, my introduction to the Model Context Protocol is the better starting point.

How Bad Is MCP Context Bloat, Really?

Numbers first, because the abstraction hides how bad this is.

What is connected Tool-definition tokens
Filesystem MCP ~3,500
Notion MCP ~9,000
GitHub MCP ~18,000
Seven typical servers 67,300
Cloudflare's full API as MCP ~1,170,000

That 67,300 figure comes from a community measurement filed against Claude Code in November 2025. It is 33.7% of a 200K context window, spent before the user types.

The Cloudflare number is not a typo. Wrapping an API with 2,500 or more endpoints as MCP tools produces over a million tokens of schema โ€” more than most context windows hold.

Now multiply by turns. A twenty-turn conversation re-sends those 67,300 tokens twenty times.

Prompt caching blunts the cost but not the problem. Cached tokens are cheaper, not free, and caching does nothing about the context window space those schemas occupy.

The space is the part people miss. Every token of unused tool schema is a token your actual document, codebase or conversation history cannot use.

Why Every Tool Schema Loads on Every Single Request

This surprises people, so it is worth being precise.

The model is stateless. Each request carries the full picture: system prompt, tool definitions, entire message history.

There is no "the model already knows about my tools from last time."

So the flow goes: the client calls tools/list on each connected server, collects every tool's name, description and full JSON Schema, and injects all of it into the request.

A tool you have never called in six months still ships on every single turn.

It gets heavier with the 2026-07-28 spec, which brought full JSON Schema 2020-12 support in tool inputs โ€” oneOf, anyOf, allOf, $ref. More expressive schemas are genuinely better. They are also bigger.

One partial relief arrived in the same release. List results are now cacheable, carrying ttlMs and cacheScope, so clients can stop re-fetching tools/list constantly.

But that saves round-trips, not context. The schemas still go into the prompt.

Bloat Costs You Accuracy, Not Just Money

Here is the part that reframes the whole problem.

Most teams treat this as a cost issue. It is a quality issue first.

Fewer visible tools, better choices

When Anthropic measured its Tool Search Tool, accuracy on tool selection went up, not down. Claude Opus 4 moved from 49% to 74%. Claude Opus 4.5 moved from 79.5% to 88.1%.

Read that again. Showing the model fewer tools made it choose better.

That makes sense once you stop thinking about token budgets. Thirty near-identical tool descriptions are a disambiguation problem. create_issue, create_ticket, new_task and add_item all look plausible for "file a bug".

Removing the noise removes the wrong choices.

So the framing is not "pay less for the same result." It is "pay less and get a better result." That is rare enough to act on.

This is also why tool description quality matters more than tool count. Ten sharp descriptions beat forty vague ones on both axes.

Fix 1 โ€” MCP Tool Search and Deferred Loading

Tool search replaces "here are all 200 tools" with "here is a search box and 200 tools behind it."

Anthropic shipped the Tool Search Tool in November 2025, reporting an 85% reduction in token usage while maintaining access to the full tool library. It went generally available in February 2026 alongside programmatic tool calling.

The client keeps a lightweight index โ€” tool names and one-line summaries โ€” and loads a tool's full definition only when the model reaches for it.

How to wire it up

Two server tool types are available, and you pick one:

  • tool_search_tool_regex_20251119 โ€” name tool_search_tool_regex
  • tool_search_tool_bm25_20251119 โ€” name tool_search_tool_bm25

Then mark the tools you want held back with defer_loading: true on the tool definition.

tools array
{
  "tools": [
    { "type": "tool_search_tool_bm25_20251119", "name": "tool_search_tool_bm25" },
    { "name": "get_invoice", "description": "...", "input_schema": {}, "defer_loading": true },
    { "name": "list_customers", "description": "...", "input_schema": {} }
  ]
}

Results come back as a tool_search_tool_result block. The model then calls the tool normally.

BM25 is the better default โ€” it ranks by relevance across names and descriptions. Regex is for when you have a strict naming convention and want exact control.

The 400 error everyone hits

Never defer everything

The search tool itself must not carry defer_loading: true, and at least one tool in the array must stay non-deferred. Otherwise the API returns a 400: All tools have defer_loading set.

It trips almost everyone once. The mental model that avoids it: leave your two or three highest-traffic tools loaded, defer the long tail.

Clients are starting to do this for you. Claude Code auto-activates MCP tool search when tool definitions exceed 10% of the context window, loading tools on demand rather than all at once.

Which tool the model reaches for still depends on the model. If you are choosing one, my comparison of the best AI model for MCP tool calling has the practical differences.

Fix 2 โ€” Code Mode and Programmatic Tool Calling

Tool search trims the menu. Code mode throws out the menu and hands the model a programming interface.

Instead of exposing 2,500 tools, you expose something closer to a search() and execute() pair. The model writes code that calls your API, rather than picking from a list of pre-declared tools.

The reported numbers are extreme:

  • Anthropic, code execution with MCP (November 2025): 150,000 tokens down to 2,000. A 98.7% reduction.
  • Cloudflare, Code Mode (February 2026): roughly 99.9% input-token reduction across an API with 2,500 or more endpoints.

On the Anthropic API side, programmatic tool calling is what lets Claude call your custom tool from inside code execution. You declare the code execution tool and add allowed_callers pointing at it on the custom tool you want callable.

โš ๏ธ The caveat most write-ups skip

Programmatic tool calling is not compatible with MCP tools. It also does not combine with strict tool use, disabled parallel tool use, or a forced tool choice. Code mode is a pattern you implement around your own API, not a switch you flip on an existing MCP server.

The trade is real. You gain enormous token savings and lose the declarative safety of per-tool schemas. Generated code needs a sandbox, a timeout and an allowlist.

Worth it at 2,500 endpoints. Almost certainly not worth it at twelve.

Fix 3 โ€” The Server-Side Fixes You Actually Control

Tool search and code mode are mostly client-side. If you publish an MCP server, these are yours โ€” and they help every client, including ones that support neither fix above.

1. Ship fewer, wider tools. Twelve narrow tools โ€” get_user, get_user_by_email, get_user_by_id, list_users โ€” usually collapse into two with a decent filter argument. Every merge removes a full schema and a disambiguation decision.

2. Cut the description to what the model needs to choose. Descriptions are prose in a system prompt. A 300-word description with usage examples and changelog notes is 300 words in every request. Say what the tool does and when to pick it, then stop.

3. Flatten the schema. Deeply nested JSON Schema with $ref chains serializes large. Full JSON Schema 2020-12 support makes expressive schemas possible, not mandatory.

4. Offer a progressive-disclosure endpoint. This is a real shipped pattern, not theory. TikTok's ads MCP server ships in two flavours: a full-disclosure endpoint loading around 400 tools at once, and a progressive-disclosure endpoint loading around 40 core tools with the rest discoverable on demand.

That is a server author making the client's context problem smaller without the client doing anything.

5. Set sane ttlMs and cacheScope on list results. New in 2026-07-28. It will not shrink your prompt, but it stops clients re-fetching a list that changes twice a year.

If you are building or refactoring a server around the current spec, my guide to building an MCP server on the 2026 spec covers the structure.

See exactly what your server sends back

Connect in the browser and read the raw tools/list response. That JSON is, near enough, what lands in your prompt on every single turn.

Which Fix Should You Use?

Situation Use
10โ€“30 tools, one or two servers Server-side cleanup. Nothing else.
30โ€“150 tools across several servers Tool search with defer_loading
Wrapping a large existing API (500+ endpoints) Code mode / programmatic calling
You publish a server others connect to Fewer tools + a progressive-disclosure endpoint
You are the client, servers are not yours Tool search, and disable servers you do not use

Start at the top of that table, not the bottom. I have watched teams reach for code mode when the actual fix was deleting nine redundant tools.

The cheapest token is the schema you never wrote.

How to Measure Your Own Bloat in 10 Minutes

Do not guess. The measurement is quick.

1. Pull the raw tools/list response from each connected server. That JSON is, near enough, what lands in your prompt.

2. Count the tokens. Use your model provider's token-counting endpoint rather than a generic tokenizer โ€” counts differ per model family and the gap is not small.

3. Divide by your context window. Above 10% is where clients like Claude Code start intervening automatically. Treat that as your own threshold too.

4. Rank tools by tokens-per-call. Pull a week of usage. Any tool with high schema cost and zero calls is pure waste โ€” turn it off.

5. Re-measure after each change. Deleting a tool that was 4,000 tokens of nested schema feels identical until you look at the number.

My MCP token counter walkthrough goes deeper on steps 2 and 3.

Five Mistakes That Make MCP Context Bloat Worse

1. Enabling servers "just in case." The most common one by far. Each idle server costs 500 to 2,000 tokens minimum, and the heavy ones cost ten times that. Enable what this project needs.

2. Assuming prompt caching solved it. Caching cuts the price of re-sending schemas. It does not give you back the context window space, and it does not stop thirty similar tools from confusing the model.

3. Deferring every tool. The API rejects it with All tools have defer_loading set. Keep the search tool and at least one real tool loaded.

4. Writing tool descriptions for humans. Changelogs, credits and worked examples in a description field are pure prompt weight. The model needs to know what the tool does and when to pick it.

5. Adding a tool instead of an argument. export_csv, export_json and export_xml are one tool with a format argument. This is the single biggest source of avoidable schema, and it compounds every release.

If you are running many servers through one entry point, a gateway helps you apply these centrally โ€” see my MCP gateway guide.

Prune Before You Optimise

MCP context bloat is measurable, it is large, and it costs you accuracy as well as money. Seven servers can spend a third of your context window before the conversation begins.

The fixes stack. Clean up the server, defer the long tail with tool search, and reach for code mode only when you are wrapping something genuinely enormous.

Measure first. Most teams find the biggest win is a tool list that grew without anyone pruning it.

And once the list is lean, check the tools still behave โ€” how to test MCP servers step by step covers the regression pass.

FAQ

How many MCP servers should I enable at once?+
Three to five for most work. Each connected server adds roughly 500 to 2,000 tokens of tool definitions at minimum, and large ones like the GitHub MCP server measure around 18,000 tokens on their own. Past five servers, enable tool search so schemas load on demand rather than all at once.
Does MCP tool search make the model worse at picking tools?+
Measured results say the opposite. Anthropic reported tool-selection accuracy rising from 49% to 74% on Claude Opus 4 and from 79.5% to 88.1% on Claude Opus 4.5 with the Tool Search Tool enabled. Showing the model fewer, more relevant tools removes the disambiguation problem created by dozens of near-identical descriptions.
Can I use programmatic tool calling with my MCP server?+
No. Programmatic tool calling is explicitly not compatible with MCP tools, and it also does not combine with strict tool use, disabled parallel tool use or a forced tool choice. Code mode is a pattern you build around your own API surface, not a flag you set on an existing MCP server.
Do cacheable list results fix MCP context bloat?+
No. The ttlMs and cacheScope fields added in the 2026-07-28 revision reduce how often clients re-fetch tools/list over the network. They save round-trips, not context. Every tool schema still enters the system prompt on every request to the model.
Is MCP context bloat a client problem or a server problem?+
Both, and server authors have more control than they think. Merging redundant tools, trimming descriptions to what the model needs in order to choose, and flattening nested schemas help every client that connects, including ones with no tool-search support at all. Offering a progressive-disclosure endpoint goes further still.
What is the fastest single win against MCP token bloat?+
Delete or merge redundant tools. It costs nothing, requires no client feature, works on every model, and improves tool-selection accuracy at the same time. Tools that differ only by a filter or a format almost always collapse into one tool with an argument.
NT

Written by Nikhil Tiwari

15+ years in product development. AI enthusiast building developer tools that make complex technologies accessible to everyone.

Build, compare & ship MCP agents

Connect any MCP server, run evals on it, compare 60+ models side-by-side, deploy hosted servers, and save reusable agents you can export as an API โ€” all in your browser.

Try for Free โ†’
MCP Context Bloat: The 67,000 Tokens You Pay Before "Hello"