{"slug": "the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools", "title": "The Layer You Don’t Control: Rethinking MCP Servers vs. Plain CLI Tools", "summary": "The Model Context Protocol (MCP) introduces a structural problem where developers control only the server middle layer, not the client or model, making failures non-deterministic and hard to debug, according to an analysis by a developer who has built multiple MCP servers. Plain CLI tools offer advantages over MCP servers for agentic AI systems because models already know common CLI interfaces, context costs are pay-as-you-go, debugging is symmetric and reproducible, and composability is free through Unix pipes. A comparison of GitHub's MCP server versus its CLI tool (gh) shows the CLI approach requires fewer round trips and provides transparent error handling for tasks like finding open pull requests with failing CI.", "body_md": "The Model Context Protocol (MCP) arrived with a compelling pitch: a universal standard for connecting AI models to tools and data. Write one server, and any MCP-compatible client — Claude Desktop, Cursor, VS Code, and a growing list of others — can use it. It’s often described as “USB-C for AI applications.”\n\nI’ve built and debugged enough MCP servers now to believe the pitch is real, but incomplete. There’s a structural problem baked into the architecture that nobody warns you about, and it changes the calculus of when you should build an MCP server at all — versus doing something far less glamorous: giving the agent a plain old CLI tool.\n\nA lot of confusion about MCP comes from not being precise about where it sits. The architecture has three parts:\n\nSo your server is a translation layer: it sits between the client (and the model inside it) on one side, and your actual API or data source on the other.\n\nHere’s the uncomfortable part: **you only control the middle box.** You don’t control the client, you don’t control the model, and you don’t control how the two of them decide to use — or ignore — your server.\n\nWhen a traditional API integration fails, you own both ends. You can log the request, log the response, step through the code, and reproduce the failure deterministically.\n\nWhen an MCP integration fails, the failure can live in places you cannot see:\n\nTools like MCP Inspector help you verify that *your* box behaves correctly in isolation. But the emergent behavior — model + client + your server together — can only be tested end-to-end, one host app at a time, non-deterministically. That’s a genuinely hard operational position to be in.\n\nMeanwhile, agentic coding tools like Claude Code, Codex CLI, and others demonstrated something almost embarrassing in its simplicity: if the agent has a shell, it can use any command-line tool ever written. No protocol, no server, no schema.\n\nWhy does this work so well?\n\n**1. The model already knows the tool.** Models have read millions of lines of documentation, Stack Overflow answers, and shell scripts involving git, gh, curl, jq, psql, aws. You don't need to teach the model your interface through a 200-word description field — the training data did it for you. And for a custom tool, mytool --help is self-documenting, fetched *on demand* rather than preloaded.\n\n**2. Context cost is pay-as-you-go.** Every MCP tool definition you expose gets injected into the model’s context up front. Connect a few busy servers and you can burn tens of thousands of tokens on tool schemas before the conversation starts — degrading both cost and the model’s focus. A CLI costs roughly zero tokens until the moment the agent runs --help.\n\n**3. Debugging is symmetric.** When the agent runs a command and it fails, the exit code and stderr come straight back into the conversation — visible to the model *and* to you, in the transcript. Better yet, you can reproduce the failure yourself by copy-pasting the exact command into your own terminal. Determinism is back.\n\n**4. Composability is free.** Forty years of Unix philosophy: gh pr list --json number,title | jq '.[] | select(...)'. With MCP, every filter, sort, and join either becomes another tool you must define or another round-trip through the model's context.\n\nThis is the cleanest apples-to-apples example, because GitHub offers both a popular MCP server and a mature CLI (gh).\n\n**Task: “Find my open PRs that are failing CI and summarize why.”**\n\n*Via the GitHub MCP server:* The client loads dozens of tool definitions into context. The model calls list_pull_requests, receives a large JSON blob into context, calls a checks-related tool per PR (several more round trips, several more blobs), then reasons over all of it. If one call fails — token scope, rate limit, oversized response truncated by the client — the failure mode depends on the client, and you may just see the model quietly give partial results.\n\n*Via the CLI:*\n\n```\ngh pr list --author \"@me\" --state open \\  --json number,title,statusCheckRollup \\  | jq '[.[] | select(.statusCheckRollup[]?.conclusion == \"FAILURE\")]'\n```\n\nOne command. The filtering happened *outside* the context window, in jq, and only the failing PRs come back. If it errors, the agent reads stderr (\"HTTP 403: token missing repo scope\") and can often fix its own mistake — or you can, by running the same line.\n\nFor an agent operating in a terminal, the CLI path is faster, cheaper, more transparent, and easier to debug. This isn’t a niche opinion anymore; a growing chorus of practitioners building serious agent systems have converged on “give it bash and good CLIs” as the default.\n\nIf the comparison above were the whole story, MCP wouldn’t exist. But notice what the CLI approach quietly assumed: *a shell*. Full filesystem access. The ability to execute arbitrary commands. A user who’s comfortable when things get technical.\n\nMCP earns its complexity exactly where those assumptions break:\n\nAfter enough time on both sides, here’s the heuristic I’d offer:\n\n**If your agent runs where a shell exists and your users are developers — prefer CLI tools.** Wrap your service in a good CLI with --help, --json output, and honest exit codes. You'll get better debuggability, lower token costs, and the model's training-data familiarity for free. (Bonus: humans get a useful tool too.)\n\n**If your agent runs where a shell doesn’t exist, or shouldn’t — build the MCP server.** Consumer clients, locked-down enterprise environments, remote OAuth-gated services, non-developer users. Here MCP isn’t overhead; it’s the only bridge.\n\n**If you build the MCP server anyway, design for the control you don’t have.** Fewer tools with sharper descriptions beat many overlapping ones. Return errors written for a *model* to read and act on, not a human. Keep responses small — filter server-side. Test in every client you claim to support, because the spec is a floor, not a guarantee.\n\nThe ambiguity you feel when working with MCP isn’t your imagination, and it isn’t a bug that a future spec version will fully fix. It’s the inherent cost of putting a probabilistic model and a third-party client between your code and its caller. Sometimes that cost buys you reach, safety, and users you couldn’t otherwise serve — pay it gladly. And sometimes the honest answer is that the best “protocol” for an AI agent was sitting in /usr/bin all along.\n\n*Thanks for reading. If you’ve hit MCP debugging stories worse than mine, I’d love to hear them in the responses.*\n\n[The Layer You Don’t Control: Rethinking MCP Servers vs. Plain CLI Tools](https://pub.towardsai.net/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools-f268fe0c2790) was originally published in [Towards AI](https://pub.towardsai.net) on Medium, where people are continuing the conversation by highlighting and responding to this story.", "url": "https://wpnews.pro/news/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools", "canonical_source": "https://pub.towardsai.net/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools-f268fe0c2790?source=rss----98111c9905da---4", "published_at": "2026-07-21 12:01:01+00:00", "updated_at": "2026-07-21 12:29:15.683928+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-tools", "ai-agents", "developer-tools"], "entities": ["Model Context Protocol", "Claude Desktop", "Cursor", "VS Code", "Claude Code", "Codex CLI", "GitHub", "MCP Inspector"], "alternates": {"html": "https://wpnews.pro/news/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools", "markdown": "https://wpnews.pro/news/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools.md", "text": "https://wpnews.pro/news/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools.txt", "jsonld": "https://wpnews.pro/news/the-layer-you-dont-control-rethinking-mcp-servers-vs-plain-cli-tools.jsonld"}}