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

Table 1. CLI and MCP compared
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 (git, gh, curl, jq) from training, so little or no description is needed. An unfamiliar tool costs a --help call.

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

--help, man pages, completion and a schema command (see Self-Describing Help). The agent learns by running the tool.

tools/list returns every tool with a description and typed schemas in a standard form; clients and hosts can present them uniformly.

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 (inputSchema, outputSchema), and results can be returned as structuredContent; the host and SDK can validate before and after the call.

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 gh already installed and authenticated by the developer, gets a lot from a few shell commands: models know gh, 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.

The same question through the CLI, with a bounded and structured answer
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 --json supplies the inputSchema and outputSchema, 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.

Table 2. Deciding quickly
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 --json through jq and 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 --help calls 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.