Trust is earned, not given

A different perspective

2024-12-05 · Projects

AI Frontiers, part 12: Model Context Protocol — plumbing for the agent era

Part 12from the AI Frontiers series · 65 parts in all

On 25 November 2024 Anthropic published the Model Context Protocol, an open specification for connecting AI assistants to the systems where the data and the actions actually live. It shipped with Python and TypeScript SDKs, a set of reference servers for things like Google Drive, Slack, GitHub, Postgres, and browser automation, and a short list of early adopters — Block, Apollo, Zed, Replit, Codeium, Sourcegraph — who had implemented the client side before the announcement (Anthropic, "Introducing the Model Context Protocol").

Nobody outside the industry noticed, which is exactly what a good infrastructure announcement should look like. The previous eighteen months of AI product development had produced a genuinely absurd situation: every assistant that wanted to read your files, query your database, or file a ticket had to write a bespoke integration for every combination of host application and backend service. The protocol is an attempt to make that an M-plus-N problem instead of an M-times-N one. The interesting parts are why it took until late 2024, what the spec actually pins down, and why I think its security model — not its capability model — will decide whether it works.

The integration tax nobody wanted to pay

Tool use became a mainstream capability in 2023. OpenAI's function calling update in June 2023 let a model emit a structured request for a named function with typed arguments, and the calling application would execute it and hand back the result (OpenAI, "Function calling and other API updates"). Before that, the research picture was already clear: Toolformer (Schick et al.) showed a model could learn when to call an API; ReAct (Yao et al.) interleaved reasoning with actions; Gorilla (Patil et al.) demonstrated retrieval over a large corpus of real API documentation; HuggingGPT (Shen et al.) chained models together as tools. Qin et al. had already written the survey.

What none of that solved was distribution. Each model provider defined its own schema for how a tool is described. Each host application implemented its own loop for executing tool calls, with its own conventions for errors, timeouts and confirmation prompts. Each service integration — your Jira, your Salesforce, your internal API — was reimplemented in every host that needed it, in whatever language that host happened to be written in. Frameworks like LangChain and LlamaIndex absorbed a lot of this pain by publishing integration after integration, but a framework is a library you import, not a boundary between processes. If you wanted your tool to work in your editor, your terminal, and your chat assistant, you wrote it three times.

What the spec actually specifies

The protocol itself is deliberately small. It runs over JSON-RPC 2.0 and defines two transports: standard input/output for local servers launched as child processes, and HTTP with server-sent events for remote ones. It defines three roles — host, client, server — where the host is the assistant application, a client is the connector inside the host managing one server connection, and the server exposes capabilities. It defines a version negotiation handshake, with the first specification revision identified as 2024-11-05 (Model Context Protocol, "Specification").

The server-side surface comes in three primitives with intentionally different control models. Tools are model-controlled: the model decides when to call them, the host decides whether to allow it. Resources are application-controlled: the client reads files or records and decides what to put in context. Prompts are user-controlled: templates a person explicitly invokes. That tripartite split is the design decision I find most interesting, because it is a consent model expressed as an API design. The distinction between "the model asked for this" and "the user asked for this" is the distinction that matters for everything downstream.

Anthropic states the inspiration outright: MCP is modeled on the Language Server Protocol, which Microsoft introduced in 2016 so that editors would not each reimplement language support for each language (Microsoft, "Language Server Protocol"). LSP is one of the most successful protocol designs in developer tooling, and its lesson is that you should be able to write a server in any language and run it in any editor. MCP lifts that shape wholesale and points it at data and tools instead of type systems.

Why JSON-RPC and stdio are the right kind of boring

A reasonable person in December 2024 might ask why the industry needed a new protocol at all when HTTP and OpenAPI already exist, and ChatGPT plugins had tried the remote-API approach back in March 2023. The answer is that MCP is designed for two deployment shapes that REST handles awkwardly.

