MCP vs CLI for AI Agents: I Ran the Same Check Both Ways
On this page, 9 sections
If your AI agent already has a shell and the tool you need is already a command, use the CLI. Use an MCP server when you need a typed interface, discovery by the host, or a host that has no shell. For a simple check, my one measured comparison showed almost no difference in speed or cost.
On 11 October 2026 I wrote the same title check twice, once as an MCP server and once as a command-line script, and asked Claude Code to run each. One run each is not a benchmark, so I treat the numbers as an example and not a verdict.
If MCP is still new to you, start with what an MCP server is.
The same check, built both ways
The MCP version is the check_title tool from my Python MCP server post. The CLI version is this script, saved as checktitle.py. I ran python -m py_compile on it, exit 0.
import argparse
import json
p = argparse.ArgumentParser(description="Check an SEO title against a character limit.")
p.add_argument("title")
p.add_argument("--limit", type=int, default=60)
a = p.parse_args()
print(json.dumps({"length": len(a.title), "limit": a.limit, "ok": len(a.title) <= a.limit}))
Run by hand on “Do You Need an XML Sitemap? What Google Docs Say”, it printed {"length": 48, "limit": 60, "ok": true}.
I then ran each through claude -p with Claude Code 2.1.296. Both runs used --strict-mcp-config, so the MCP run loaded only my server and the CLI run loaded an empty MCP config. The CLI run was allowed one Bash pattern, Bash(python3 checktitle.py:*).
| Run | Turns | Duration | Reported cost | Result |
|---|---|---|---|---|
| MCP server | 3 | 10,482 ms | $0.1443 | length 48, limit 60, ok true |
| CLI script | 2 | 10,408 ms | $0.1367 | length 48, limit 60, ok true |
The MCP run took 74 ms longer, 0.7 percent, and cost $0.0076 more, 5.6 percent. I calculated both in Python from the raw figures. That gap is inside what I would expect from run-to-run noise, though I did not repeat the runs to measure the noise.
Why the comparison is weaker than it looks
- The prompts were not identical. For the CLI run I gave Claude the exact command. For the MCP run it had to find the tool, which is where the extra turn came from.
- The extra turn was a search. The MCP transcript shows a
ToolSearchcall formcp__postchecks__check_titlebefore the tool call. The Claude Code docs say tool search is on by default and defers MCP tool definitions, so only tool names load at session start. - One tool. With a single small tool, loading definitions upfront would cost almost nothing either way. I did not test a server with dozens of tools.
- One model and one host. I did not try another host, another model or a non-Claude agent.
What each one gives you
These come from running both, not from a benchmark.
| Need | MCP server | CLI script |
|---|---|---|
| Input schema | Generated from type hints and docstring | Whatever --help prints |
| Output | Structured content, such as {'length': 50, 'limit': 60, 'ok': True} | Text on stdout that you format yourself |
| Errors | isError: True with your message | Exit code and stderr |
| Discovery | Host lists tools, resources and prompts | Agent must know the command exists |
| Extra surfaces | Resources and prompts as well as tools | Tools only |
| Needs a shell | No | Yes |
Where the cost shows up (documented, not measured)
I did not measure these. They are in the Claude Code MCP docs.
- Output size. Claude Code warns when an MCP tool returns more than 10,000 tokens and limits output to 25,000 tokens by default. Text results over 50,000 characters are saved to a file.
- Trust. The docs tell you to verify that you trust each server before connecting it, and note that servers which fetch external content can expose you to prompt injection.
- Startup. A stdio server is a child process that has to start, and the docs give
MCP_TIMEOUTfor how long Claude Code waits for it.
A CLI has its own risks. A Bash permission rule such as the one I used limits which command can run, and an agent with a broad shell can do more than one with a narrow tool. I did not compare the two security models in depth.
How to measure it on your own setup
One run each told me little, so repeat it. This is the CLI side of what I ran, with the pattern that limits Bash to the one script. Swap in your own command, and run the MCP version the same way with your server in the config file.
echo '{"mcpServers":{}}' > empty.json
claude -p "Run this exact command with Bash and reply with only its output: python3 checktitle.py 'Your title here'" \
--mcp-config empty.json --strict-mcp-config \
--allowedTools "Bash(python3 checktitle.py:*)" \
--output-format json > run.json
The JSON output carries num_turns, duration_ms and total_cost_usd, which are the three figures in my table. I would run each path at least five times and compare medians, not single runs.
Give both runs the same level of instruction. My two prompts were not identical, which is the biggest flaw in my own comparison. If you tell the agent the exact command in one run and make it discover the tool in the other, you are measuring the prompt, not the interface.
Also test with a realistic number of tools. A server with one tool tells you nothing about a server with thirty, and the Claude Code docs say the practical limit is your context window budget.
How I choose (opinion)
- The tool already exists as a command, and the agent has a shell: use the CLI. I would not wrap
gitorcurlin a server. - The tool is my own small check and only I run it: a script is quicker to write and easier to debug.
- The host has no shell, or I want several hosts to use the same tool: MCP.
- I want typed inputs, structured results and a reusable prompt or resource shipped with the tool: MCP.
- The tool talks to a remote service with sign-in: a remote MCP server handles that connection in one place. See MCP servers for WordPress: what exists for what is available there.
This is my judgement from two small tools. If you run a server with dozens of tools, or tools that return large outputs, the trade changes and you should measure your own setup.
What I could not verify
- Whether the 74 ms and $0.0076 gaps would survive repeated runs. I ran each path once.
- Token counts per run. I report duration, turns and the cost the CLI printed, not tokens.
- Behaviour with many tools, large outputs, other models or other hosts.
- Any claim about what other people measure. I read no benchmark on this and cite none.
Do this today
Take one tool you plan to expose to an agent and ask whether it already works as a command. If it does, run it from claude -p with a narrow Bash permission and look at the turns and cost it reports.
Only wrap it in an MCP server if you need a second host, typed results or a resource or prompt alongside it.