Daniel Rosehill Hey, It Works!
API or MCP? When the CLI Just Works Better
· Claude Code

API or MCP? When the CLI Just Works Better

The MCP protocol promises unified tool access for AI agents, but sometimes a plain API call or CLI command is more reliable. What does that tell us about MCP's maturity?

I was halfway through publishing a blog post via my Contentful MCP connection when it timed out. The rich text payload was too large, apparently — or the MCP server was having a bad day, or something in the aggregation chain hiccupped. Hard to say, really (debugging MCP failures is its own adventure). So I fell back to what I probably should have done in the first place: a curl command hitting the Contentful Management API directly.

It worked instantly.

This isn’t a one-off. I’ve been noticing this pattern for months now, and it’s become frequent enough that I’ve started baking it into my workflow as a deliberate strategy: try the MCP, and when it chokes, hand the agent a CLI command or a raw API call instead. The success rate on the fallback path is embarrassingly high.

The Pattern

Here’s what keeps happening. I’ll have an MCP server configured for some service — Contentful, GitHub, a database, whatever. The MCP exposes a set of tools that an AI agent can call. In theory, this is the dream: the agent discovers the tools, understands their schemas, and invokes them without needing to know the underlying API. In practice, the tools frequently time out on larger payloads, return cryptic errors that are harder to debug than the raw API responses would be, or simply fail silently in ways that leave you guessing.

Meanwhile, the same operation executed as a CLI command or a direct API call (via curl, gh, psql, whatever the native tool happens to be) works first time, every time. The agent doesn’t even need special tooling — it just needs shell access and knowledge of the CLI’s flags.

I’ve seen this with:

  • Contentful — MCP times out on large rich text entries; the Management API via curl handles them without complaint

  • GitHub — the gh CLI is rock-solid for creating PRs, managing issues, and querying repos, while GitHub MCP servers occasionally lose their connection or return partial results

  • Databases — psql and direct SQL are more reliable than database MCP tools, especially for complex queries or bulk operations

  • File operations — native filesystem commands outperform MCP-wrapped equivalents almost universally

The pattern is consistent enough that I’ve started writing my agent skills with a two-tier approach: “try MCP first, fall back to the CLI/API.” Which raises an uncomfortable question.

Does This Mean MCP Is Useless?

No. But it does mean MCP is immature — and that’s an important distinction.

The protocol itself is sound (genuinely). The idea of giving AI agents a standardised way to discover and invoke tools, with typed schemas and structured responses, is exactly right. The alternative — hardcoding every integration, teaching every agent the specific CLI for every service — doesn’t scale. MCP solves a real problem.

The issues aren’t in the protocol design. They’re in the implementation layer:

Transport reliability. MCP servers sit behind a transport layer (stdio, SSE, streamable HTTP) that adds failure modes the underlying API doesn’t have. When you call the Contentful API directly, you’re making one HTTP request. When you call it through an MCP server, you’re making a request to the MCP client, which talks to the MCP server (possibly through an aggregator, possibly over a tunnel), which then makes the API call, and the response has to travel all the way back. Every hop is a potential timeout or serialisation failure.

Error surface area. Raw API errors are well-documented and googlable. MCP errors — “MCP error -32602” or a silent timeout — tell you almost nothing. Was it the transport? The server? The aggregator? The payload serialisation? The tool schema validation? Good luck figuring it out without reading the server’s source code.

Payload handling. Many MCP servers weren’t designed for large payloads. They work brilliantly for “get me the current weather” or “list my calendar events” but buckle under a 3,000-word rich text document or a bulk database operation. The underlying APIs handle these payloads routinely — the MCP wrapper is the bottleneck.

Schema fidelity. Sometimes the MCP tool’s schema doesn’t perfectly match the API it wraps. Fields get renamed, optional parameters get dropped, complex nested structures get flattened. The tool works for the common case but falls apart on edge cases that the raw API handles fine.

What This Actually Tells Us

I think the honest read is that MCP is in its “useful but fragile” phase. The protocol has crossed the threshold from “interesting experiment” to “I use this every day” — I run dozens of MCP servers across my setup, and they handle the majority of my agent-to-service integrations. But it hasn’t yet crossed the threshold from “works most of the time” to “works reliably enough that I don’t need a fallback.”

The analogy I keep coming back to (and I realise I’m the sort of person who always has an analogy) is early REST APIs versus the SOAP ecosystem they replaced. SOAP had better tooling in theory — typed schemas, WSDL discovery, formal contracts. REST was scrappier but more transparent: you could debug it with curl, the error messages made sense, and the failure modes were obvious. REST won not because it was more sophisticated but because it was more reliable in practice.

MCP is the SOAP in this analogy. Not because it’s bad — it’s genuinely well-designed — but because the implementation ecosystem hasn’t caught up with the protocol’s ambition. The servers are often thin wrappers around APIs, written quickly, not stress-tested against large payloads or concurrent requests or network instability. The aggregation layers (which I use heavily) add latency and failure modes. The debugging story is poor.

The Pragmatic Middle Ground

So what do I actually do about this? I keep using MCP — but I also keep CLI fallbacks in my skills and agent configurations. The approach I’ve landed on:

  1. MCP for discovery and simple operations. When I’m listing items, reading small payloads, or doing CRUD on single records, MCP works well and saves the agent from needing to know service-specific CLI syntax.

  2. CLI/API for heavy lifting. When the operation involves large payloads, bulk operations, or anything where reliability matters more than convenience, I route through the native tool.

  3. Skills that encode the fallback. Rather than hoping MCP will work, I write my agent skills with explicit fallback paths: “try MCP first; if it fails, here are the curl commands and credentials to do it directly.” This way the agent doesn’t get stuck.

  4. Monitor and promote. When an MCP server proves reliable over time, I gradually remove the fallback path. When it proves flaky, I demote it and make the CLI the primary method.

This isn’t elegant. It’s the kind of duct-tape architecture that makes protocol purists wince. But it works — which, when you’re trying to ship a blog post at midnight and the MCP just timed out again, is the only thing that matters.

Where This Goes

MCP will get better. The protocol is too useful and too well-backed to stay in the “fragile” phase forever. Server implementations will mature, error handling will improve, transport layers will get more robust. Aggregation tools like MCP Jungle are already making the operational side more manageable.

But in the meantime, the pragmatic advice is: don’t bet everything on MCP. Keep your CLIs sharp, keep your API tokens accessible, and teach your agents that sometimes the best tool for the job is a well-crafted curl command. The protocol is the future, but the command line is still the present — and it works.