Skip to main content

MCP vs CLI vs Skills - Comparison and When to Use Each

This guide sorts out the claims in "MCP is dead. Long live the CLI" and the rebuttals and updates that followed, and gives criteria for choosing between MCP, CLI, Skills, and function calling. The short version: neither side is simply right. In practice, you choose by who the users are, which clients you target, and what your authentication and audit requirements are.

1. What This Document Covers​

  • The claims in MCP is dead
  • Practical pain
  • Quandri's verification
  • Rebuttal 1: enterprise use and HTTP
  • Rebuttal 2: points resolved in 2026-07-28
  • When the CLI wins and when MCP is needed
  • Relationship to Skills and difference from function calling
  • A decision flow and hybrid setups

The claims in MCP is dead​

In a post dated 2026-02-28, Eric Holmes argued that MCP provides no real benefit and that the CLI is better. His points:

PointClaim
No special protocol neededLLMs already know CLIs from man pages, Stack Overflow, and shell scripts on GitHub. Tell one to run gh pr view 123 and it works. With MCP you end up writing the same documentation about each tool and when to use it anyway
Humans can reproduce with the same commandsWhen an LLM does something unexpected with Jira, you can run jira issue view yourself and see the same output. An MCP tool exists only inside the LLM conversation, so you end up digging through JSON transport logs
CLIs compose through pipesjq, grep, and redirects can narrow huge results. With MCP you either put everything in the context or build filtering into the server
Existing auth is enoughaws profiles and SSO, gh auth login, and kubectl kubeconfig work as they are. When they break, you fix them as usual with something like aws sso login
No moving partsA local MCP server is a process that has to start and stay running. A CLI is just a binary on disk

Practical pain​

Beyond the design argument, he lists day-to-day friction.

  • Flaky initialization
    • An MCP server sometimes fails to come up and the client has to be restarted
  • Re-authentication never ends
    • With several MCP tools, each server needs its own authentication. A CLI with SSO or long-lived credentials only needs it once
  • Coarse permissions
    • In Claude Code you can only allowlist MCP tools by name, with no way to restrict to read-only operations or restrict parameters. With a CLI you can allow gh pr view and require approval for gh pr merge

Quandri's verification​

Quandri's engineering blog ran measurements on its own stack in response to that post.

  • Context consumption
  • Speed
    • It cites a measurement attributed to the original post's author: the Jira MCP was about 3x slower than calling the REST API directly, and about 9.4x slower on the first call including initialization. The post explains this as architectural overhead, since an MCP server adds a process layer between the LLM and the API
  • Operating policy
    • Day-to-day gh / psql / aws use Bash and CLI, repeatable workflows use Skills, and services without a strong CLI or where team-wide authentication and permission scoping matter use MCP. If a CLI already exists and is authenticated locally, the post calls that usually the lightest option

The same post adds that Claude Code's Tool Search largely addressed the context problem. Read the measurements as describing a naive implementation before that.

Rebuttal 1: enterprise use and HTTP​

Charles Chen concedes that MCP over stdio is often better replaced by a simple CLI, but argues that MCP over Streamable HTTP is the linchpin of organizational and enterprise adoption.

  • MCP is just a thin payload and interaction model on top of HTTP, so everything you use to secure HTTP (TLS, OAuth, OIDC) applies directly
  • The observability and telemetry you roll out for HTTP endpoints (OpenTelemetry, logging) applies directly
  • The server frameworks and operational know-how you already use for API servers can deliver MCP capabilities
  • Scaling and load balancing follow the usual HTTP approach

He says CLIs suit work without auth and solo developers, but pose an operational and security risk where organizational authentication, authorization, observability, and scale are needed.

Rebuttal 2: points resolved in 2026-07-28​

The 2026-07-28 revision answers several of the operational complaints at the specification level.

ComplaintChange in 2026-07-28
Flaky initialization, many moving partsinitialize and sessions are removed. Each request is self-contained and can land on any instance behind a load balancer
Slow first callThe initialization exchange is gone. Still, measure the actual speed
Hard to debugSelf-contained requests are easy to reproduce with curl
Re-authentication frictionAuthorization was tidied up, including the move to Client ID Metadata Documents (CIMD) and RFC 9207 iss validation
Control at gatewaysThe Mcp-Method / Mcp-Name headers let you route and authorize without parsing JSON

