CLI vs. MCP
|
This content was generated with the assistance of AI and should be verified against the official documentation of each tool and framework before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
This page was written against the MCP specification’s latest revision, Claude Code’s documented behaviour, the GitHub CLI and the
GitHub MCP server, and the docsctl running example of this sub-section, as checked on 2026-09-30. Hosts, servers and
articles change quickly; re-check the linked sources before relying on a detail.
Whether to give an agent a CLI or an MCP server is a recurring argument, and both camps have a point. This page states the trade-offs and leaves the verdict to your constraints. The short version: a CLI is cheap, familiar to models and works anywhere there is a shell, while MCP offers typed schemas, standard authorization, governance and reach into hosts without a shell. Often the right answer is one implementation exposed both ways, which is why the rest of this sub-section designs the CLI so that it can be wrapped as an MCP server with little effort.
The trade-offs
| Dimension | CLI (run through a shell tool) | MCP server |
|---|---|---|
Context cost |
Nothing is loaded until the command is run; only the output is paid for. Models already know common CLIs ( |
Tool names, descriptions and schemas are loaded into context up front by default (hosts increasingly defer or search tool definitions to reduce this). Results come back as a structured payload that counts against the host’s output limit. |
Discoverability |
|
|
Typing |
Arguments are strings on a command line; validation is the tool’s own and the failure comes back as an exit code and a message. JSON output can be schema-described but nothing in the protocol enforces it. |
Input and output are declared with JSON Schema ( |
Auth |
Whatever the tool implements: environment variables, token files, credential stores, device flows. The agent (or its sandbox) needs access to the secret, which raises the trade-offs on Configuration & Auth. |
A standard authorization framework for remote servers (OAuth-based) that lets a host obtain scoped tokens on the user’s behalf without the model ever seeing them (see MCP Authorization). |
Governance |
Controlled by the host’s shell permissions and sandbox: allow and deny rules over command lines, filesystem and network isolation. Powerful and blunt; auditing means logging shell commands. |
Tools are individually named, so a host can allow, deny or require approval per tool, and a central server can log every call and enforce policy. Annotations describe read-only or destructive behaviour but are hints, not guarantees. |
Host support |
Needs a host with a shell tool and a machine that has the binary installed. Excellent for coding agents; absent from many chat and enterprise hosts and hosted agents. |
Supported by many coding, desktop and cloud agent hosts, including ones that have no shell at all, and reachable over the network without installing anything locally (remote servers). |
Composition |
Pipes, files and scripts: an agent can chain, filter and store intermediate results without passing them through the model. |
Each call returns to the model; chaining goes through the model unless the host supports code execution over tools (below). |
Failure and safety model |
The command runs with the user’s privileges in the user’s environment unless sandboxed; argument injection and shell quoting are the main risks (see Security). |
Local servers share the same risk; remote servers add network and identity risks, and tool descriptions themselves can be attack input (see MCP Security). |
Read the table as tendencies, not laws. A CLI can be governed well (a sandbox, a narrow allowlist), and an MCP server can be expensive (hundreds of loosely described tools). The engineering matters more than the transport.
Two disagreements are worth knowing about because reasonable people land on both sides. The first is secrets in environment variables: clig.dev advises against them for sensitive values, while posts on building agent-friendly CLIs recommend them for headless use; a token file or a credential store, plus an environment variable for CI, is the middle path (see Configuration & Auth). The second is whether agents "prefer" CLIs: they are strong with familiar ones and weaker with bespoke ones, which is exactly what good help text and a skill try to fix.
References: MCP specification — Tools, Claude Code — Best practices (which describes CLI tools as a context-efficient way to use external services).
Case study: gh and the GitHub MCP server
GitHub ships both. The GitHub CLI (gh) covers issues, pull requests, releases, workflow runs
and a raw gh api, with --json, --jq and --template for structured output (see
Machine-Readable Output). The
GitHub MCP server exposes GitHub operations as MCP tools, locally or as a hosted
remote server with OAuth.
The comparison shows how the dimensions play out:
-
A coding agent in a terminal, with
ghalready installed and authenticated by the developer, gets a lot from a few shell commands: models knowgh, output can be piped through--jq, and nothing has to be loaded in advance. -
A hosted or chat agent with no shell, or an enterprise that wants per-tool approval, central audit and OAuth scopes instead of a personal token in an environment variable, is better served by the MCP server.
-
Both use the same underlying API and the same account permissions; what differs is the packaging, not the capability.
gh pr list --repo albertoirurueta/docs --state open --limit 5 --json number,title --jq '.[] | "\(.number) \(.title)"'
docsctl search "kalman filter" --limit 5 --json | jq -r '.results[].title'
The MCP route returns the same data as a typed tool result instead, at the price of loading the tool definitions into the context up front.
Neither is "the right one". They are two front doors to the same service, chosen per host and per policy.
When to ship both
If your tool will be used by more than one kind of host, build the capability once and expose it twice.
-
CLI first. A CLI is the easiest thing to build, test and use yourself, and the discipline of the previous pages (JSON output, exit codes, dry-run, self-describing help) makes it a good foundation.
-
MCP as a thin wrapper generated from the CLI’s own metadata: each command becomes a tool,
docsctl schema --jsonsupplies theinputSchemaandoutputSchema, and the safety block supplies annotations. The wrapper calls the CLI with an argv array, injects--json --no-input, allowlists commands and flags, caps output and never auto-confirms. The Wrapping a CLI as an MCP Server shows this for Python, TypeScript and Spring AI, Wrapping a CLI as an Agent Tool covers the agent-framework and host-permission routes, and Designing Good MCP Servers covers the MCP side of tool design. -
Keep one source of truth for behaviour, so the two front doors cannot drift, and test both.
-
Prefer an MCP server implemented natively (calling a library or the service directly) when latency, streaming or server-side governance matter more than reuse; a wrapper is a convenience, not a requirement.
-
Ship a skill for the CLI and keep the MCP tool descriptions equally clear, since each host learns from a different channel.
| Situation | Lean toward |
|---|---|
Only coding agents in a terminal, familiar or self-describing tool, you control the machine |
CLI |
Hosted or chat agents, no shell, or several hosts and clients |
MCP (remote server) |
Central policy, per-tool approval, audit trail and scoped OAuth are requirements |
MCP |
Heavy piping, large intermediate data, scripting |
CLI, or code execution over tools |
A tool for both audiences |
CLI plus a thin MCP wrapper |
Code execution over tools
A third design sidesteps some of the cost of both. Anthropic’s article Code execution with MCP describes presenting MCP servers to the agent as code APIs, for example files on a filesystem, instead of loading every tool definition into the context. The agent discovers what it needs by looking at the files, writes a short program that calls the tools it wants, and processes the intermediate results in the sandbox; only the final, filtered result returns to the model. The article argues that this cuts context use (tool definitions are loaded on demand and intermediate data never passes through the model) and that it makes control flow such as loops and conditionals ordinary code.
What that means for a CLI author:
-
A CLI already fits this model: a script that pipes
docsctl search --jsonthroughjqand prints three lines is code execution over a tool, with the CLI as the API. The stable, projectable JSON output from the earlier pages is what makes it work. -
It needs a sandbox, because the agent is now running code; the article and the host documentation both stress isolation and resource limits (see MCP Security and Claude Code sandboxing).
-
It adds complexity (the runtime, the sandbox, the generated wrappers) that is worth paying for when there are many tools or large intermediate results, and not for a handful of small ones.
The article is Anthropic’s own proposal, evaluated by Anthropic; treat its claims as a design argument to test on your workload, in the same spirit as the vendor comparisons below.
Reading vendor comparisons
Several companies that sell CLI-related or MCP-related products have published token-cost comparisons of "MCP versus CLI". Two often cited are from Firecrawl and CircleCI. This page does not repeat their figures. They are vendor claims: measurements chosen and run by parties with a product on one side of the question, on particular tasks, hosts, models and tool sets, that may not resemble yours. Read them for the method and the arguments they make, and then check with your own numbers:
-
count the tokens of your tool definitions (MCP) and of your typical outputs (both) with your model’s tokenizer;
-
include the
--helpcalls a CLI needs to be learned, and the retries caused by unclear errors; -
count total task cost and success rate, not one message;
-
remember that hosts change quickly: deferred or searched tool loading narrows the up-front cost of MCP, and skills and self-describing help reduce the learning cost of a CLI.
The estimate technique on Agent Ergonomics applies to both sides. For deeper background on the tools themselves, see Model Context Protocol and Tool Design.