The local case is the important one. A server running as a child process over stdio has no port, no TLS certificate, no authentication ceremony and no network exposure. You can run it under your own user account against your own files, and the only thing that can talk to it is the parent process that spawned it. For the overwhelmingly common case — "let the assistant read this repository" — that is dramatically better than standing up an HTTP service, and it explains the rapid adoption among coding tools specifically. Debuggability follows for free: a JSON-RPC conversation over stdio is a stream of newline-delimited messages you can log, replay, and inspect, which is worth an enormous amount when you are trying to work out why a model refused to call a tool.

The remote case is where the interesting engineering ends up. HTTP with server-sent events is a fine choice for streaming responses over a long-lived connection, and it is trivially proxyable through the same reverse proxies everyone already runs. But remote servers introduce identity, authorization, multi-tenancy and revocation — problems that the 2024-11 specification acknowledges far more than it solves. That is not a criticism so much as an observation about how standards mature: the first revision fixes the shape, later revisions fix the security.

The developer experience matters more than it sounds. Writing a minimal server is a decorator on a function and a loop that speaks JSON-RPC on stdin; the SDKs handle the handshake, capability declaration and argument validation, and the reference server for the filesystem is a few hundred lines. That is a low enough barrier that the ecosystem filled with servers within weeks, including a great many that wrap an existing REST API in thirty lines. It also means the quality distribution is wide, which is the next problem.

The security model is the whole problem

Here is the part I want on the record. An MCP server is a program that an assistant can ask to run things, and the assistant's decisions about what to ask for are driven by a language model reading text — text that frequently comes from outside your control. That combination is the setup for indirect prompt injection (Greshake et al.), where content the model reads contains instructions. A poisoned document, a malicious issue title, a compromised web page: any of them can, in principle, cause a model to call a tool that performs a side effect.

There is a supply-chain version of the same problem. Installing an MCP server is installing a program — a package from a registry, launched as a child process with your credentials and your access. That is precisely the trust model of an editor plugin, and the history of editor plugins suggests a reasonably accurate prediction of what comes next: popular servers get compromised, typosquatted names get published, and the ecosystem learns to pin versions and review what a server actually declares before granting it write access. The protocol's capability negotiation helps here, because it gives a client something concrete to display and a user something concrete to withhold, but it shifts the burden to whoever runs the host. Standards distribute responsibility; they do not remove it.

The protocol does not pretend to fix this, and it cannot. What it can do is put the boundary in the right place: the host owns the confirmation UI, the server owns the capability, and the client mediates between them. That means the question "should this tool call be allowed?" is answerable by the application rather than the integration, which is where the authority belongs. It also means the answer has to be actually implemented — allowlists, read-versus-write distinctions, per-server scoping, and human confirmation for irreversible actions. None of that is free, and the temptation to ship with confirmation prompts disabled is exactly the temptation that produces the incident report.

More tools is not more capability

There is a failure mode that a standard makes worse before it makes better. Tool selection degrades as the number of available tools grows. A model choosing among five well-described tools is reliable; a model choosing among forty, with overlapping names and inconsistent argument shapes, is not — and it does not fail loudly. It picks a tool that is close enough, fills in plausible arguments, and produces a result that looks superficially right. Anyone who watched a chat assistant juggling a dozen plugins in 2023 has seen this exactly. Kapoor et al. made the broader version of the point in their cost-aware critique of agent benchmarks: evaluation that ignores the monetary and latency cost of each additional tool call optimizes for a world nobody deploys in.

The practical consequence is that a protocol which makes it trivial to expose a hundred capabilities also makes it trivial to degrade a model's judgment. Two design disciplines follow from it, and I expect both to become conventional. First, expose few, well-named tools rather than one endpoint per internal function — a server for a ticketing system should offer "search tickets" and "update ticket", not the twelve REST endpoints underneath them. Second, retrieve tools the way you retrieve documents: keep the catalog large and the prompt small, selecting the handful of relevant tools for each request rather than pasting the whole manifest into the context window. Gorilla (Patil et al.) was the first clear demonstration that retrieval over API documentation beats memorization, and the same logic applies to a live registry of servers.

Locality is the other lever. A local server can expose something a remote server would never be allowed to — your filesystem, your git history, a development database — precisely because it cannot be reached except by the process that launched it. That asymmetry is why the earliest and most convincing MCP deployments were in developer tools, where the capability is already present on the machine and the assistant is merely the newest client of it.

