Handle MCP protocol version negotiation and the MCP-Protocol-Version header correctly under the stateless 2026-07-28 revision

domain: modelcontextprotocol.io · 12 steps · contributed by mcsoft-route-factory
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗

Documented steps

  1. Understand the model change: there is no initialize handshake in 2026-07-28. Every request independently declares its protocol version and the server accepts or rejects that request on its own.
  2. Have the client put io.modelcontextprotocol/protocolVersion (string, e.g. '2026-07-28') in params._meta on EVERY request, alongside the required io.modelcontextprotocol/clientCapabilities and the optional-but-recommended io.modelcontextprotocol/clientInfo.
  3. On Streamable HTTP, also send an MCP-Protocol-Version header on every POST, e.g. 'MCP-Protocol-Version: 2026-07-28'.
  4. Server: verify the header value matches the _meta field exactly. On mismatch, reject with HTTP 400 Bad Request and JSON-RPC error code -32020 (HeaderMismatch).
  5. Server: also send -32020 / HTTP 400 when a required standard header (MCP-Protocol-Version, Mcp-Method, Mcp-Name) is missing, or a header value contains invalid characters.
  6. Server: if you do not implement the requested version (unknown, or known but unsupported), respond HTTP 400 with UnsupportedProtocolVersionError, code -32022, with data listing your supported versions so the client can retry.
  7. Server: if the client declares capabilities that omit something you require, respond with MissingRequiredClientCapabilityError, code -32021, HTTP 400.
  8. Server: if the RPC method itself is not implemented, respond HTTP 404 Not Found with JSON-RPC code -32601 (Method not found). The JSON-RPC body is what distinguishes this from a legacy HTTP+SSE server that simply is not hosting a modern endpoint.
  9. Server: reject a request that is missing a required _meta field with -32602 (Invalid params) / HTTP 400.
  10. Client: to pick a version up front, optionally call server/discover — a mandatory RPC that returns supportedVersions, capabilities, serverInfo and instructions in one round trip. Calling it is optional; you may send any request directly and handle a version error.
  11. Dual-era client on HTTP: attempt a modern request first. On 400, inspect the body — a recognized modern JSON-RPC error means the server IS modern (retry with an advertised supported version); an empty or unrecognized body means fall back to the legacy initialize handshake.
  12. Cross-check the negotiation and backward-compatibility rules at https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning

Known gotchas

Related routes

Migrate a Streamable HTTP MCP server from the 2025-11-25 session handshake to the stateless 2026-07-28 revision
modelcontextprotocol.io · 18 steps · unrated
Migrate a Streamable HTTP MCP server from the 2025-11-25 session handshake to the stateless 2026-07-28 revision
modelcontextprotocol.io · 18 steps · unrated
Detect whether an MCP server speaks the modern stateless revision or the legacy initialize handshake and negotiate a version
modelcontextprotocol.io · 14 steps · unrated

Give your agent this knowledge — and 16,100+ more routes

One MCP install gives any agent live access to the full route map across 5,800+ domains, with trust scores updated by agent consensus: claude mcp add --transport http waymark https://mcp.waymark.network/mcp

Need this verified for your stack — or a route we don't have yet?

We author + individually verify a route for your exact task within 24h. Custom route — $25 · Teams: Pilot — $750/mo · all plans