Your MCP tools eat the context before any work starts

18 August 2026

MCP Tool Definition Linter What your tool list costs every request. Runs in your browser.

Connecting an MCP server does not add a capability your agent uses when needed. It adds text to the front of every single request, forever. Tool definitions are a fixed cost per turn, and they are paid whether or not any tool is called.

That is the part the mental model usually gets wrong. People reason about tools the way they reason about installed software: idle until invoked, cheap to have around. In an agent the opposite is true. A tool that is never called still occupies context on every turn, still competes for the model’s attention, and still costs money on every request.

The arithmetic

A tool definition is a name, a description, and a JSON Schema with a description per property. Serialized, a modest one lands somewhere around 200 to 500 tokens, and a rich one with a dozen parameters and careful documentation runs well past that.

Multiply it out and the number stops being abstract quickly:

ConnectedToolsTokens before your first word
One small server8roughly 2,000 to 4,000
Three servers30roughly 9,000 to 15,000
Five servers60roughly 18,000 to 30,000
The GitHub MCP server alone~90reported at about 42,000

Industry write-ups through 2026 put multi-server setups at 40 to 50% of the context window consumed before the agent does any work, and the working consensus for how many servers you can connect before quality falls off sits at about five to seven.

Two things follow from this that are worth stating separately, because people usually notice only the first.

The cost is per request, not per session. Every turn resends the whole tool list. A 30,000 token tool preamble on a 40 turn conversation is 1.2 million input tokens spent describing tools, most of which were never called.

The cost is paid in attention as well as in tokens. This is the part that does not show up on a bill.

How it shows up

Not as an error. That is what makes it expensive to diagnose.

An agent that is drowning in tool definitions does not fail. It gets slightly worse, in ways that read as model quality problems:

  • It calls a plausible tool that is not the right one, particularly where two servers offer similar verbs.
  • It invents a tool name that sounds like several real ones.
  • It stops following an instruction from your system prompt, because that prompt is now a small fraction of a very large preamble.
  • It gets slower and more expensive per turn, and nobody attributes it to the integration that shipped three weeks ago.

The tell is the timeline. Agent quality that degraded after an integration landed, rather than after a model change, is usually this.

Why the first instinct is wrong

The first instinct is to write better descriptions. That is genuinely worth doing, and the tool definition linter exists partly for it, but it does not solve this problem and can make it worse.

Better descriptions are usually longer descriptions. Adding “call this when the user asks about X, but not when they mean Y” to forty tools improves each individual choice and inflates the preamble that is causing the trouble. You can easily end up with a more expensive agent that is no more accurate.

The second instinct is to raise the context window, moving to a model with a larger one. That relieves the pressure and does nothing about attention: a model choosing between 60 tools is choosing between 60 tools regardless of how much room the list has to sit in. It also raises the bill rather than lowering it.

The thing that actually works is reducing how many tools are in front of the model at once. Everything below is a variation on that.

Four ways to cut it, and what each costs

ApproachWhat it doesWhat it costs
Disconnect serversRemoves whole tool sets from the preambleSomebody has to decide what is not needed, and they will be wrong occasionally
Filter tools per clientKeeps the server, exposes a subset. Most clients support an allowlistMaintenance per client and per project, and it drifts
Sub-agents with narrow toolsetsAn orchestrator routes to an agent that holds only the tools for its jobReal architecture: routing, handoffs, more moving parts
Dynamic or searchable toolsetsThe agent discovers tools on demand rather than holding all of themA round trip before the first call, and a dependency on a server that supports it

There is a fifth that deserves separate mention because it changes the shape of the problem rather than the size: have the model write code that calls the tools, rather than exposing every tool for direct invocation. Instead of forty tool definitions, the model gets an interface and writes a short program against it. Vendors reporting on this have claimed very large reductions, and the trade-off is real: you have gained a code execution surface, and that decision is a security decision as much as a token one.

The practical order for most teams is boring and effective: disconnect what you do not use, filter what you do, and only reach for architecture when you have done both.

