The MCP vs CLI argument is about one mechanism: when a tool's description enters the model's context. A client that loads MCP tools up front sends every tool's name, description and input schema with every request, so a server you connected for one task costs tokens on every turn. A command-line tool the model already knows costs nothing until the agent runs it. Anthropic's own Claude Code guidance says CLIs such as gh, aws, gcloud and sentry-cli "are still more context-efficient than MCP servers because they don't add any per-tool listing"1.
That does not make MCP the wrong choice. It makes the overhead something to measure and manage. This guide explains where the tokens go, how to count them, five patterns that reduce them, and when MCP is still the right answer.
Why MCP tool definitions cost tokens on every turn
An MCP client discovers a server's tools with a tools/list request. Each tool comes back with a name, an optional title, a description, an inputSchema in JSON Schema, and optionally an outputSchema and annotations2. To let the model call those tools, the client converts them into the model API's tool format and puts them in the request.
Model APIs are stateless, so the tool list goes in every request, not once per session. Anthropic's pricing page is explicit that the tools parameter (tool names, descriptions and schemas) is billed as input tokens, and that any request with tools also carries a tool-use system prompt the API adds automatically; on Claude Opus 5.5 that is 286 tokens3. An agent turn is several requests, one per tool call, so the definitions are paid for again on each step.
Two consequences follow:
- Idle tools cost the same as used ones. A 40-tool server connected for one lookup is paid for on every request of the session.
- The cost scales with servers, not with work. Anthropic's tool search documentation gives a typical five-server setup (GitHub, Slack, Sentry, Grafana and Splunk) as about 55,000 tokens of definitions "before Claude does any work"4.
Size is not the only problem. The same page says Claude's ability to pick the right tool degrades once more than 30 to 50 tools are available4. A long tool list is paid for in tokens and in wrong choices.
OpenAI tells Codex users the same thing from the other side: "Every MCP server adds more context to your messages and uses more of your limit," and advises disabling servers you do not need5.
MCP vs CLI: the mechanical difference
| MCP tools loaded up front | CLI through a shell tool | Skill or instruction file loaded on demand | |
|---|---|---|---|
| What is in every request | Every tool's name, description and schema | One shell tool definition | A short name and description |
| When details load | At session start | When the agent runs --help or reads the output | When the agent invokes it |
| Auth | Server holds or brokers credentials | Whatever is on the developer's machine | Whatever the skill's commands use |
| Works remotely | Yes, over HTTP | Only where the binary is installed | Where the agent runs |
| Central control and audit | Possible at the server or a gateway | Shell history, if anything | None by default |
The CLI advantage depends on the model already knowing the tool. git, gh, kubectl and the major cloud CLIs are in the training data, so the agent can call them without a schema. An internal CLI the model has never seen needs documentation in context, either a skill or the output of --help, and that is a tool definition by another name.
How to measure the overhead
Do not guess. Count a request's input tokens with and without the tool list, using the provider's token-counting endpoint. Anthropic's POST /v1/messages/count_tokens accepts the same inputs as a message, including tools, returns the total input tokens, is free to use within its own rate limits, and is documented as an estimate that may differ slightly from the billed count6.
First, fetch the tool list from your MCP server and convert it into the Messages API's tool shape:
# tools/list from a Streamable HTTP server, then MCP shape -> Messages API shape
curl -s "$MCP_URL" \
-H "Authorization: Bearer $MCP_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
| jq '[.result.tools[] | {name, description, input_schema: .inputSchema}]' > tools.jsonThen count the same message twice:
count() {
curl -s https://api.anthropic.com/v1/messages/count_tokens \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d "$1" | jq .input_tokens
}
MSG='[{"role":"user","content":"List open issues assigned to me"}]'
count "{\"model\":\"claude-sonnet-5-5\",\"messages\":$MSG}"
count "{\"model\":\"claude-sonnet-5-5\",\"messages\":$MSG,\"tools\":$(cat tools.json)}"The difference is what that server costs on every request. Some servers paginate tools/list with a cursor2; follow nextCursor until it is empty. Recount when you change models: Anthropic notes that Claude 4.7 and later models use a newer tokenizer that produces roughly 30% more tokens for the same text6.
In Claude Code, /context shows what is consuming the context window, server by server1.
Prompt caching reduces this cost; it does not remove it. On Anthropic's API a cache hit bills at 0.1x the base input rate, 0.05x on Claude Opus 5.5 and Claude Sonnet 5.53, but the definitions still occupy the window and still bill. Tool definitions sit at the front of the prompt, so changing the tool list mid-session invalidates the cache behind it. Long context in production covers the window side of the same problem.
Five patterns that cut tool overhead
1. Fewer, narrower tools
The cheapest token is the one you do not send. Many MCP servers expose every endpoint of an API as its own tool. Turn off what the agent never needs. Codex supports enabled_tools and disabled_tools per MCP server in config.toml7; Claude Code lets you disable unused servers with /mcp1. If you write the server, merge near-duplicate tools and keep descriptions short and specific. Claude Code cuts tool descriptions that load up front at 4,096 characters by default8, which is a hint about how long they should be.
2. Toolsets per task
Group tools by job: a read-only toolset for investigation, a write toolset for changes. Connect the one the task needs. A server that exposes toolsets lets each client choose the smallest set that works.
3. Deferred loading and tool search
Anthropic's API lets you send tools with defer_loading: true alongside a tool search tool. The model sees only the search tool and any non-deferred tools at first, searches when it needs something, and the API expands only the matching definitions4. Anthropic reports this typically cuts definition tokens by over 85%, loading the three to five tools a request needs, and that deferred tools are excluded from the system-prompt prefix so prompt caching is preserved4. Its own guidance: use tool search with ten or more tools or more than 10,000 tokens of definitions, and stay with standard tool calling below that4. Note that you still send every definition in the request; deferral controls what enters the context, not what crosses the wire4.
Claude Code applies this to MCP by default: only tool names and server instructions load at session start8.
4. Code execution instead of direct tool calls
Anthropic's engineering team describes a different shape: present MCP servers to the agent as code on a filesystem, let it read only the definitions it needs, and let it write code that calls tools and filters their results before anything returns to the model9. This addresses both costs the post names, definitions that overload the context window and intermediate results that pass through it; in its worked example token use fell from 150,000 to 2,0009. The post is equally clear about the price: running agent-written code needs a sandbox with resource limits and monitoring, which adds operational overhead and security considerations that direct tool calls avoid9.
Results matter as much as definitions. Claude Code warns when an MCP tool's output exceeds 10,000 tokens and limits it to 25,000 by default, saving larger results to a file8. A tool that returns a whole table when the agent needed three rows costs more than its definition ever will.
5. Filter tools per key at a gateway
Client-side settings live on each developer's machine and drift. A gateway between agents and MCP servers can decide which tools each credential sees at all: an agent that only triages issues gets three tools, not the server's forty. That shrinks the list before the client ever builds a request, and it works the same whether or not the client supports deferred loading. The MCP gateway guide covers the pattern in full.
When is MCP still the right answer?
Use a CLI where the model knows it, the agent has a shell, and the credentials on that machine are the right ones. Use MCP where those conditions fail:
- Remote tools. A hosted agent, a CI job or a chat assistant has no developer laptop to install a CLI on. MCP over HTTP reaches the service from anywhere.
- Credentials you do not want on every machine. An MCP server, or a gateway in front of it, holds the service credential; the agent holds only its own. Rotating one secret beats rotating one per laptop.
- Governance. Approve which tools exist, which agents may call write tools, and switch a tool off for everyone at once. The MCP specification itself says clients should show users which tools are exposed and keep a human able to deny invocations2.
- Audit. The specification recommends that clients log tool usage for audit purposes2. A central path makes that one log instead of one per machine. MCP in production covers the failure modes worth logging.
- Many clients, one definition. The same server serves Claude Code, Codex, an internal agent and an IDE. A CLI wrapper per client is more code to keep in step.
The honest framing is not MCP versus CLI but which tools must be on every turn. Keep that list short, defer the rest, and put control where more than one machine depends on it.
Governing tool lists with INFRO
INFRO's MCP gateway sits between your agents and the MCP servers you already use. An admin registers each server once with its credential, approves and pins each tool's definition, and grants gateway keys access to a server in read, all or selected mode. A key with no grant sees no tools, and on the aggregated endpoint a key lists only the approved tools its grants allow, so an agent's tool list is as narrow as its job. Every call, refusals included, is recorded on the same trace as the agent's model calls, approvals and blocks are written to the audit log, and blocking a tool or disabling a server takes effect on the next call. INFRO executes no tool and hosts no server: the servers are yours, reached with your credentials. Setup is on the MCP gateway docs page.
For measurement, agents that call Claude through INFRO's /v1/messages can use POST /v1/messages/count_tokens on the same base URL; it asks the first Anthropic connection serving the model, costs nothing and leaves no request row. INFRO forwards tool search on an Anthropic connection: the deferred tools, the search tool, the tool_reference blocks and the anthropic-beta header reach Anthropic as Claude Code sent them, so set ENABLE_TOOL_SEARCH=true when Claude Code points at INFRO. A model INFRO has to translate to Chat Completions cannot run the search tool, and such a request is refused before any call. Recipes for pointing Claude Code and Codex at INFRO are on the coding agents page.
