MCP vs CLI for coding agents: what your tools actually cost
10m read time

MCP vs CLI for coding agents: what your tools actually cost

Every comparison quotes a multiplier. Mine came out at 88.9x, and my client had already answered the question that number was asking. What a tool surface costs now, and what still separates a schema from a command.

Search for "MCP vs CLI" and you get a wall of multipliers. CLI is 4x cheaper. 10x. 32x. 137x. Every post has a number, every number comes from one benchmark, and none of the benchmarks agree.

So I measured my own. I spoke MCP directly to every server configured on this machine, asked each one for its tool list, and counted the bytes.

Forty-nine tools. 72,612 characters of tool definitions, against 817 characters if you list nothing but the names. That is 88.9x, and it sits right inside the range everyone is quoting.

The shape is real. The number is answering last year's question.

Two prompts side by side: 49 tool schemas in one, against tool_search and the four schemas it pulls on demand.

What the bytes actually say

Here is the measurement, with the servers anonymised because they are mine and their names are not the point.

ServerToolsChars~Tokens
docs lookup24,5851,100
resilience audit316,3214,000
architecture3344,85710,900
test fidelity116,8491,700
Total4972,612~17,700
Names only817~200

Characters are exact. Tokens are an estimate at roughly four characters per token, which I calibrated rather than guessed: MCP issue #2808 measured eleven tools of the context-mode plugin through Anthropic's token-counting API in May 2026, and re-measuring those same eleven tools here puts the ratio at 4.11. Treat the token column as a rounded figure with a real method behind it.

Two things fall out that the multiplier posts skip.

The cost is the schema. Of those 72,612 characters, 11,911 are the human-readable tool descriptions. Sixteen per cent. The rest is JSON Schema: parameter names, nested types, enums, constraint keywords. So the standard advice to write terser tool descriptions is aimed at a sixth of the problem. Issue #2808 found the same thing from the other end, measuring an almost tenfold spread between the cheapest and most expensive tool in a single server and concluding that "the 10x delta is entirely in JSON Schema size".

Tool count is the wrong unit. My three-tool server costs 5,440 characters per tool. My 33-tool server costs 1,359. A server with a tenth of the tools can cost four times as much per tool, because one of them takes a deeply nested object and the others take a string. Counting tools tells you almost nothing about what a server costs you.

The client already moved

The whole MCP-is-expensive argument rests on a premise: every schema loads into the prompt before you type anything. That was true when the benchmarks were run, and I have done that arithmetic here before, back when the honest total for a stacked install was around eleven thousand tokens of pre-work overhead.

Anthropic published the fix in November 2025. The code execution post on 4 November made the case that an agent should read tool definitions the way it reads files, on demand, and put the saving at 98.7%, from 150,000 tokens down to 2,000. The advanced tool use post on 24 November shipped the mechanism as the Tool Search Tool, and it is worth reading their own numbers on their own setup: "That's 58 tools consuming approximately 55K tokens before the conversation even starts", and, more bluntly, "At Anthropic, we've seen tool definitions consume 134K tokens before optimization."

It stopped being an experiment on 17 February 2026, when the release notes recorded that the code execution tool, web fetch tool, tool search tool, tool use examples and memory tool "no longer require a beta header". Ten months after the announcement it is the default in the client I am typing this in. Claude Code 2.1.260 carries a per-server alwaysLoad setting, described in the binary as:

text
When true, all tools from this server are always included in the prompt and never
deferred behind tool search. Equivalent to setting defer_loading: false on the API.
Default: tools are deferred when tool search is enabled.

Read the default clause twice. Deferral is what you get, and alwaysLoad is how you switch it off, per server, when you want a server's tools present from turn one.

In this session, all 49 of those tools arrived as bare names. Getting at any one of them cost me a search call and a few thousand tokens for the three or four schemas I actually wanted. The 88.9x I measured is the gap between what a server publishes and what a client chooses to send, and my client is choosing to send the names.

What deferral costs instead

The tokens did not evaporate. They turned into round trips.

An always-loaded tool is one call. A deferred tool is a search, then a call, and the search can miss: it matches on names and descriptions, which is exactly the sixteen per cent I said was not the cost. You are now paying attention and latency where you used to pay context.

There is a third cost, and I only found it because the people arguing about the protocol got there first. On that same MCP discussion, a collaborator pointed out on 26 August that deferral "doesn't deal with prompt cache invalidation, where even models that support lazy loading of tools bust the prompt cache if" the list of tool definitions changes, "even if defer loading is true on them all". Your schemas can be deferred and your cache can still be cold, because any change to the tool set invalidates it, at any size. Start a server mid-session and you have paid for that.

