Kan Yilmaz measured one configuration with six MCP servers, eighty-four tools, and about 15,540 tokens of tool definitions loaded before useful work began. The exact cost depends on the client and its tool-search behaviour, but the example exposes a real trade-off: a standard interface is not free.
I had been recommending MCP servers by default. The measurement pushed me to compare them with the less novel interface agents already know how to use: command-line tools.
What Claude Code Already Handles
Before reaching for an external server, it is worth remembering what Claude Code can do through its built-in tools and shell: Git operations, filesystem access, web retrieval, and ordinary command-line programs. For many tasks, that is sufficient and does not require a separate MCP catalogue.
The bash handle is the interesting one. Because the agent can invoke shell commands, any CLI tool installed on the machine is implicitly available to it. That’s why Claude infamously reaches for grep before anything else when looking for code: the tool exists, it works, and the model has seen it in roughly every repository on GitHub. It doesn’t need a protocol to know what -r does.
The downside is that tools drift. Alias grep to ripgrep and a subset of flags silently stops behaving the same way. The agent fires off grep -P expecting Perl regex, gets back a cryptic error, tries three variations, burns a few thousand tokens finding its feet. Not fatal. Annoying. The fix is a line in CLAUDE.md telling it which binary lives behind the name, and suddenly the looping stops. Small investment, large return, if it’s not lost in context.
The Case for MCP
MCP, the Model Context Protocol, is Anthropic’s open standard for connecting AI applications to external systems. It lets Claude use tools it didn’t ship with, often without needing to install a CLI at all. The advantages are real and I don’t want to pretend otherwise.
The strongest argument is the standard interface. MCP decouples the tool from the agent. Any MCP-compatible client can use any MCP server. You write the integration once. For tool builders trying to support Claude, Cursor, Continue, and whatever arrives next quarter, that’s a genuine win; one implementation, many clients.
There are specific MCPs I still reach for regularly. Context7 for library documentation lookup, which has saved me from hallucinated API docs more than once. Playwright for browser automation; hard to replace with a shell pipe when you need to click something. Doc-focused servers like Docfork also solve problems CLIs don’t address well.
These earn their keep. But “earns its keep” is a much smaller set than “installed by default,” and that gap is where the argument lives.
The Case Against MCP
So why not go all-in? This is where I’ve changed my mind over the past few months, and the turning point had names attached.
In February 2026, Eric Holmes published MCP is Dead. Long Live the CLI.. A short, pointed argument that the protocol offers no real-world advantage over the command line. A few days earlier, Kan Yilmaz had put the token arithmetic in a spreadsheet and open-sourced a tool called CLIHub that generates CLIs from MCP servers. Read the two together and the case is uncomfortable.
The core argument: LLMs don’t need a special protocol. They’ve been trained on decades of man pages, Stack Overflow answers, shell scripts, and GitHub READMEs. Tell Claude to run gh pr view 123 and it just works. You didn’t teach it gh; gh was in the training data long before the agent ever touched your repo. MCP promised cleaner interfaces, but in practice you end up writing the same README-style guidance anyway, just in a JSON Schema instead of a --help string.
CLIs have decades of design behind them. They’re debuggable by both humans and machines. When an agent does something weird with Jira, you can run the exact same jira issue view command in your own terminal and see what it saw. Same input, same output, no mystery. With MCP, the tool only exists inside the conversation, and debugging means reading JSON-RPC transport logs if you’re lucky and re-running the whole session if you’re not.
CLIs compose. Pipes, jq, grep, redirects. Holmes gives a Terraform example worth reproducing:
terraform show -json plan.out | jq '[.resource_changes[] | select(.change.actions[0] == "no-op" | not)] | length'
One line, no schema, counts the number of actual changes in a plan. The MCP equivalent is either “dump the entire plan into context and let the model count” or “ship a custom filtering parameter on the server.” The first is expensive and unreliable on large plans; the second means every MCP author reinventing jq badly.
Then there is auth. MCP supports OAuth, but the quality and deployment model still vary between servers and clients. Established CLIs often reuse familiar flows such as aws sso login and gh auth login, which may already fit the local environment.
Permissions are another consideration. MCP controls vary by client and server and can be coarser than command-specific shell rules. With CLI tools, Claude Code’s allowlist can distinguish read operations such as gh pr view from mutations such as gh pr merge. Verify the actual policy in your client rather than assuming either interface is safe by default.
Then there are other disadvantages of using MCP servers. MCP servers are background processes that need to start, stay running, and not silently hang; binaries sit on disk and run on demand. MCP initialisation failures requiring client restarts have become a routine ritual for anyone who leans on them.
That is quite the list, and a reason to reconsider how many MCP servers we use, if any.
The Token Economics
Yilmaz ran the numbers for a setup that matches what I had loaded: six MCP servers, roughly fourteen tools each, eighty-four tools total. The arithmetic is blunt:
- MCP session start: ~185 tokens per tool × 84 = 15,540 tokens loaded upfront. Every schema, whether you use it or not.
- CLI session start: ~50 tokens per tool × 6 binaries named and located = 300 tokens. Details discovered on demand via
--help. - After one tool use: MCP ~15,570, CLI ~910. A 94% saving.
- After one hundred tool uses: MCP ~18,540, CLI ~1,504. A 92% saving.
In Yilmaz’s model, CLI used fewer tokens at each measured usage level, with estimated savings between 92% and 98%. The lazy-loading pattern, discovering a tool’s surface only when needed, is progressive disclosure applied to tool definitions.
To put the tool counts in context, the official GitHub MCP server, Stripe MCP server, and Playwright MCP server all expose broad capabilities. In clients that eagerly load schemas, combining several large servers can occupy significant context before the tools are used. Tool search and lazy loading change that cost substantially, so inspect your current client rather than adding the counts blindly.
Anthropic’s Tool Search post examines a large customer configuration and reports reducing its startup context by 85% by loading a search index and fetching schemas on demand. Their internal benchmark also improved. This addresses much of the eager-loading cost, though a CLI may still expose a smaller, human-written help surface for common operations. Tool Search is a client and model capability rather than a property every MCP integration inherits.
What This Looks Like in Practice
The theory is one thing. What actually changed in my configuration is the more useful answer. No more token-hungry MCP if there is a CLI that can do the same job. Usually Claude already knows how to use the tools, but a reminder in CLAUDE.md like “use gh to interact with GitHub” helps guide the agent towards the CLI.
To handle aliases, I provide the agent with an up-to-date list of all the aliases I use via a SessionStart hook like the following:
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo '## Active Shell Aliases' && cat ~/.claude/shell-aliases.txt 2>/dev/null"
}
]
}
]
This is loaded at the start of each session, and ensures that Claude is aware my grep is, in fact, ripgrep. It has the same limitations we discussed in previous chapters regarding enforcement, but it helps.
For more complex tools, the solution is to find a relevant Skill that can teach Claude how to use the CLI properly. Skills will be discussed in a following chapter.
To avoid surprises during execution, you can enforce a safety gate by allowlisting only the safe verbs, so that dangerous operations are blocked or require user approval. Trust the training data to handle the syntax. It is boring rather than elegant, but it works.
When To Use MCP
If you’re going to use MCP (and I still do, selectively), keep it bounded. My current rule of thumb: only servers that are clearly better than a CLI (like MCP for browser interactions) or when I can’t find a Skill that replaces the server exactly.
With the new 1M context windows and lazy-loading, it seems like MCP context use through tools shouldn’t be an issue. It isn’t that simple. If you check /usage in a recent version of Claude Code, you’ll see that it specifically highlights sessions where the context window went over 150k tokens. That’s for a reason, and it shows we still need to consider what we load.
Cloudflare’s Code Mode MCP replaces large tool catalogues with a small number of generic primitives and lets the agent express operations as code. Cloudflare reports reducing tool-definition overhead to roughly 1,000 tokens regardless of API size. If that pattern holds, it is a more scalable design than loading every schema upfront. Anthropic’s code execution with MCP moves in the same direction.
David Cramer, in MCP, Skills, and Agents, reports that he runs with two MCP servers and about a dozen skills. He frames it neatly: “skills teach you to cook, MCP provides the instruments that let you do it.” That is one practitioner’s configuration, not a universal optimum, but it is a useful example of selective use.
MCP Security
The security story deserves more attention than it gets, because MCP is a supply chain and we haven’t been treating it like one.
Environment variable exfiltration through MCP servers isn’t hypothetical. Check Point Research disclosed CVE-2025-59536 and CVE-2026-21852 in early 2026: malicious .mcp.json and .claude/settings.json entries in a cloned repository could trigger remote code execution and steal Anthropic API keys before the user had a chance to read the trust dialog. The attack vector was exactly the one MCP’s “easy onboarding” was designed to enable: drop a config file in the repo, let the client auto-load it. Between January and February 2026, researchers filed more than 30 CVEs against MCP servers, clients, and infrastructure, with severities topping out at CVSS 9.6.
My recommendation is to review an MCP server’s source before installing it and to treat .mcp.json as executable project configuration: checked into git, reviewed in PRs, and approved like any other dependency.
Trail of Bits goes further. Their shared Claude Code configuration sets enableAllProjectMcpServers: false and declares denied reads for named credential paths. The intent is opt-in MCP access and explicit protection for secrets. Those deny rules still need OS-level filesystem isolation to constrain shell subprocesses reliably. I have adopted the opt-in pattern because project MCP configuration should be reviewed like executable code.
Where This Leaves Us
My current position, which I reserve the right to change as the tooling matures, is CLI-first. I keep MCP for cases where there is no good CLI equivalent or where the protocol provides a capability the shell genuinely cannot match, such as Playwright’s page interaction, Context7’s version-pinned docs, or Sentry’s scoped issue retrieval.
Document CLI usage in CLAUDE.md. Tell the agent what’s on the path and how you want it used: “Use gh pr list for open PRs. Use gh issue view 123 --comments for issue context.” This costs almost nothing in context, makes the agent productive immediately and survives protocol changes, client rewrites, and whichever MCP server stopped being maintained last week.
If you are building tools for agents, Holmes’s plea is the one I would echo: ship a good API and a good CLI. Agents are often familiar with established CLI conventions, and --help provides a current fallback. An MCP server can still add value, but it should solve a problem that the API and CLI do not.
My bet is that more tools will add --json output, structured help, and safe read-only verbs, while MCP concentrates on cases where discovery, resources, or interactive application control justify the protocol. That forecast may be wrong. The practical choice today is simpler: measure the context and permission cost of each integration, then keep the interface that earns it.