What to measure

Two numbers, and neither needs new infrastructure.

The serialized size of your tool preamble. Take the tools/list response from each connected server, concatenate them, and measure. Bytes are exact and you can get them today; tokens are roughly bytes over four for English JSON, and if you want the real figure, run the same string through the provider’s token counting endpoint. That is precisely what the tool definition linter reports, along with the tools whose descriptions are so similar the model has nothing to choose on.

The ratio of tools called to tools present. Over a week of real traffic, how many of the tools you expose were invoked even once? For most teams that number is uncomfortable the first time they look at it, and it is the cheapest possible justification for cutting the list.

What changed in 2026

Three things, and they move the advice above rather than replacing it.

Clients grew filters. Exposing a whole server used to be all or nothing. Most major clients now let you allowlist tools per server and per project, which turns “disconnect the server” into “keep the three tools you use”. That is the single highest-leverage change available to most teams, and it needs no architecture.

Tool discovery became a runtime operation. Rather than shipping every definition up front, a server can expose a search or a dynamic toolset and hand over only what the current task needs. Vendors publishing on this have claimed very large reductions in tokens spent on definitions. The cost is a round trip before the first real call, and a hard dependency on the server implementing it.

The code execution pattern arrived properly. Instead of exposing forty tools for direct invocation, expose an interface and let the model write a short program against it. It collapses the preamble and it is a security decision as much as a token one, because you have added a code execution surface to your agent. Worth evaluating on both axes rather than only the cheap one.

What did not change: the arithmetic. Definitions still render at the front of every request, they are still resent every turn, and the model still has to choose among everything it can see.

The prompt cache trap

Worth its own section, because it is the most expensive detail here and the least known.

Tool definitions render at the very front of the prompt, before the system prompt and before the messages. Prompt caching works on a prefix: everything up to a breakpoint is cached, and a cache hit requires the prefix to match byte for byte.

So changing the tool list invalidates the entire cache, not just the tool section. Add one tool mid-session, or connect a server that advertises listChanged and updates itself, and the next request pays full price for the whole prefix including the system prompt that did not change.

A server that adds and removes tools dynamically is therefore expensive in a way its own size does not show. If you are chasing cost and your tool list is stable, this is not your problem. If your tool list moves during a session, it may be most of it.

Migration path, for an agent already in production

You cannot generally cut sixty tools to ten in one change, because you do not know which ten. A sequence that works:

  1. Log tool calls for a fortnight. Name and timestamp is enough. This is the only step that requires patience, and every later step depends on it.
  2. Sort by call count and find the long tail of zero. Nothing that has never been called in two weeks of real usage is earning its place in the preamble.
  3. Cut whole servers before individual tools. A server contributes fixed overhead beyond its tools, and removing one is a single reversible change rather than forty small ones.
  4. Filter the survivors per context. A support agent and a deploy agent rarely need the same set, and most clients let you say so.
  5. Re-measure the preamble. If it did not move, you cut the wrong things.
  6. Only now consider sub-agents or dynamic toolsets. These are worth real effort once you know the shape of your usage, and they are a poor first move because they add architecture to a problem that is often solved by deletion.

When this advice is wrong

If your agent is single-purpose, stop optimising. An agent with one server and eight tools is spending perhaps 3,000 tokens on definitions, and there is nothing here worth your afternoon. The failure mode of this article is a team building a dynamic toolset router for a preamble that was never the constraint.

If tool choice accuracy matters more than cost, more description wins. In a high-stakes workflow where calling the wrong tool is expensive, spending tokens on contrastive descriptions that name the alternative is a good trade. Pay the preamble, get the accuracy. The advice to shorten everything is a cost argument, and cost is not always the binding constraint.

And if you are on a cached, long-lived prefix with a stable tool list, the per-request cost of definitions is much lower than the headline arithmetic suggests, because the cache is doing its job. The attention cost stays. The money cost largely does not, and it is worth knowing which of the two you are actually trying to fix before you start.