Let me be honest: MCP is slow. Not a little, not sometimes, but by construction. I am not saying this from a distance. We connected 33 tools to NeoCoder via MCP, and I have been sitting in front of it for months. What I noticed is by now also written down by the people who invented the protocol. In July they rebuilt it, so thoroughly that old and new implementations no longer fit together. That is not an accusation. That is the most honest form of "we designed it differently from how it ended up being needed". My opinion, with evidence.
What MCP is, in three sentences
The Model Context Protocol, published by Anthropic at the end of 2024, is a standard for how a model finds and calls tools: read files, query a database, create a ticket. A server describes its tools, the client loads the descriptions into the model, the model calls, JSON out, JSON back. The idea is good: connect once, usable everywhere. The SDK is now downloaded almost a hundred million times a month, there are over ten thousand servers. The standard has won. And that is exactly why it is worth looking at where it does not work.
33 tools, and what happens then
In NeoCoder, 33 tools hang on the model: read repos, create tickets, start tests, check deployments, fetch logs, search documents, and so on. Each has a description with parameters, types, return values. All 33 descriptions go into the context with every request. Before the model reads the question, it has already read a small manual. By my calculation that is ten to twenty thousand tokens, every time, for tools of which it needs two at that moment.
Then the calls. A sprint review via MCP looks like this: the model reads, calls "fetch tickets", waits. Answer comes, the model reads the answer, calls "fetch commits", waits. Answer, read, "fetch tests", wait. Ten tools are ten round trips, and each round trip goes through the model once, with the whole context. What a script does in two seconds takes a minute this way and costs ten times as much.
Problem one: the context is full before the question arrives
This is the problem Anthropic itself has described most clearly. In November 2025 their engineers published an article in which they do the maths: if all tool descriptions are loaded into the context upfront, an agent with many tools needs hundreds of thousands of tokens before it has even read the request. Their example: 150,000 tokens for the tools, 2,000 tokens if the model only reads what it needs. That is 98.7 percent less.
And the second thing, easy to overlook: every intermediate result passes through the model. Their example is a meeting transcript fetched from a document and written into a CRM. The whole text goes into the model once and out again once, 50,000 tokens for nothing, and with large documents the context window breaks. Here it is the same effect with logs: two thousand lines of log go into the model so it can find the three lines that matter.
Problem two: every call is a round trip
MCP knows no flow, only calls. "Fetch the tickets, filter the open ones, fetch the commits for each, check whether tests are green" is a loop for a script. For MCP it is thirty individual calls, each with a round trip through the model, and the model has to remember where it was with every round. That is not just slow. It is the point where models make mistakes, because they copy data from round to round instead of processing it once.
And it costs time in a way you do not see in the tokens: time to first token per round. When the model has to evaluate a condition, whether this ticket is relevant, you wait for a model response for something a line of code decides in a microsecond. Anthropic writes it that way themselves: executing a condition in code is faster than waiting for a model to evaluate an if.
Problem three: built for the laptop
This is the part that became public in July. The original MCP was stateful: one session per connection, the server has to remember who is there, what they can do, where they are. On the laptop that is harmless. On a server behind a load balancer it is poison: which server holds the session? What happens when it restarts? How do you route a request whose actual operation is buried deep in a JSON body that no network device reads?
Here it led to us building a state layer next to it. The standard was then only the transport, and the point of a standard is gone when everyone lays their own layer over it. A study from Polytechnique Montréal, which published the first large fault taxonomy for MCP servers in March 2026, confirms this from the broad view: five fault classes, among them performance and stability, with hangs, slow operations and timeouts under load. Those are not beginner mistakes. Those are the faults a protocol produces that was meant for a different environment.
What the July revision changes
On 28 July 2026 the maintainers finalised the biggest revision since launch. Protocol-level sessions are gone; every request carries its own metadata, like the rest of the internet. Routing information now also sits in HTTP headers so that network devices can read it without opening the JSON body. Rarely used features were removed, sampling, roots, the protocol's own logging. An Anthropic engineer summed it up in the livestream: a lot of what made MCP is gone. And whoever built their own MCP has a lot of work ahead, because old and new are not compatible.
I think that is right. And I find it remarkable that it took so long, because stateless has been the standard for twenty years for everything that has to scale. But it also shows: the MCP most people use today is the old one. The migration is still to come.
What I do differently in the implementation
I do not change the protocol itself, the maintainers do that. But how you use it, you decide yourself. This is how I would build it, and this is how we are rebuilding it right now.
Load tools only when they are needed. Not 33 descriptions in the context, but a search: the model asks "what is there for tickets", gets three names, loads the description of one. Anthropic calls that progressive disclosure. Claude Code now has it built in, with over 85 percent less context. Here that becomes a small model that picks the two to four fitting tools from the request before the big model even reads. That is the rebuild in progress right now.
The model writes a script that makes the calls. Instead of thirty round trips, one: the model writes ten lines that fetch tickets, filter, fetch commits, check tests, and returns only the result. The tools are then functions in a folder, not entries in the context. That is exactly what I described with the avatar: once a generic script, which then runs without a model. Latency drops by an order of magnitude, and the logs never pass through the model, only the three lines that matter.
No state in the server. Every request carries what it needs. That is what the revision now prescribes, and it is the reason the state layer next to it goes away again: it does not scale. Idempotency keys per call, so that a retry does not create anything twice. The server may die at any time.
Small, clear tools. No big ones. "Do everything with the ticket" is a bad tool. "Read ticket", "set ticket status", "append comment" are good ones. Small tools have short descriptions, the model chooses more reliably, and in a script they combine. The same rule as with the micro models: each can only do its task, each can be understood.
Filter data before the model sees it. The script filters the ten thousand rows down to five. And where customer data is inside, the layer in between replaces it with placeholders before the model sees it, and puts it back only at the next tool. That is the pseudonymisation from the test data article, just in a different place. Anthropic describes exactly this pattern in their article.
Timeouts and a script that cleans up. Every call has a deadline. And next to it runs the small script that checks processes and stops the ones that take too long. I described it in the rules article and people smiled at it. The taxonomy from Montréal lists exactly these hangs as their own fault class.
You can see the pattern. All of this is old software engineering: lazy loading, stateless services, small interfaces, filtering close to the source, timeouts. None of it is new. What is new is only that people forgot it with models, because the first demo on the laptop looked so good.
Evidence
I do not make claims without a source here, that is a rule I set myself. The numbers and statements above come from these texts, all read in September 2026:
Anthropic Engineering, "Code execution with MCP", 4 November 2025. Describes the two core problems (tool descriptions fill the context, intermediate results pass through the model) and the example of 150,000 versus 2,000 tokens, 98.7 percent. Recommends code instead of individual calls, progressive disclosure, filtering before the model, placeholders for sensitive data. anthropic.com/engineering/code-execution-with-mcp
The Register, "Model Context Protocol prepares to break with its stateful past", 23 July 2026. Report on the 2026-07-28 revision: sessions removed, metadata per request, routing in HTTP headers, sampling and roots removed, not backward compatible, big effort for homegrown implementations. Figures on SDK downloads and number of servers. theregister.com
Taraghi, Morovati, Khomh (Polytechnique Montréal), "Real Faults in Model Context Protocol (MCP) Software: a Comprehensive Taxonomy", arXiv, March 2026, revised August 2026. First large fault taxonomy for MCP servers with five fault classes, confirmed by a practitioner survey. arxiv.org/abs/2603.05637
Own experience. 33 tools in NeoCoder via MCP, in operation since early 2026. The token estimate per request is my calculation, not a measurement, and is therefore stated as an estimate in the text.
What stays
MCP stays. As a description of which tools exist and how to call them it is useful, and after the revision usable on servers too. What does not stay is the idea that the model calls every tool individually and reads every result. That was the demo. Operation looks different: the model decides, a script works, and the model only sees what matters.
MCP is slow because it was built that way: all tools in the context, every call a round trip, state in the server. By now the inventors say so themselves, with numbers, and they rebuilt the protocol in July. What I do differently: load tools only when needed, the model writes a script instead of thirty calls, no state in the server, small tools, filter before the model, timeouts. Old engineering. It still works.
Written by me. The thoughts, the values, the learnings, the mistakes: all mine. Grammar and spelling are corrected by a twin model of my own, trained on my texts. Sometimes that turns into a mix. Of course I read everything again, but nobody is infallible. Whatever stays in is mine too.