I updated my editor last week and three MCP servers stopped working. Same error each time:
I spent about forty minutes assuming I'd broken something. I hadn't. Neither had the server authors. The spec changed underneath all of us.
If you got here from googling -32601 method not found mcp or initialize method not found or you're just staring at a server that worked fine on Friday, this is what happened.
MCP revision 2026-07-28 made the protocol stateless. Not "added a stateless mode". Made it stateless, and deleted the parts that assumed otherwise.
Gone: initialize and notifications/initialized ping logging/setLevel resources/subscribe and resources/unsubscribe notifications/roots/listchanged server-initiated requests entirely, which means sampling/createMessage, elicitation/create and roots/list no longer work the way they did
Every MCP server written before mid-2026 relies on at least the first item. That's why yours broke.
Your client is modern, your server is not. The client never sent a handshake because there is no handshake anymore. Instead it sends server/discover, which your server has never heard of, and then the reverse happens: your server waits for an initialize that never comes.
Because there's no session, every single request now has to carry its own context. It goes in params.meta:
Protocol version and client capabilities on every request. Not once at startup. Every request. If you're writing a client by hand and skipped this, that's your error.
The version in that meta block didn't match. Worth knowing that the error codes got renumbered in this revision too, so old code checking for -32001 will silently stop matching. -32020 is header mismatch, -32021 is a missing client capability, -32022 is the version one.
The server needed something the client didn't declare. Since capabilities now arrive per request instead of being negotiated once, a client that forgets to declare sampling will get this the moment a tool tries to use it.
If your server calls back to the client mid-request (an elicitation prompt, a sampling call, asking for roots), it's now waiting forever. Modern clients cannot receive pushes. There's nothing listening.
This one is nastier than the others because there's no error at all. It just sits there.
This is the part I found genuinely clever, and it's worth understanding even if you never write a server.
Old world: server interrupts its own call, asks the client something, waits for an answer, continues.
New world: the server can't push, so it returns early with a result that says "I need input", and the client calls the same thing again with the answers attached.
The client answers by re-sending the original request with requestState and an inputResponses map keyed the same way. The call picks up where it left off. It's called a multi round-trip request, MRTR if you read the SEPs.
The bit that catches people: the values in inputResponses are the response body itself, not wrapped in a result field. I got that wrong the first three times.
