ComparisonNew

MCP vs CLI

Should you give your coding agent tools through an MCP server, or just let it use the command line?

Alex Garrett-SmithOct 216 minAgents and context
MCP vs CLI
MCP

An MCP server describes its tools to the agent, which calls them directly without a terminal.

Docs for MCP
CLI

The agent runs the same command line tools you do, like gh or playwright-cli, in a terminal.

Docs for CLI

Use a CLI when there's a good one, and MCP when there isn't. I gave Claude Code the same eight tasks through each one, and with Sonnet 5.5 both got every answer right. MCP used 2.1× the tokens to get there, though, and cost 2.1× as much. Most of that came down to how well Sonnet used the terminal, so let's take a look at what it actually did.

How it works

What each one sends and gets back

Let's start with a single job. Both routes end up doing the same thing behind the scenes, but the agent asks for things differently, and the amount of text that comes back can be very different. These are real calls Claude Code made during my test, so pick a job and compare them.

CLIBefore it starts

Nothing is loaded for gh. The model already knows it from training, so it went straight to the command.

It runs
$ gh pr view 14578 -R cli/cli \
  --json author,changedFiles,reviews,state,title \
  --jq '{title, state, author: .author.login, changedFiles,
    approvers: [.reviews[] | select(.state=="APPROVED")
    | .author.login]}'
It gets back135 characters
{"approvers":["BagToad"],"author":"williammartin",
 "changedFiles":8,"state":"MERGED",
 "title":"Replace extension browse with Bubble Tea"}
MCPBefore it starts

Tool names load at the start. The full definition of pull_request_read, around 4,600 characters, loads when the agent asks for it.

It calls
pull_request_read({ method: "get", owner: "cli", repo: "cli", pullNumber: 14578 })
pull_request_read({ method: "get_reviews", owner: "cli", repo: "cli", pullNumber: 14578 })
It gets back19,564 characters
{"additions":1781,"base":{"ref":"trunk","repo":{"description":
"GitHub's official command line tool","full_name":"cli/cli"},
"sha":"6fc1c29d…"},"body":"<!--\nThank you for contributing to
GitHub CLI!\n\nIf you are proposing a fix for a security issue…
…plus every review, including two long Copilot review summaries

Both got it right: williammartin opened it, it changed 8 files and BagToad approved it. The CLI asked for five fields and used --jq to filter the reviews down, so only 135 characters ever reached the model.

The MCP tool sent back the whole pull request and every review instead. That's about 145 times as much text for the agent to read through, just to find the same three answers.

I've trimmed the outputs to fit, but the sizes are the full number of characters each tool sent back to the agent.

Before the first message

What the tools cost before your agent does anything

Before the agent runs anything, there's another cost to think about. An MCP server sends the agent a description of every tool it has, and that text sits in the context window for the whole session. A CLI only needs the terminal tool, whatever you run through it, so switch things on and off to see what I measured in Claude Code.

TerminalClaude Code's Bash tool, for any CLI
GitHub MCP serverDefault toolsets or every toolset
Playwright MCP server25 browser tools
Tool searchLoad MCP tool definitions only when needed
22,160tokens
before you've typed anything, and sent again on every turn
  • Terminal (Bash tool) · 1,767Covers every CLI the agent runs
  • GitHub MCP, 46 tools · 20,393Every tool definition, loaded up front

With every definition loaded, GitHub's server adds 20,393 tokens before your agent has done anything, and that's sent again on every turn. Switch Tool search on to see what Claude Code does by default now.

Try 95 tools as well. That's every toolset GitHub offers, and the cost more than doubles.

Measured on 15 October 2026 with Claude Code 2.1.300 and Sonnet 5.5, by starting a session that replies "OK" and subtracting the 2,887 tokens it uses with no tools at all. I added up the combinations from single measurements, so treat them as approximate.

The test

I gave both the same jobs

So that's a single call and the cost of getting started. To see how it all adds up over a whole job, I ran Claude Code on eight read-only tasks, three times for each setup. Five use GitHub (gh against GitHub's MCP server) and three use a small shop running on my machine (playwright-cli against Playwright MCP).