On the other hand, context consumption by tool definitions and the composability of CLI pipes remain valid criticisms. The former can be eased with client-side progressive discovery and Code Mode, but the latter requires the server to provide filtering.

When the CLI wins​

When all three of the following hold, a CLI (with Skills) is the lightest and most reliable choice.

  1. The agent has a shell
  2. A mature CLI exists (gh, aws, kubectl, psql, and so on)
  3. The user is a developer already authenticated on their own machine

Under these conditions the LLM's built-in knowledge applies directly, no definitions need to stay resident, and a human can reproduce a run with the same commands. Charles Chen likewise says to use a local CLI for local capabilities, tools like jq, curl, and grep that are well represented in training data, and tools that need no auth.

When MCP is needed​

MCP is needed when any of the following applies.

  • Clients without a shell
    • Web, desktop, and business apps with no shell, or users who do not use a terminal
  • Organizational control that needs scopes and audit
    • Authorization per tool or scope, and centralized logging and observability on HTTP infrastructure
  • Sharing across multiple clients
    • One server used by several hosts without integration code per client
  • Services with no CLI
    • For example, SaaS products offered only on the web
  • Tools that need state or long-running backends
    • Anything that must hold state behind HTTP
  • Safe access to production databases
    • Quandri points out that an MCP server can enforce read-only mode and block dangerous queries on the server and can manage connection strings internally. Skills plus a CLI cannot stop an LLM from running DROP TABLE. For a local development or personal database, Skills plus a CLI are enough

Relationship to Skills​

A Skill is a folder that bundles procedures and knowledge (a SKILL.md plus supporting files). Quandri compares MCP to "spreading all the menus on the table upfront" and Skills to "asking the librarian for only the book you need".

  • Embed CLI usage in a Skill and load it only when the Skill is invoked. Definitions do not stay resident, and context does not grow with the number of Skills
  • Skills and MCP are not in opposition. With the Skills over MCP extension, a server exposes Skills through skills/list and skills/get, and clients fetch the content only when needed through the Resources mechanism. You can distribute a service's instructions and procedures together with that service's MCP server
  • MCP Prompts are a feature close to Skills, which many hosts invoke through slash commands. Charles Chen compares today's manual syncing of skill files to downloading HTML and JS by hand to run a web app. Host support is uneven, though (it has been pointed out that Codex does not support MCP Prompts)

Skills over MCP is still being implemented in SDKs and hosts. Check each client's support before relying on it.

Difference from function calling​

Function calling is a mechanism where one app defines and runs tools itself for one LLM provider. When the tool owner and the model user are the same, putting an MCP server and client in between is overhead.

MCP pays off when the tool provider and the consumer are different and you want the same tools from several apps (hosts). Because the protocol is standardized, you do not write integration code per app. A host ultimately converts MCP tools into the model's function calling format, so the two are not mutually exclusive.

Decision flow​

Use this flow to pick a first candidate.

This is a starting point. For example, if one app owns its tools for a single provider, function calling alone may be enough, with neither MCP nor a CLI.

Hybrid setups​

In practice, you do not pick just one. Following Quandri's example:

UseChoice
Everyday gh / psql / awsCLI (Bash). No context cost, and you can debug right in the terminal
Repeatable multi-step workflows such as commit drafting and PR reviewsSkills. Loaded only when invoked
Services without a CLI, things that need uniform team-wide authentication, and anything needing control such as a production databaseMCP

2. MCP vs CLI​

AspectCLI (+ Skills)MCP
Context consumptionNo resident definitions. A Skill loads only when invokedDefinitions tend to stay resident. Progressive discovery can reduce this
ComposabilityFilter intermediate results with pipes, jq, and grepResults enter the conversation. Filtering must be provided server-side
DebuggingA human can run the same command to reproduceStateless design makes curl replay easy, but the tool still lives inside the conversation
AuthenticationReuses existing profiles and SSO of aws, gh, and kubectlStandard authorization via OAuth 2.1. Each client needs authorization
Permission granularityPer-command allowlists are possible but depend on the runtime's permissionsControlled per scope and tool, and validated on the server
ClientsOnly environments with a shellAlso works in web, desktop, and business apps without a shell
Reuse across clientsIntegration code needed per clientOne server shared by many clients
Audit and observabilityDepends on local historyCentrally managed on HTTP infrastructure
OperationsJust place a binaryServer operations needed (for remote)

3. Common Pitfalls​

