--- title: "The protocol and the plumbing" description: "Layering: protocol vs. infrastructure for tool-using agents." doc_version: "1.1" last_updated: "2026-05-01" canonical: "https://modiqo.ai/blog/the-protocol-and-the-plumbing.txt" --- # The Protocol and the Plumbing *On ten years of financial messaging, the Model Context Protocol, the CLI-vs-MCP knife fight, and why Rote speaks MCP without the middle layers.* --- ## What a protocol actually is, when the money moves Before any of this — before LLMs, before agents, before the word *context* became a technical term — I spent a long time building and extending financial protocols. SWIFT. ACH. OFAC screening. FIX on the capital-markets side. The cybersecurity layer that sits underneath and around all of them. When you work on financial messaging long enough, you develop a specific kind of respect for the distinction between a *protocol* and an *implementation*. The distinction is not philosophical. It is enforced by reality. A SWIFT MT103 wire message is an MT103 whether it is sent by a mainframe in Frankfurt, a Java-based core banking system in Mumbai, or a Python script riding on an API gateway in Manhattan. The message has a schema. The schema has field tags. The field tags have meanings that were negotiated over years by working groups and then frozen. If you deviate from the schema, your message does not land. Nobody cares how you built your pipes. They care that the MT103 you sent conforms. That is what a protocol is. It is a *contract about wire format*, plus a set of semantic guarantees about what fields mean. It is not a piece of software. It is not an SDK. It is not a gateway product. The protocol is the thing that survives the decade-long migration from SWIFT MT to ISO 20022 MX, because the protocol is the *specification* — the part you can take with you when your vendor goes out of business or your bank gets acquired or your country changes its central clearing infrastructure. Implementations change. Pipes change. The protocol, if it is well-designed, does not. I have watched this play out for ten years across three distinct bodies of specification. SWIFT, over five decades, accumulating revisions — MT, then MX, then CBPR+, now the long coexistence period ending November 2025 and the full ISO 20022 migration running through 2027. ACH, governed by NACHA, quietly clearing trillions of dollars a year on a message format that would be recognizable to an engineer from 1980. OFAC sanctions screening — less a wire protocol than a compliance regime, but with its own specification language about lists, typos, fuzzy matches, and the difference between "block" and "reject." Each of these specifications has its own working group, its own change-management rituals, its own deprecation timelines measured in years, not months. What these systems have in common is that you cannot *sway* them. A single bank, even a very large bank, cannot unilaterally decide to add a field to an MT103 and expect the network to accept it. The protocol is a shared commons. To change it, you have to go through the working group, convince the other participants, wait for a release cycle, and then survive the coexistence period where both the old format and the new format have to round-trip cleanly. This is slow. It is also, I have come to believe, the *correct speed* for something that the global financial system depends on. I mention all of this because it is the backdrop against which I first read the Model Context Protocol specification. --- ## Reading the MCP spec for the first time Anthropic released MCP on November 25, 2024. David Soria Parra and Justin Spahr-Summers had co-authored it, inspired — as they freely admitted — by the Language Server Protocol that Microsoft had shipped for VS Code in 2016. The pitch was simple and, to anyone who has worked on standards, immediately compelling. There was an *M × N problem* in the agent ecosystem: every AI model needed its own custom connector to every external system, which meant an exponential explosion of integrations. A protocol would collapse this to M + N. I read the spec carefully in December 2024. I will tell you what I noticed, because I think most of the criticism that emerged later missed the part that was actually good. The spec was *carefully thought through*. Whoever had worked on it had internalized the hard lessons of LSP — that a good protocol is small, that it draws a sharp line between the client and the server, that it uses a boring transport like JSON-RPC so that implementers can focus on semantics rather than plumbing. The resource/tool/prompt trichotomy was elegant. The lifecycle model — initialize, list capabilities, invoke, teardown — was obviously derived from decades of experience with interactive protocols. The authentication story was deferred to later versions, which is exactly what you do with a new protocol if you want it to ship: you get the core right first and let the auth question get settled by working groups and implementers under real load. More than anything, it was *readable*. A working engineer could sit down with the spec and understand, in about an hour, what MCP was and was not trying to do. That is rarer in protocol design than people realize. I have seen specifications three times the length of the original MCP document that communicate one-third as much. So my first reaction, as someone who had spent ten years on financial protocols, was approval. This was a real protocol, not a product. It had the shape of something that could become a commons. I had one concern, and it was the concern I want to dwell on. --- ## The one critique: conflation The concern was this: the spec and the reference implementation were entangled. In good protocol design, the specification should be *completely silent* on how the protocol is implemented. A SWIFT MT103 specification does not tell you to use a particular vendor's middleware. An ISO 20022 XML schema does not tell you how to run a gateway. A FIX message specification does not tell you what programming language to use. The protocol is the protocol. How you choose to implement it is your problem. MCP, in its early form, blurred this line. The reference server implementations shipped alongside the spec. The SDKs shipped alongside the spec. The assumption — legible to anyone reading the documentation — was that you would run an MCP server process, connect to it over stdio or SSE, and treat that server as the thing that "speaks MCP." Nothing in the protocol strictly required this. But everything in the ecosystem around the protocol *suggested* it. This is a small thing. But small things in protocol design compound. When the reference implementation becomes the de facto implementation, the implementation's constraints become the protocol's constraints. Developers stop asking *what does MCP require?* and start asking *what does my MCP server support?* These are not the same question. And the gap between them is where industry confusion gets born. I flagged this, quietly, in my notes at the time. I did not have a clean solution. I thought it would probably get worked out as the ecosystem matured. It did not get worked out. It got worse, because what happened next was the gold rush. --- ## The gold rush Within ninety days of the November 2024 launch, MCP was everywhere. OpenAI announced support across the Agents SDK and ChatGPT desktop in March 2025. Google DeepMind followed in April with Gemini. Microsoft, Cloudflare, AWS — all of them integrated. By mid-2025 there were hundreds of MCP servers in the wild and the protocol had crossed from experimental into the de facto standard for agent tool access. And then the infrastructure companies arrived. I do not have a clean total for how much venture capital has been deployed into MCP-adjacent infrastructure over the last eighteen months — nobody publishes that number, and the startups are funded in rolling rounds that are hard to aggregate. But the direction is unmistakable. Hundreds of millions of dollars, at minimum, have flowed into MCP gateways, MCP security appliances, MCP observability platforms, MCP authentication and authorization systems, MCP registries, MCP federation services. Runlayer launched out of stealth in November 2025 with $11 million from Khosla and Felicis, having signed up eight unicorns as customers in four months; they named David Soria Parra himself as an angel and advisor. MintMCP took money from Karpathy, Dean, and Coatue. IBM shipped ContextForge. Docker shipped an MCP Gateway. Cloudflare shipped MCP-compatible authentication flows. Every major observability vendor announced MCP traffic inspection. The list is long and it is getting longer every week. What every one of these companies had in common was an answer to the same implied question: *how do you run MCP in production?* And the answer, almost uniformly, was: *you install our middleware.* This is where the conflation I had worried about compounded. Because now the protocol had become inseparable, in practice, from an infrastructure story. To adopt MCP, you were not just adopting a wire format and a semantic contract. You were adopting a piece of software that sat between your agent and your existing APIs, consuming compute, generating audit logs, demanding its own auth, requiring its own operational discipline. The MCP server was an artifact. The artifact was a product. The product had vendors. The vendors had revenue models. And the revenue models now depended on MCP continuing to look like something that *needed* middleware to work. I have seen this movie before. In the mid-2000s, an entire industry of SOA governance products existed to solve problems that SOAP, as a protocol, had created by being over-specified. In the 2010s, API gateways became a billion-dollar category by inserting themselves between clients and REST APIs that, in most cases, did not need a gateway to function. Middleware has a way of proving, indefinitely, that it is necessary — in part because the organizations that install it structure themselves around its continuing presence. --- ## The context-window complaint And then, a few months later, came the backlash. It was quantitative, and it was painful. Engineers started publishing benchmarks showing what the middleware was costing them in tokens. Scalekit ran 75 head-to-head comparisons using the same model on the same tasks and found MCP costing 4 to 32 times more tokens than a plain CLI equivalent. GitHub's MCP server was exposing 43 tools, and every single one of those tool schemas was being injected into every agent conversation before the agent had read a single user message. Apideck published a writeup documenting that a three-server connection — GitHub, Slack, Sentry — would burn 55,000 tokens in schema definitions before any useful work began, over a quarter of Claude's 200k context window, gone. A blog post with the title *"Your MCP Server Is Eating Your Context Window"* went viral. Peter Steinberger, a prolific open-source developer who had since joined OpenAI, posted a one-liner that rippled through the engineering community: *MCPs were a mistake. Bash is better.* The CLI camp emerged. The pitch was practical. Every agent framework — Claude Code, Cursor, Gemini CLI, Goose — already had a shell execution primitive. Every API in the world had a CLI wrapper, or could have one in an afternoon. The agent's training data was saturated with terminal interactions, which meant the model already knew how to use `gh` and `kubectl` and `psql` fluently. A CLI's `--help` flag gave you progressive disclosure for free. You paid context tokens only for the tools you actually invoked, not for the entire catalog the server happened to expose. And the CLI approach was framework-agnostic: the same binary worked from any agent that could run a shell command. The knives were out. MCP was schema bloat; CLI was training-data-native. MCP was over-engineered; CLI was "just bash." Companies that had shipped MCP servers started shipping *CLI versions alongside them* — not because the CLI was fundamentally better, but because they needed to stay relevant in both agent-harness narratives. Anthropic itself introduced the Skills framework and explicitly contrasted its lightweight, on-demand-loading properties with the "sometimes tens of thousands of tokens" that MCP connections could consume. What I saw, watching this unfold in real time, was an argument that had nothing to do with the protocol and everything to do with the plumbing. --- ## Why this felt wrong to me Here is where my financial-protocols background became a frame I could not shake. In the world I had spent ten years in, arguments like this did not happen. Or rather, they happened — but they happened *inside the standards body*, over years, between working group participants who had committed their institutions to the outcome. A SWIFT bank could not wake up one morning and decide that MT103 was "a mistake" and that plain TCP was "better" and expect the network to accommodate it. The infrastructure operators — the clearers, the central banks, the correspondent networks — set the pace. A single implementation vendor could not sway the specification. The protocol had the dignity of being *hard to change*, which meant it could be *relied on*. The MCP-versus-CLI debate was, by contrast, a blog-post war. Individual engineers, reasoning from their own harnesses, with strong opinions and real benchmarks, were relitigating the question of what the protocol was for. The ecosystem was younger than the protocol itself had been alive. And the companies that had just raised on the assumption that MCP was the future were now publicly scrambling to build CLI-shaped products on the side. There was something correct inside the critique. The context bloat was real. A 43-tool schema injection is not a reasonable default. And the CLI advocates were right that much of the apparent value of MCP, in practice, was value that could be delivered by a different mechanism with less overhead. But I also thought the critique was throwing out something important. The protocol itself — the wire format, the semantic model of resources and tools, the lifecycle contract — was genuinely useful. It gave the agent a *type system* for interacting with the world. What the critics were really complaining about was not the protocol. It was the *implementation pattern* the industry had collectively decided the protocol required: a separate server process, pre-announcing its entire catalog, sitting behind a middleware layer, paying for itself with every token. You could have that protocol *without* that pattern. The question was whether anyone was willing to build it that way. --- ## The resistance I resisted picking a side for months. This was not strategic. It was temperamental. I had been through enough protocol wars in the financial world to know that the instinct to declare a winner is almost always premature, and the instinct to build a *parallel universe* ("here is our better thing") is almost always a vendor instinct rather than a builder instinct. What I kept coming back to, sitting with the problem, was a reformulation that seemed to me to be where the argument actually lived but was not being articulated: *Can we have the semantic benefits of MCP without the implementation cost?* Specifically: can an agent speak MCP to any external system — using the wire format, the resource/tool model, the lifecycle contract — *without that system having to install an MCP server?* Can the protocol be something the agent uses to *interpret* an API, rather than something that has to be served by a separate process alongside the API? The API spec of almost every modern API already describes, in structured form, exactly what an MCP tool definition would describe: the endpoint, the parameters, the types, the response schema. The agent does not need a server to translate this. It needs an interpreter — something that reads the spec and speaks MCP on the agent's side, against the real API, straight off the wire. Stated this way, the answer was almost embarrassingly obvious. The protocol was the protocol. The middleware was optional. The industry had, for reasons I have already described, confused the two. --- ## The proxy objection, honestly addressed Someone will read what I just wrote and say: *but that is still a proxy. You have just moved the middleware into the agent's harness.* That is correct. It is a proxy. But I want to be careful about what the word *proxy* is doing in this sentence, because I think the language is what has been obscuring the argument. In the limit, every layer of any software system is a proxy for something else. The kernel is a proxy between your process and the hardware. The TCP stack is a proxy between your application and the wire. An ORM is a proxy between your code and the database. The question is never *is this a proxy?* The question is *what are the costs of this proxy, and who pays them?* The costs of an MCP middleware proxy, in the form it has taken over the last year, are these. It is a separate process that has to be installed, configured, and maintained. It is an additional endpoint that has to be authenticated against. It is a new attack surface that has to be secured. It is a metered service — increasingly, a paid service — that charges per tool invocation or per connection or per audit event. It is a dependency that the organization running it now has to defend, because the revenue model behind it depends on its continued relevance. Every one of these costs is real. Every one of them gets paid by someone — the developer, the operator, the end user, the token budget. A proxy that lives *inside the agent harness*, by contrast — that reads API specs and speaks MCP against live APIs — pays none of those costs. It does not need to be installed separately. It does not have its own auth. It does not run as a network-exposed service. It is not a thing you pay for per invocation; it is a library function in the process the agent is already running. It is, in the phrase I have been using internally, *invisible, free to invoke, no tool-call tool*. There is no gateway. There is no server. There is nothing to audit, because the audit happens at the same layer the agent is already audited at. It is still a proxy. But it is the kind of proxy that the kernel is — a piece of the substrate that does not announce itself, does not charge rent, and does not have to be justified as its own product. That is the distinction that matters. Not *proxy or no proxy*, but *does the proxy pay for itself with every invocation, or does it disappear into the fabric?* --- ## What Rote was at genesis This is what Rote has been from the beginning. When I first started sketching out the architecture, I was not thinking about taking a side in the MCP debate. The debate had not really crystallized yet. I was thinking about the deeper problem — about agents burning tokens, about crystallizing successful exploration into reusable structure, about giving agents a workspace where practice could accumulate. But when I looked at what the agent needed in order to probe any external system, I kept coming back to the same architectural requirement: the agent should be able to *speak MCP to any API without the API having to do anything special to accommodate it*. That is what the adapter primitive in Rote actually is. It reads the API spec of the target system. It exposes, to the agent, exactly the resource and tool semantics MCP defines. It handles the lifecycle, the introspection, the invocation. The agent's side of the conversation looks, to the agent, exactly like a protocol — because the protocol is the protocol, and the protocol is what the agent was trained to speak. The API's side of the conversation looks like a normal HTTP call against the real endpoint, because that is what the API was always going to be. The adapter is the bridge, and the bridge is a library, not a product. No MCP server process. No gateway to configure. No auth appliance to install. No per-invocation billing layer. No separate attack surface. No catalog of 43 tools pre-announced into the context window before the agent has read the user's first message. The adapter announces exactly what is needed when it is needed. Tool probe happens against the adapter spec, which is a reformatted and index definition of the API owner was already publishing anyway. The context budget spent on schema is spent on the tools actually being invoked — not on the tools that happen to exist in the same server. This is what I mean by *speaking MCP without the middle layers*. The protocol wins. The plumbing disappears. --- ## What the financial protocols taught me, finally There is a reason I opened this essay with SWIFT, ACH, and OFAC, and I want to close on it explicitly. What those systems taught me, over ten years, is that a good protocol outlives every implementation that was built to serve it. The MT103 message format has survived IBM mainframes, mid-century core banking systems, three generations of middleware vendors, the rise and fall of SOAP, the rise and eventual acceptance of ISO 20022. None of the implementations that were "necessary" in 1998 are necessary in 2026. The protocol is still there. The plumbing got replaced. The way you honor a good protocol is not by building products that depend on its implementation details. It is by building systems that speak the protocol *natively* and let the plumbing fall away. A bank that has been around for a hundred years knows this instinctively. It does not marry itself to any particular middleware vendor, because it has watched every middleware vendor of the last four decades either get acquired, get deprecated, or become irrelevant. What the bank commits to is the specification. The implementation is always, always replaceable. Rote is built on the same conviction, applied to agentic protocol. The protocol Anthropic shipped in November 2024 is a good protocol. The infrastructure industry that grew up around it in the following year is, in my view, mostly optional. The CLI advocates are correct about the costs of the middleware but incorrect about the value of the protocol. What the agent ecosystem actually needs is a way to speak MCP without paying the middleware tax — a way to let the specification be what it was always meant to be, and let the plumbing fade into the substrate where plumbing belongs. I did not pick a side in the MCP-versus-CLI war. I picked a different side, which was the side of the protocol itself, uncoupled from the implementation pattern that had hitched a ride on it. If that reads as contrarian, I will tell you honestly that it does not feel contrarian from where I am sitting. It feels like the same thing I have been doing for ten years. Respect the specification. Refuse to confuse it with the plumbing. Build for what will still be true in a decade. The protocol outlives the plumbing. It always has. --- *References: the MCP specification at modelcontextprotocol.io; the* Software Engineering Daily *interview with David Soria Parra, May 2025; the Scalekit benchmark "MCP vs CLI," March 2026; the Apideck writeup "Your MCP Server Is Eating Your Context Window," April 2026; SWIFT's public documentation on the ISO 20022 migration at swift.com/standards; NACHA's resources on ACH formats and ISO 20022 adoption. On the broader standards question, I have found Marc Levinson's* The Box *useful as a working-engineer's history of how a specification — in that case, the intermodal shipping container — survives by being small, boring, and uncoupled from any particular implementation.*