Pick a task and hit Replay to watch the middle run of each three, by token count.

Model
GitHub · gh vs GitHub MCP
Browser · playwright-cli vs Playwright MCP
In the GitHub repo cli/cli, look at pull request #14578. Who opened it, how many files did it change, and who approved it?
CLI✓ 3/3 right
Context4,997 tokens
  1. $ gh pr view 14578 -R cli/cli --json author,changedFiles,reviews,state,title --jq '{title,state,author:.author.login,changedFiles,approvers:[.reviews[]|select(.state=="APPROVED")|.author.login]}'135 chars
9.9ktokens
$0.014cost
4.0stime
Final answer

PR #14578 in cli/cli, "Replace extension browse with Bubble Tea" (merged): - Opened by: williammartin - Files changed: 8 - Approved by: BagToad

MCP✓ 3/3 right
Context14,956 tokens
  1. pull_request_read {"method": "get", "pullNumber": 14578}5,953 chars
  2. pull_request_read {"method": "get_reviews", "pullNumber": 14578}13,611 chars
27ktokens
$0.060cost
7.0stime
Final answer

PR #14578, "Replace extension browse with Bubble Tea": - Opened by: williammartin - Files changed: 8 - Approved by: BagToad, on 2026-10-07. It was the only approval. The other reviews were comments from williammartin and the Copilot reviewer bot. The PR was merged on 2026-10-08, and williammartin did the merge.

MCP, all tools loaded✓ 3/3 right
Context33,914 tokens
  1. pull_request_read {"method": "get", "pullNumber": 14578}5,953 chars
  2. pull_request_read {"method": "get_reviews", "pullNumber": 14578}13,611 chars
59ktokens
$0.055cost
5.1stime
Final answer

PR #14578, "Replace extension browse with Bubble Tea": - Opened by: williammartin - Files changed: 8 - Approved by: BagToad, on 2026-10-07. This is the only approval. The other reviews were comments from Copilot and williammartin. The PR was merged on 2026-10-08.

Across three runs, MCP used a median of 27k tokens against 9.9k for the CLI, which is 2.7× as many.

All nine runs got this right. The CLI did it in a single command, while MCP had to search for the tool first and then make two calls, pulling back roughly 19,500 characters of pull request and review data along the way.

The amber lane is the same MCP server with tool search off, so every tool definition loads up front, which is how Claude Code worked before tool search. It used 59k tokens but cost $0.055, because those definitions get cached, and cached tokens are much cheaper.

Long commands and answers are trimmed, marked with …

Across every task

One task on its own doesn't tell you much, so here's the median for every task and setup.

Sonnet 5.5 · switch model above
Look up a PRGitHub
CLI: 9.9k tokens
MCP: 27k tokens
MCP, all tools loaded: 59k tokens
MCP 2.7×
Debug a CI failureGitHub
CLI: 19k tokens
MCP: 33k tokens
MCP, all tools loaded: 93k tokens
MCP 1.7×
Count merged PRsGitHub
CLI: 9.9k tokens
MCP: 20k tokens
MCP, all tools loaded: 54k tokens
MCP 2.0×
Filter issuesGitHub
CLI: 10k tokens
MCP: 28k tokens
MCP, all tools loaded: 52k tokens
MCP 2.8×
Unresolved reviewsGitHub
CLI: 10k tokens
MCP: 22k tokens
MCP, all tools loaded: 55k tokens
MCP 2.2×
Filter and sortBrowser
CLI: 25k tokens
MCP: 36k tokens
MCP 1.5×
Page through resultsBrowser
CLI: 36k tokens
MCP: 87k tokens
MCP 2.4×
Fill in a formBrowser
CLI: 28k tokens
MCP: 58k tokens
MCP 2.1×
  • CLI
  • MCP
  • MCP, all tools loaded

With Sonnet, MCP used more tokens than the CLI on 8 of 8 tasks. The CLI got 24 of 24 answers right and MCP got 24 of 24.