Do not frame it as MCP or CLI​

The debate tends to swing between "MCP is dead" and "MCP is mandatory", but in practice you choose by users, clients, and authentication and audit requirements. As Quandri does, even within one organization you can use a CLI for gh and MCP for Slack or Linear.

Do not apply old measurements to current MCP​

The measurements of context consumption and Jira MCP speed were taken before Tool Search and 2026-07-28. The direction of the argument is useful, but re-measure the numbers in your own environment.

Overtrusting CLI permission control​

With a CLI you can allow gh pr view and require approval for gh pr merge. But that is an allowlist on the host side and depends on the runtime's permissions. MCP tool permissions are per tool name, with no restriction by argument. In both cases, real authorization control belongs in least-privilege credentials such as a read-only token.

Do not pick a CLI just because there is a shell​

Even when the agent has a shell, if the CLI is immature, its output is meant for humans rather than machines, or its authentication depends on a personal environment, MCP can be more stable. When choosing a CLI, check whether it has machine-readable output such as --json.

Do not leave production data access to a CLI just because one exists​

Writing psql into a Skill works, but a CLI cannot stop an LLM from running writes or destructive queries. For production or shared data, use MCP, where read-only mode and query validation can be enforced on the server, or a least-privilege role.

Treating Skills as a security boundary​

A Skill hands over procedures and knowledge; it is not a mechanism for restricting permissions. Treat Skill content and permission grants such as allowed-tools as untrusted input, and use them under user approval.

Comparing while ignoring MCP's context problem​

Many of MCP's disadvantages assume that progressive discovery and Code Mode are not in use. When you compare, align which mitigations the client applies.

4. Code Examples​

Narrowing results with a CLI​

If you narrow with a pipe, intermediate data never enters the context. With MCP, the server has to provide equivalent filter arguments.

# Extract only the numbers and titles of PRs where review is requested from me
gh pr list --search "review-requested:@me" --json number,title \
| jq -r '.[] | "\(.number)\t\(.title)"'

Separating CLI permissions per command (Claude Code)​

In .claude/settings.json, allow the read operations and require approval for the write operation.

{
"permissions": {
"allow": [
"Bash(gh pr view *)",
"Bash(gh pr list *)",
"Bash(gh pr diff *)"
],
"ask": [
"Bash(gh pr merge *)"
]
}
}

MCP tools, by contrast, are allowed by server and tool name. The form is mcp__<server>__<tool>, and wildcards work, but you cannot write restrictions on arguments.

{
"permissions": {
"allow": [
"mcp__github__get_*"
],
"ask": [
"mcp__github__merge_pull_request"
]
}
}

Packaging CLI usage in a Skill​

A Skill starts SKILL.md with YAML front matter holding name and description. Only the description stays resident, and the body is loaded when the Skill is invoked.

---
name: pr-review
description: Review a GitHub pull request with the gh CLI. Use when the user asks to review or summarize a PR.
---

# PR review

1. Get an overview with `gh pr view <number> --json title,body,files`
2. Read the diff with `gh pr diff <number>`
3. Summarize findings by severity. Do not run `gh pr merge`

A hybrid setup (Claude Code)​

Connect only services with no CLI, or that need control, through MCP. Keep using the CLI for everyday tools such as gh.

# Add a service without a CLI as a remote MCP server (use --scope project to share with the team)
claude mcp add --transport http linear https://mcp.linear.app/mcp --scope project

# Authenticate with OAuth from /mcp. To check the registration:
claude mcp list

5. Summary​

  • The claims in MCP is dead are five: no special protocol needed, humans can reproduce, pipes compose, existing auth is enough, and no moving parts
  • The practical pain is three things: flaky initialization, re-authentication, and coarse permissions. Quandri additionally measured context consumption and speed
  • The 2026-07-28 revision's stateless design and authorization cleanup reduced many operational complaints. Context and composability remain valid criticisms
  • The CLI wins when the agent has a shell, a mature CLI exists, and the user is an authenticated developer, all three together
  • MCP is needed for clients without a shell, control that needs scopes and audit, sharing across clients, services with no CLI, and safe access to production databases
  • Skills load CLI usage on demand, do not oppose MCP, and can also be distributed over MCP. Function calling is enough when one app owns the tools for one provider
  • In practice, combine them: CLI for everyday CLIs, Skills for fixed workflows, and MCP for what has no CLI or needs control

References​