In retrospect, stateful MCP was clearly wrong.
This essentially makes MCP just another REST API endpoint, and lets you use the same infrastructure you already have set up for REST APIs (like load balancers, API gateways, progressive rollouts, etc).
In retrospect, stateful MCP was clearly wrong.
This essentially makes MCP just another REST API endpoint, and lets you use the same infrastructure you already have set up for REST APIs (like load balancers, API gateways, progressive rollouts, etc).
Something that anyone doing distributed systems knows after a few scars, stateless servers are always better, and stateful only if there is no way around it.
I learnt this with Sun RPC and the whole "The network is the computer".
Somehow this keeps having to be relearnt.
I keep encountering mistakes by people who are convinced that agentic interactions are nothing new, that all the decades of hard-won lessons about service API design are 100% relevant and nothing more is needed, that agents can be relegated to the role of just-another-caller and left to the dismal domain of client developers.
It’s not true. It’s not totally untrue, but don’t hide your head in the sand.
You didn't provide any arguments to support your claim. Calling people names isn't going to convince anyone.
Okay, here’s one I’m working through. When the workload consists of compound elements in multiple domains, agents work best when they see that as a flat surface of detailed resources. Traditional APIs work best when they hide the implementation details behind an ergonomic api.
So service API developers want to abstract and hide, over and over, and this means agents have less and less context and do more guessing.
And agentic enthusiasts apparently believe agents can do anything except REST.
If agents are "like humans" (whatever we mean by that), then shouldn't all the lessons we learned over the decades on how to build APIs for direct and indirect human consumption be extremely relevant?
With human devs, errors become recovery instructions.
400 Bad Request is fine for a client developer who reads it once at design time and fixes the code forever. it's dead weight for an agent that must self-correct from the string alone. "Expected ISO-8601, got 03/04/2025" is now a functional part of the interface.
Not all agents are developers who can code their own interface.
MCP is basically just:
1. a REST-like API
2. with a spec (OpenAPI, introspection, etc.)
3. with harness-level authz (the ability to allow / deny specific methods in the harness)
The only part that's actually new is #3, but it seems like it should be fairly easy to provide similar support for REST APIs. There might already be a Pi extension that allows you to allow / deny particular method / path patterns for particular sites. Regardless, there's always service-level authz with service accounts, at least for the more sophisticated APIs.
So ya, I don't see why we need a whole new set of standards and protocols just to have harness-level fine-grained API permissions. We could have just done it all with REST.
Honestly MCP is geared mainly for the non-technical folks who don't understand a thing about REST or OpenAPI (otherwise, of course folks can just ask models to search/parse/code/parse and get things done -- don't need to ask for an MCP endpoint at all). Models also do a lot better with tool calls than asking them to string together instrospection, web-search, curl, etc. (that's a lot of tokens) rather than having the endpoint expose a single URL that the model can take, auth, understand, and use.
I maintain https://endara.ai and you can very quickly introduce a ton of capabilities for Claude/Cursor/ChatGPT by configuring all the stuff you use in a single place (and slicing them with profiles if needed).
The user experience for a rest api and for mcp can be the same. For MCP, you have to give the mcp server url. For REST, you could provide a url to the openapi spec. The open API spec has everything you'd need - oauth url + all the endpoints and params.
Most chat products will just have a directory of connectors anyways - so for non technical folks they won't even here the term MCP or REST, they'll just "Install the Gmail plugin".
Yep. There's already a well-established system of `.well-known` URL paths to support things like API spec discover, auth discovery, etc. Why re-invent those wheels?
Like many things in this fashion industry, how else do you get new conference subjects, consulting gigs, books,...?
Because while an agent can indeed call a REST API directly using some other tool ( probably curl) what LLMs are good at is calling tools, and all MCP is doing is turning an API into a tool and standardizing authorization, which if you go the API route can be a nightmare as auth is not even mentioned in OpenAPI specs, usually, so the agent has to figure out how to do auth, and it will necessarily have access to your token and maybe even credentials, so it can easily leak it to attackers your agent happens to visit by just asking for it. I can’t believe anyone who has tried to give agents access to APIs in a sane manner hasn’t concluded that something on the lines of MCP is absolutely necessary.
I guarantee you any LLM will be perfectly capable of navigating HTTP auth [1] which has been around since 1999.
You could use `curl`, or you could bake an HTTP client tool into the agent harness which operates at a more abstract level. The agent would just have a tool that looks a lot like the Fetch API [2] and the harness could simply be configured to inject credentials using the various well-established patterns that have long existed, allow / deny certain methods, etc. The thing is, everything you can do with MCP could also simply be done with REST, so neither is inherently better than the other, I just don't like the proliferation of needless standards.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Aut...
[2]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...
You can’t be seriously proposing HTTP auth (you probably mean basic auth??) as a solution!? Just hand your raw credentials to the LLM, what could go wrong?
Letting the harness inject the credentials implies not exposing them to the LLM.
Besides, the current state of MCP authentication almost always involves just hard coding secrets in .claude/settings.json so it's not like that's doing a great job keeping the creds away from the LLM anyway. All I'm saying is that MCP auth offers no advantage.
OpenAPI 3.0 has auth. You can turn OpenAPI specs into tool calls just as well, without giving your agents access to call curl and without leaking credentials.
The problem is often that OpenAPI schemas are often incomplete, since they used to be useful to humans even in an incomplete state.
MCP basically requires you to do the equivalent work of getting your OpenAPI schema complete. It’s just much easier to sell to your managers.
I think by now even non-technical vibe coders have enough of an overview on REST APIs
The spec is more than just an OpenAPI scheme; it’s a strict wire format with shared semantics for a huge range of features.
Are you trying to say that REST APIs don't have a strict wire format with shared semantics for a huge range of features?
Kind of--I'm saying that RESTful APIs are just an abstract vocabulary to describe state transfer operations, whereas MCP describes a concrete set of such operations. REST sits on top of the HTTP protocol layer, MCP sits on top of REST (if we accept how the meaning of REST has been butchered, but you know what I mean.)
This is easy to see when you think in terms of a client: It is pretty much impossible to build an opinionated UI for any kind of RESTful API, while creating one for an MCP server is fairly self-explanatory: MCP servers offer a mandatory and complete runtime introspection endpoint (you can retrieve a listing of available tools/resources/prompts etc. along with their parameter and return type schemas). So that means clients have a way to exhaustively describe everything an MCP server is able to do with a vocabulary that carries over exactly to other servers - a tool is a tool everywhere.
See my point #2. There are already standards to describe APIs.
This is easy to see when you think in terms of a developer. The natural way to adapt an existing REST API into an MCP server while keeping the two synchronized is to simply write a basic translation tool that takes your OpenAPI spec and turns it into an MCP manifest, mapping each HTTP endpoint to an MCP method, and copying over all the request / response type signatures and descriptions for everything. Then, all of the sudden, it hits you: there is no need for this translation layer.
I think OpenAPI does all you mentioned in your comment too. Maybe MCP is more strict, in the sense that it requires natural-language descriptions, which are optional in OpenAPI, but I don’t see the distinction.
There are multiple products that turn OpenAPI schemas into front-ends nowadays.
Isn’t that the case? Aren’t REST people still debating about what makes a true beautiful REST API?
When I say REST, I basically mean HTTP/JSON. I know. Shame on me.
But there's a pretty large body of RFCs that define what makes a good REST API. For instance POST should create things, PUT should re-define them, PATCH should incrementally update them, GET must be side-effect-free, etc. And there's a ton of standard HTTP headers. Pair it with OpenAPI and the whole thing is self-documenting. You can achieve the same effect with gRPC + reflection, or GraphQL + reflection, and there's plenty of mature tooling and interoperability for each system.
By comparison, MCP actually has relatively few conventions. LLMs are very familiar with REST and OpenAPI already. Just use that.
REST has issues tough.
How do you send a big read only query? A POST? A GET hoping nothings logs it or swallows half of it?
How do you deal with delayed answers? Things that most HTTP middleware will timeout long before the result is achieved?
REST has issues if you limit yourself to think of the “resources” as your domain entities.
If you have a long running search, the resource is the search. Create a search. Fetch search results. Delete the search when you’re done.
Similarly, if you have a sufficiently complex command, the resource is the command itself. Maybe it requires async work, and you can later fetch the command results.
Anecdotally, this seems to be too big of a leap in mental model for beginners, mostly because all of the REST learning path does is teach you how to use it in CRUD domains.
I think you provide good and accurate information. However, what you described sounds like a workaround to me.
The read-only QUERY method can send much bigger requests than GET.
For delayed answers, MCP offers no improvement, because remote MCP servers use an HTTP transport anyway, and local ones don't involve middleware you can't control. Besides, that's well-trodden ground. SSE, trailers, gRPC streaming, websockets, simple polling, etc. We don't need another protocol.
The wire format certainly isn’t strict
There's a nice feature in the new version that lets you copy tool _arguments_ in to the HTTP Headers for custom routing etc.
I came here to ask why it was ever stateful?
If you connect the dots of the earlier MCP Client/Server docs you understand that your desktop AI tool was also a MCP Server. This MCP Server provided the tools like "search files", "alter files", "open file".
It's was simpler to design/implement the AI tool if these interactions had state. When this was generalized to internet interactions this no longer made sense and was gradually cleaned up.
I think at the same time, the AI tool "protocol" to interact with the local system moved away from MCP model.
During the initialize step, the client tells the server about its capabilities. Then the server remembers them for the session, so the client doesn't need to keep saying what it can do, and the server won't expose tools the client can't use. It's more overhead for the server, but more efficient over the wire for the rest of the session (that's just my understanding at least -- not saying this couldn't all be stateless).