Switch to Haiku 5.5 above to see how a smaller model did.

What other tests found

Saying that, my tasks are all reads on well known tools, which is a good fit for a CLI. Other people have tested different things, and their results don't all line up with mine.

Scalekit · March 2026

Five read-only GitHub tasks on Sonnet 4. gh used 4 to 32 times fewer tokens than GitHub's MCP server and finished 25 of 25 runs. MCP finished 18 of 25, and all seven failures were connection timeouts.

scalekit.com ↗
Port of Context · March 2026

Twelve Stripe tasks, including writes, on Sonnet 4.6. Everything passed, but the stripe CLI was the most expensive at $2.22, against $1.60 for MCP. Creating an invoice took 19 turns through the CLI and 12 through MCP.

portofcontext.com ↗
Mario Zechner · August 2025

His own terminal tool built as both an MCP server and a CLI, tested alongside tmux and screen over 120 runs. Both versions of his tool succeeded every time, and the MCP one was 23% faster and 2.5% cheaper. His conclusion was that "MCP vs CLI truly is a wash".

mariozechner.at ↗
Your setup

When is MCP worth it?

My test is close to the best case for a CLI, with popular tools on a developer's laptop and one person signed in. Plenty of setups look different, so answer these about yours and I'll tell you which way I'd go.

Can your agent run commands in a terminal?Claude Code, Codex and Cursor can. Claude on the web, ChatGPT and most chat apps can't.
Is there a good CLI for the service?Think gh, aws, stripe or psql. Plenty of SaaS apps only have an API.
Is the agent acting for other people, each with their own account?Like a support bot that files issues as the customer, or an agent in your product.
Do you need to strictly limit what the agent can do?For example, read-only access with no way to run anything else.
I'd give the agent the CLI
  • This is what my test looked like, and the CLI got the same answers using fewer tokens. You can also see and rerun every command the agent ran.
  • If you find yourself explaining the same commands to the agent over and over, write them into a skill or AGENTS.md before reaching for a server.

Side by side

CriterionMCPCLI
How the agent learns the toolThe server sends a definition for every toolFrom training for popular tools, otherwise --help
Cost before it startsAbout 20,000 tokens for GitHub's server, or 2,200 with tool searchAbout 1,800 tokens for the terminal tool, whatever you run
Trimming the outputOnly if the tool has options for it, like tail_linesPipes, --jq, grep, head
Steps per turnOne per tool call, although the agent can make a few at onceSeveral, chained with &&
Needs a terminalNo, so it works in Claude, ChatGPT and other chat appsYes
Signing inEach user signs in with OAuth through their own clientWhoever's signed in on that machine
Limiting what it can doAllow or deny each tool. Some servers have a read-only modeCommand permission rules, or a sandbox
In my test (Sonnet 5.5)24 of 24 right, $0.43 for all eight tasks (median runs)24 of 24 right, $0.21 for all eight tasks (median runs)

When to pick which

Pick MCP if
  • The agent has no terminal, like Claude on the web or ChatGPT
  • The service has no decent CLI
  • The agent works for other people who each have their own login
  • You want to allow specific actions and nothing else
Pick CLI if
  • There's a well known CLI for it, like git, gh, aws or stripe
  • Your agent runs in a terminal, on your machine or in CI
  • It'll pull back lots of data that it only needs part of
  • You want to see and rerun every command the agent ran

How we tested

Task
Eight read-only tasks in Claude Code, run three times per setup. Five used GitHub, with gh against GitHub's remote MCP server, and three used a small shop running on my machine, with playwright-cli against Playwright MCP.
Evidence
111 headless Claude Code sessions (claude -p) on 15 October 2026, with no other tools loaded. Each answer was checked against the real data.
With
Claude Code 2.1.300, Sonnet 5.5 and Haiku 5.5, gh 2.86.0, GitHub's remote MCP server, with and without tool search, @playwright/cli 0.1.22, @playwright/mcp 0.0.83, with tool search

Updates

  • Published.