The same binary is honest about the trade in the other direction. That alwaysLoad description continues: setting it "also blocks startup until the server is connected (capped at the standard 5s connect timeout) even though MCP startup is otherwise non-blocking by default, since the tools must be present when the turn-1 prompt is built". Token cost and startup latency are the same dial. Pin a server's tools into the prompt and you have also decided to wait for that server before your first message goes anywhere.

The tools that quietly are not there

Here is the part I did not expect to find, and the reason this post is not just about tokens.

Claude Code drops MCP tools it cannot use, and the binary builds two messages for it. One names the casualty: "toolName" (MCP server "X"): "reason". The other is a summary that reads MCP server "X": 12 tools excluded (invalid input schema), and the switch between them is a constant set to 30. Under thirty dropped tools from one server you are told which ones and why. Over thirty you get a count.

A server can advertise a tool your client will never offer the model, because the schema uses something the client will not accept. Your tool list and the server's tool list are different lists, and the gap is reported at a level of detail that decreases exactly as the problem gets worse.

That is a reliability property, and it is the one thing a CLI genuinely does not have. git commit does not fail to appear because its argument parser was too baroque.

A CLI is not free either

The case for the CLI is usually stated as though commands cost nothing. Discovery is where they charge you.

An agent that has never used your CLI has to learn it, and it learns it by running --help and reading the output into context. On this machine gh --help is 2,007 characters and gh pr --help is another 1,433. Two help calls to do one thing is roughly a thousand tokens, paid in the session where you use it, and paid again in the next session unless something wrote it down.

The real advantage of a CLI is that the model already knows git, gh, docker and psql from pretraining, so the discovery cost is zero for the tools everyone uses and full price for yours. A CLI you wrote last month is in exactly the same position as an MCP server: undocumented interface, discovered at runtime, and now discovered through a channel with no schema, which means the agent can get the flags wrong and find out from a non-zero exit code.

That is the trade, stated properly. MCP buys you an exact, machine-checked interface and charges you for it in the prompt, or in a search round trip. A CLI buys you whatever the model already knows and charges you for anything it does not.

So which one

The useful question is what a tool costs when the agent ignores it, and what it costs when the agent reaches for it.

  • The model already knows the interface. Use the CLI. gh, git, kubectl, psql. Wrapping these in an MCP server buys you a schema for something that needed no schema.
  • You need auth, a remote service, or an audit trail. Use MCP. OAuth, per-tool permission policy and a server you can put a boundary around are not things a shell command gives you, and none of that is a token argument.
  • You use it every session. Set alwaysLoad on that one server and accept the startup wait. Everything else stays deferred.
  • You are about to build one. The test has not changed: does this need to exist. Deferral only lowers the price of keeping an unnecessary one. It still runs, it still has a supply chain, and it still needs vetting whether or not its schema is in your prompt today.

And measure your own, because your servers are not mine. Speak tools/list to each one, count the characters, and look at the per-tool spread rather than the tool count.

The protocol is only now catching up

Every fix described above is a client feature. The protocol still hands over the full schema for everything: when I asked those four servers for their tool lists, I got 72,612 characters, because that is the only thing tools/list returns.

That gap is known and it has been argued over for a while: issue #2808 was filed on 28 May 2026 and converted to a discussion by a maintainer the next day. Discussion #1923, "Progressive Tool Discovery for Token Efficiency", has been open since 3 December 2025 and was still collecting comments a week before this post went out. SEP-2636, "Progressive Tool Disclosure", has been open since 23 April 2026 and was last touched on 3 September, the day before I published this. The spec is still at revision 2026-07-28, and none of it is in there.

What did change is the intent. The roadmap published on 22 August makes this a funded work item rather than a thread: a Core Primitives working group on progressive discovery, so that "clients learn a server's tools and resources as they need them instead of ingesting the full catalog up front". That is the client-side trick this whole post is about, written down as something the protocol should do itself.

So the saving you are enjoying today belongs to your client. You can lose it by switching clients, by pinning a server, or by an update that retunes a threshold you never knew was there, and in a release or two you may stop owning it at all, because the protocol will. That is worth knowing before you rewrite a working MCP server as a CLI on the strength of a multiplier someone measured on a different client, in a different month, and rounded in their own favour.

The tools are cheaper than the benchmarks say. They are also less permanent than they look, and the context they sit in is still the budget everything else has to fit inside.