You read the specification end to end before writing anything. Message shapes, transports, error codes, how a client asks a server what it offers: none of it ambiguous. So you wrote a small file server, pointed an agent at it, and the calls landed on the first try. Later you opened the official reference implementation of roughly the same thing, expecting to find nothing new. The protocol part was identical. Everything that mattered sat in the parts the specification never mentions — where the path check goes, what a refusal is allowed to say, how the tool descriptions are worded.

The written definition cannot be weighed

A reference server is not a product. It is a maintained example: a deliberately small surface of prompts, resources and tools, built with an official SDK and kept correct so that people can read it. Its job is to teach.

For most of a century, a kilogram was a metal cylinder in a vault outside Paris. The definition was one sentence long, and on its own that sentence was useless. Everything that made the cylinder mean anything lived in the handling: which gloves, which washing procedure, what air it sat in, how often the copies held by national laboratories were carried back and compared against it. Those laboratories never put the artefact on a shop counter. They used it to calibrate their own working weights, under their own conditions, and the scale in the market downstream was theirs to answer for.

A reference implementation is that artefact, and the specification is the sentence. You read the server not because you cannot write the calls yourself, but because the handling is recorded there in a form a document cannot hold: the order of the checks, what the error returns, how small the surface was kept and what was deliberately left out.

The specification never writes down the boundary

Ask what the protocol actually guarantees and the answer is narrow. It says a tool has a name, a description and a typed input, and it says how the call travels. It does not say where the tool runs. It does not say who wrote the description.

Both gaps are where the damage is. A tool with real effects — a browser, a filesystem — running without a sandbox can do something irreversible on the first bad argument, which is why isolation is treated as a requirement rather than a nicety by anyone who has watched it happen. One research harness spins a fresh isolated container for every run and exposes more than fifty MCP tools inside it. That project also hints at the second gap: every public function in its tools directory is auto-registered as a tool, so the surface a model sees is decided by a file layout rather than by a review.

The second gap is the description itself. A server can return text — either its output or the tool description a model reads before choosing — that carries instructions aimed at the model rather than at you. There is now a benchmark for this, run against real MCP servers, because it stopped being hypothetical. It is the familiar problem in a new place: the model reads one stream and cannot see which part of it was only ever meant to be data.

You copy the shape, not the trust

So a reference server teaches, and then it stops. What it hands you is a shape: where a boundary check belongs, what an audit line looks like, how narrow a tool description can be and still be usable, which capabilities were never exposed at all. What it cannot hand you is a threat model, because it does not know yours. The common failure is quiet — someone deploys the reference server exactly as it came, in front of real data, having never written down who is allowed to call it or what gets recorded when they do. Nothing breaks. That is the problem.

The healthy version is dull. A team starts from the reference filesystem server, replaces its access boundaries with their own, adds the audit they will be asked for, and only then lets an agent near it. The example was the fastest way to learn what the questions were. It was never the answer to them. A specification can tell you a call is well formed. Only an implementation can show you the one it should have refused.