That tweet got 1.6k likes in March:
Perplexity’s CTO reportedly told his team they’re moving from MCP to APIs and CLIs:
OpenClaw left MCP out on purpose:
Garry Tan’s version was shorter: “MCP sucks honestly.”"
They’re half right: the problem is real, but the diagnosis isn’t. What’s broken is how most agents use MCP, and the fix is not to throw the protocol away but to stop using it badly.
This piece builds on my talk at AI Engineer World’s Fair “MCP doesn’t suck. Your agent does.” (San Francisco, July 2026). Watch it on YouTube.
The problem is the harness, not the protocol
Most agents treat MCP tools as prompt-time function calls. Connect a server and every tool definition lands in the context window. Call a tool and the full result lands there too. Ten servers with five tools each, and you pay thousands of tokens on every turn before the agent has done anything. Results pile up, context rots, the agent gets slower and less accurate, and data the model never needed to see is now inside the model.
None of that is in the spec. MCP already has the fixes: progressive tool discovery (Anthropic’s tool search tool, Cursor’s dynamic context discovery), code mode (Cloudflare and Anthropic both wrote it up), and sub-agents with split context. But most MCP clients don’t implement them. The protocol moves faster than the ecosystem.
Now look at what CLIs get right, mostly by accident. Agents never load a CLI’s docs all at once; they read --help when they need it. They run CLI tools as code by default, chaining them with pipes and shell scripts. And every model knows the shell by heart, because there’s 50 years of it in the training data. The catch here: a CLI is a local black box. No standard transport, no standard auth, no discovery, no way to scope or intercept what it does to a remote service.
That’s why agents have MCP connectors, not CLI connectors.
MCP for remote, CLI for local
The fix is to use each where it’s strong. MCP stays the standard remote interface: server discovery, authentication, and access control. The CLI becomes the local interface between the agent and MCP. That’s what we built in mcpc, an open-source universal CLI client for MCP:
┌──────────┐ Bash() ┌────────┐ MCP ┌────────────┐
│ AI agent │ ─────────► │ mcpc │ ────────► │ MCP server │
└──────────┘ └────────┘ └────────────┘
Sessions, OAuth, Tools,
Resources, Prompts,
Tasks, x402, ...
The agent only needs one tool, Bash(), to call mcpc, learn how it works through --help, and interact with MCP servers. And it can leverage the full MCP protocol out of the box: persistent sessions, OAuth 2.1 (including enterprise SSO), tools, resources, prompts, async tasks, skills, x402 payments, and a code mode using --json. mcpc speaks MCP 2026-07-28 and falls back to older versions. No LLM inside, fast, and minimal dependencies. As a bonus, one login and one set of live sessions can be shared between many agents on the same machine.
What it looks like in the shell
brew install apify/tap/mcpc # or: npm install -g @apify/mcpc
mcpc login mcp.apify.com # OAuth once; tokens go to the OS keychain
mcpc connect mcp.apify.com @apify # persistent session
mcpc @apify # server info, capabilities, instructions
mcpc @apify grep "crawler" # progressive tool discovery
mcpc @apify tools-get search-actors # one tool's schema, only when needed
mcpc @apify tools-call search-actors keywords:="tiktok scraper"
And code mode, where the agent writes a script instead of making a round trip through its context for every call:
mcpc @apify tools-call search-actors keywords:="tiktok scraper" limit:=1 --json \
| jq -r '.content[0].text | capture("`(?<actor>[^`]+)`").actor' \
| xargs -I {} mcpc @apify tools-call fetch-actor-details actor:="{}" --json
That’s progressive discovery and code mode on any MCP server, whether or not the agent’s own MCP client supports either.
What the evals say
We built connector-bench to measure the efficiency of mcpc against CLIs and naive MCP implementations. Each run gives an agent the same cross-server task under three harnesses: raw MCP with every tool loaded into context, the native CLIs for the same services, and mcpc. We track cumulative cost against wall-clock time.
Here’s an example comparing Apify MCP server with Apify CLI on an Actor discovery scenario:
In many of our tests, mcpc finishes the job faster than native CLI, albeit sometimes with higher cost. That’s understandable, as native optimized CLIs are usually less verbose and more token-efficient than a generic CLI wrapper for MCP. But we believe there is plenty of room for optimization and the performance of mcpc will converge towards native CLIs.
So stop saying CLI beats MCP
MCP + CLI beats both. Even OpenClaw uses MCP through mcporter, an MCP-to-CLI converter, which proves the point. The problem was never the protocol. It was that agents implemented MCP poorly.
MCP has ten official SDKs for languages like TypeScript, Python, or Go, but none for the shell, the most universal programming language. mcpc is our attempt to fill that gap, so any agent with a code runtime can use all of MCP.
Try it, break it, star it:
apify
/
mcpc
The most compatible MCP CLI client. Supports: tools, resources, prompts, completions, async tasks, skills, stdio and Streamable HTTP (MCP 2026-07-28 and 2025-11-25). Persistent sessions, OAuth 2.1 with DCR, CIMD, client credentials, and ID-JAG, OS keychain, --json for code mode, grep across servers, proxy for AI sandboxes, x402 & more.
mcpc — a universal MCP CLI client
mcpc is a command-line client for the Model Context Protocol (MCP)
that maps every MCP operation to an intuitive shell command.
Use it to manually inspect and debug MCP servers, to script repeatable MCP workflows in plain shell, or to
give AI agents the full MCP protocol through a single Bash() tool call, so they can interact with any MCP
server and its latest capabilities using the most universal programming interface there is: the UNIX shell.
Key features:
- 🔧 Full MCP support - Tools, prompts, resources, async tasks, skills, notifications, and logging over stdio and Streamable HTTP.
- 🔄 Persistent sessions - Keep connections to multiple servers alive in parallel, whether the server protocol is stateful or stateless.
- 🗺️ Progressive tool discovery - Find relevant MCP tools on the fly to save tokens and increase accuracy.
- 🔌 Code mode - JSON output composes with…
Top comments (1)
Agree on the diagnosis, with one data point from the other side of the table: I publish data Actors on the Store and watched how agents call them through mcp.apify.com. Two harness habits fixed most of what people blame on the protocol. First,
?tools=on the server URL, so the agent sees five tool definitions instead of the whole Store; that alone removed the wandering and most of the per-turn token cost. Second, the Actors expose a count mode that returns no rows, and the agent is told to call it first, so the paid call becomes a decision the harness can gate. A PreToolUse hook onmaxResultsdid that in Claude Code; when the hook blocked a 25,000-row pull the agent self-corrected to a 100-row sample without being told. The CLI version is the same JSON on stdin, and the agent takes whichever is in front of it. The protocol was never the bottleneck; the defaults were.