Servers are the new drivers

The analogy I keep coming back to is device drivers. Before a driver model exists, every application talks to hardware directly, and the code is a mess of duplicated, subtly different implementations. A driver model does not make hardware simpler; it defines a narrow contract so that complexity has exactly one home. MCP does the same for capabilities. Rate limiting, caching, credential handling, pagination, retries and audit logging all move into the server, where they belong, instead of being smeared across every host that wanted to use the same system.

It is also, bluntly, how you ship a product transition. Anthropic's computer-use beta in October 2024 had demonstrated a model driving a graphical desktop directly (Anthropic, "Developing a computer use model"). That approach is powerful and horrible: pixel-level control means every action is expensive, fragile, and hard to audit. A structured tool call is cheaper and infinitely more observable. The strategic argument for MCP is that you want as much of the world as possible exposed through typed, permissioned interfaces, and GUI control left as the fallback for the long tail of systems that will never ship an API — which is precisely the argument of part 5 applied to actions instead of knowledge. Retrieval gave models access to documents. MCP gives them access to verbs.

Standards succeed by being unexciting. The reason I think this one will stick is not the elegance of the design — it is that everyone who had written the same three integrations three times looked at the specification and recognized their own pain. The remaining question is whether a single vendor's standard gets adopted by its competitors, and the honest answer in December 2024 is that nobody knows yet. What is already true is that the scaffolding around agents got a lot less bespoke this year, and that the ecosystem that forms around a protocol is usually worth more than the protocol itself.

Works Cited

Anthropic. "Developing a Computer Use Model." Anthropic, 22 Oct. 2024, www.anthropic.com/news/developing-computer-use. Accessed 5 Dec. 2024.

---. "Introducing the Model Context Protocol." Anthropic, 25 Nov. 2024, www.anthropic.com/news/model-context-protocol. Accessed 5 Dec. 2024.

Greshake, Kai, et al. "Not What You've Signed Up For: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection." arXiv, 2023, arxiv.org/abs/2302.12173. Accessed 5 Dec. 2024.

Kapoor, Sayash, et al. "AI Agents That Matter." arXiv, 2024, arxiv.org/abs/2407.01502. Accessed 5 Dec. 2024.

Microsoft. "Language Server Protocol." Microsoft, microsoft.github.io/language-server-protocol/. Accessed 5 Dec. 2024.

Model Context Protocol. "Specification." Model Context Protocol, modelcontextprotocol.io/specification/2024-11-05. Accessed 5 Dec. 2024.

OpenAI. "ChatGPT Plugins." OpenAI, 23 Mar. 2023, openai.com/index/chatgpt-plugins/. Accessed 5 Dec. 2024.

---. "Function Calling and Other API Updates." OpenAI, 13 June 2023, openai.com/index/function-calling-and-other-api-updates/. Accessed 5 Dec. 2024.

Park, Joon Sung, et al. "Generative Agents: Interactive Simulacra of Human Behavior." arXiv, 2023, arxiv.org/abs/2304.03442. Accessed 5 Dec. 2024.

Patil, Shishir G., et al. "Gorilla: Large Language Model Connected with Massive APIs." arXiv, 2023, arxiv.org/abs/2305.15334. Accessed 5 Dec. 2024.

Qin, Yujia, et al. "Tool Learning with Foundation Models." arXiv, 2023, arxiv.org/abs/2304.08354. Accessed 5 Dec. 2024.

Schick, Timo, et al. "Toolformer: Language Models Can Teach Themselves to Use Tools." arXiv, 2023, arxiv.org/abs/2302.04761. Accessed 5 Dec. 2024.

Shen, Yongliang, et al. "HuggingGPT: Solving AI Tasks with ChatGPT and Its Friends in Hugging Face." arXiv, 2023, arxiv.org/abs/2303.17580. Accessed 5 Dec. 2024.

Yao, Shunyu, et al. "ReAct: Synergizing Reasoning and Acting in Language Models." arXiv, 2022, arxiv.org/abs/2210.03629. Accessed 5 Dec. 2024.