MCP clients now load tool names, not schemas. Our gateway's token pitch didn't survive it.
In September we corrected our gateway's headline from 10× less context to about 3× (post 4). Both numbers rested on one sentence in that post: "Every MCP server in your client config injects its entire tool schema into every turn, whether you use it or not."
In three clients that sentence is false by default, and in two of them it already was when we wrote it. Claude Code, Cursor and Kiro give the model the names of your MCP tools, and fetch a tool's full definition only when it's needed. Post 4 measured with our own harness, which sent every definition, and we didn't check a real client. This week we measured all three. Then we redid post 4's whole-bill comparison in Claude Code, over one task and over an eight-turn session.
What ten configured servers, 500 tools between them, add to every request:
| client, default settings | added to every request | sent upfront |
|---|---|---|
| Claude Code 2.1.308 | 14,853 tokens | tool names, server instructions |
| Cursor 3.17.21 | 4,330 tokens | tool names |
| Kiro 1.4.26 | 26,398 characters | server::tool ids |
| Claude Code, tool search turned off | 183,889 tokens | every definition, in full |
Cursor's figure is its own estimate. Kiro logs characters, not tokens.
Over a whole session, the gateway did worse than we expected. With Claude Code's default settings, over eight turns, our gateway used about 597,000 prompt tokens. Three servers configured directly used 475,000, and nine used 510,000. It came out ahead only against the ten-server setup, whose tenth server has 375 tools, and only from the third turn.
The rest of this post covers how we measured, why the gateway lost, and what we're changing.
What changed in the clients
Claude Code calls it tool search. Its
MCP documentation
says tool search is enabled by default, and that "only tool names and server
instructions load at session start". Claude loads a tool's definition through a
ToolSearch tool when it wants one. ENABLE_TOOL_SEARCH=false turns it off. The
docs also list cases where Claude Code loads everything upfront anyway: older
models and some cloud deployments. According to its
changelog,
version 2.1.7, released on 13 January 2026, began deferring MCP tools by default
once their definitions passed 10% of the context window. In 2.1.308 it deferred
even our smallest setup, one server with 29 tools.
Cursor calls it dynamic context discovery. Its
post of 6 January 2026 describes
syncing MCP tool descriptions to a folder. The agent starts with a small amount
of static context that includes the tools' names, and reads a tool's file when it
needs one. Cursor reports 46.9% fewer total agent tokens in an A/B test, counting
runs that called an MCP tool. The folders are on disk:
~/.cursor/projects/<project>/mcps/user-<server>/tools/<tool>.json.
Kiro doesn't document this anywhere we could find, so we don't know since
when. Its agent doesn't get
one function per MCP tool. It gets two, tool_load and tool_call, and calls
tools by server::tool id. In our measurements, each configured tool made
Kiro's request longer by exactly the length of its id plus two characters. That
rule predicted the 1-, 3-, 9- and 10-server requests to the character.
In all three, a configured MCP server now costs roughly what its tool names cost. A typical server is cheap. A server with hundreds of tools isn't, even by name alone.
How we measured
- Ten real tool lists, replayed. We took the ten most-downloaded servers whose latest start test passed and whose tools we store: Chrome DevTools (29 tools), Context7 (2), filesystem (14), everything (13), memory (9), sequential-thinking (1), Firecrawl (26), n8n (7), Notion (24) and Hostinger's API server (375). A small stub served each list to the client exactly as the server had returned it to us, so no third-party code ran.
- The same setups in every client: no MCP servers; the first 1, 3, 9 and 10 of that list; and our gateway alone.
- Claude Code:
claude -pwith Sonnet 5.5. Tokens are the API's own count for each request: input, plus cache writes, plus cache reads. - Cursor: for every chat, Cursor stores the token breakdown its context gauge shows. We read it from Cursor's local state database. Model: grok-4.6.
- Kiro: request size in characters, from Kiro's own log.
- One short message per setup, in a new chat each time. We report what each setup adds over no servers.
What a configured server costs now
Added to every request, compared with no MCP servers:
| setup | tools | Claude Code | Claude Code, tool search off | Cursor | Kiro (chars) |
|---|---|---|---|---|---|
| 1 server | 29 | +630 | +9,393 | +141 | +3,107 |
| 3 servers | 45 | +1,050 | +14,143 | +266 | +3,974 |
| 9 servers | 125 | +3,085 | +77,656 | +910 | +7,693 |
| 10 servers | 500 | +14,853 | +183,889 | +4,330 | +26,398 |
| our gateway | 13 | +716 | +5,595 | +342 | +3,797 |
Read down a column, not across: there are three tokenizers here and one character count.
Two things stand out. First, nine servers with 125 tools cost about 3,000 tokens in Claude Code and under 1,000 in Cursor. Most of the ten-server cost is one server, whose 375 tool names add up even without their schemas. Second, our gateway, with 13 tools and a paragraph of instructions, costs about as much as two or three ordinary servers.
With tool search off, Claude Code sends every definition in full, and the picture is post 4's: ten servers add 184,000 tokens to every request, and the gateway 5,600.
The whole bill for one task
Standing cost is what sits in the prompt. The bill also depends on how many requests a task takes, because each request sends the prompt again. That was post 4's lesson, and it matters more now.
The task: "Use the list_directory tool from the filesystem MCP server to list [a folder], then reply with exactly the text the tool returned." With the server configured, Claude Code takes three requests: find the tool, call it, answer. Through the gateway it takes six. It checks what's connected, loads the gateway's own tools, connects the server (after searching our registry in 3 of 10 runs; otherwise by package name), calls the tool through the gateway, and answers.
Prompt tokens for the whole task in Claude Code:
| setup | default (tool search on) | requests | tool search off | requests |
|---|---|---|---|---|
| 3 servers | 81,494 | 3 | 111,103 | 2 |
| 9 servers | 87,599 | 3 | 238,129 | 2 |
| 10 servers | 122,903 | 3 | 450,595 | 2 |
| our gateway | 173,063 | 6 | 240,766 | 5 |
The gateway figures are the median of five runs. With tool search on they ranged from 168,756 to 229,033 (one run took eight requests); with it off, from 240,747 to 245,803. Repeat runs of the configured setups gave identical counts.
Claude Code's base prompt, its system prompt and built-in tools, is about 26,000 tokens, and every extra request sends it again. With tool search on, the gateway's three extra requests cost more than it saves in standing context against any of these setups. With tool search off, the configured setups pay for every definition on every request: the gateway comes out level with nine servers, and at about half the cost of ten.
Every prompt ended with: "If that server isn't connected yet, you have my approval to find and connect it yourself." Without that sentence, Claude stopped rather than start a package nobody had approved. That's the right call, and a gateway user should expect to be asked.
Over a session
A single task undersells one side. Configured servers cost something on every request, while the gateway's search-and-connect cost is paid once. So we kept one Claude Code process running for eight turns: the same task first, then seven more requests to list a folder with the same tool.
Cumulative prompt tokens with Claude Code's default settings:
| turn 1 | turn 2 | turn 3 | turn 4 | turn 8 | each later turn | |
|---|---|---|---|---|---|---|
| 3 servers | 81k | 136k | 192k | 248k | 475k | ~56k |
| 9 servers | 88k | 147k | 206k | 266k | 510k | ~60k |
| 10 servers | 123k | 206k | 289k | 372k | 710k | ~84k |
| our gateway, 2 runs | 169–170k | 228–230k | 288–291k | 349–352k | 595–600k | ~61k |
Against ten servers, the gateway draws level at turn 3 in one run and turn 4 in the other, and is 16% lighter by turn 8. Against three or nine servers it never draws level, and the gap slowly widens.
The reason is in the last column. After the first turn, a request through the gateway carried about as much as a nine-server request: about 30,000 tokens against about 29,500. From standing cost alone, it should have been about 2,400 lighter. But everything the gateway did in the first turn, the connected-servers check, the registry search and the connect call, stays in the conversation together with its results, and every later request sends it all again. The one-time cost isn't one-time.
With tool search off, the order flips. The gateway is lighter than nine servers from turn 2, and lighter than ten from turn 1. Against three servers it saves about 5,000 tokens a turn, but starts 134,000 to 184,000 behind, so it would need roughly 25 to 40 turns to catch up.
When the gateway still saves context
- When your client loads definitions upfront. Claude Code does with tool search off, on models older than the ones its docs list, and on some cloud deployments. Clients we haven't measured may do it by default.
- When one server has hundreds of tools, and the session runs past a few turns.
- Not for a handful of typical servers in Claude Code, Cursor or Kiro.
That's a narrower claim than post 4's "four or more servers, it pays", and much narrower than the 10× we started with.
What the gateway is for
Context was always our secondary argument. The gateway exists so that a server
you add doesn't get your environment. It starts each server with a short
allowlist (PATH, HOME, USER and a few more) plus only the variables you
name, so the API keys in your shell aren't there to read. That doesn't depend on
how your client loads tools. It also doesn't stop a server reading files as you,
unless you turn on container isolation; the
README says what each
level protects.
What we're changing
- The gateway README's section "Why it uses less of your context" goes. These measurements replace it. The change reaches npm with the next release.
- Post 4 now opens with a dated correction pointing here. Its numbers are right for a client that sends every definition. Its first sentence wasn't true of Claude Code or Cursor even when we published it.
- The measurement scripts are public, linked below.
How sure we are
- Claude Code counts: high. They're the API's own token counts for each request, and repeat runs of the configured setups gave identical numbers.
- Kiro sizes: high, as characters. A one-line rule predicted every setup to the
character. Kiro also adds a fixed 2,065 characters once any MCP server is
configured; we think that's the definitions of
tool_loadandtool_call, but that's inference. - Cursor figures: medium. They're Cursor's estimates for its context gauge. Every category in the breakdown grew a little as MCP grew, which suggests Cursor scales its estimates to a measured total. So we used the total, not the breakdown's MCP line, which would have understated the cost.
- Break-even turns: medium. Two gateway sessions, and one for each configured setup.
What we don't claim
- Not a benchmark. One task shape, one model per client, the same tool eight times. A session that connects several servers through the gateway pays the search-and-connect cost again for each one.
- Not real servers. We replayed stored tool lists. Real servers can also send instructions, which Claude Code loads at session start (up to 4,096 characters each). Ours sent none, which makes our configured setups slightly cheaper than real ones.
- Not dollars. Repeated prompt prefixes are cached and billed at a fraction of the input price, on both sides. The cost then depends on how warm the cache is: identical runs differed by up to 7× in what Claude Code reported. Token counts didn't move.
- Not other clients. We didn't measure VS Code, Windsurf, Claude Desktop or ChatGPT.
- Not for long. Claude Code 2.1.308, Cursor 3.17.21 and Kiro 1.4.26, measured on 27 and 28 October 2026. These clients change monthly.
- We are not neutral. We build the gateway, and this post makes its case smaller.
Reproduce it
The scripts are in the gateway repo's
demo/ folder:
claude-code-tokens.mjs: standing cost for each setup.claude-code-whole-bill.mjs: one task, every request counted.claude-code-session.mjs: the eight-turn session.cursor-standing.mjs,kiro-standing.mjs: you send one message per setup, and the script swaps the MCP config, waits for the client to load it, and reads the result. It puts your own config back afterwards.replay-tools-server.mjs,replay-npx.mjs: the stub, and thenpxstand-in the gateway gets, which refuses any package it doesn't know.
The fixture is the ten servers' tool lists as our API serves them:
curl -s https://mcprating.io/api/v1/servers/hostinger-api-mcp
# .tools: name, description, inputSchema for each of its 375 tools
The scripts read them as { "servers": [ { "slug", "tools": [ … ] } ] }, and the
stand-in maps each slug to its npm package with { "<slug>": { "npm": "<package>" } }.
CLAUDE_BIN=claude CC_GATEWAY_ENTRY=path/to/@mcp-rating/gateway/dist/index.js \
node demo/claude-code-session.mjs fixture.json packages.json
A client that sends only tool names has already done most of what our gateway did for context. What's left for the gateway is the job it was built for: keeping your keys away from the servers you run.