Opens in a new tabSkip to content
Agent LighthouseAgent Lighthouse

    Searches the text of every published page. The evidence sources themselves are not in this index — search all of them on the trusted sources page.

    GitHub ↗
    Browse checks and page contents
    agent-interfaces/mcp-version-downgrade

    Version Downgrade Recoverability

    What it checks

    Negative-path probe that verifies the server fails correctly when handed a protocol version it does not support, and when the MCP-Protocol-Version header disagrees with the body’s _meta. Both are MUST-level behaviors whose absence strands otherwise-compatible clients.

    Why it matters

    With the handshake removed, one mechanism is left for a client to discover a mutually supported version mid-flight: the UnsupportedProtocolVersionError. The spec requires code -32022, with data.supported[] listing the server’s versions, and instructs clients to select from that list and retry. A server that instead returns a 500, a generic -32600 or -32602, or a 400 with no supported array, gives the client nothing to downgrade to. A client whose preferred version is one revision ahead of the server’s then fails permanently — even though a mutually supported version exists on both sides.

    Separately, the spec requires the header and the _meta value to agree, with a 400 and -32020 HeaderMismatch on divergence. A server that silently ignores the mismatch is trusting whichever source of truth its proxy layer did not. That is the exact split-brain the header-validation rules exist to prevent.

    Evidence

    • MCP Specification 2026-07-28 — Streamable HTTP Transport — Model Context Protocol (Anthropic / MCP Working Groups) (spec, URL verified 2026-08-20)
    • Revision 2026-07-28 removed the GET stream endpoint and protocol-level sessions (Mcp-Session-Id, Last-Event-ID). Server MUST expose one POST endpoint. Server MUST validate Origin; if Origin is present and invalid it MUST return 403 Forbidden. Every POST MUST carry MCP-Protocol-Version, Mcp-Method, and (for tools/call, resources/read, prompts/get) Mcp-Name headers; these are ‘REQUIRED for compliance’. Header value MUST match the _meta body value or server MUST return 400 + JSON-RPC code -32020 HeaderMismatch. Unknown protocol version -> 400 + UnsupportedProtocolVersionError. Unknown method -> 404 + -32601. x-mcp-header constraints defined; clients MUST reject (exclude from tools/list) tools that violate them. Servers SHOULD send X-Accel-Buffering: no on SSE. GET/DELETE to endpoint SHOULD now return 405.
    • MCP Specification 2026-07-28 — Versioning and Compatibility — Model Context Protocol (spec, URL verified 2026-08-20)
    • ‘There is no negotiation handshake.’ Terminology: Modern = 2026-07-28+ (per-request _meta); Legacy = 2025-11-25 and earlier (initialize handshake). Unsupported version MUST return error code -32022 with data.supported[] and data.requested. Verbatim compatibility matrix: Modern client + Legacy server = fails. Legacy client + Modern server = fails. Only dual-era implementations bridge. Extensions negotiated via capabilities.extensions map with mandatory reverse-DNS prefix.

    How it scores

    Tier per evidence policy: scored — grade A meets the A/B bar required for scored audits.

    Example failure

    A SaaS vendor’s server supports 2025-11-25 and 2026-07-28. Sent 1900-01-01, its framework’s generic error handler returns 500 Internal Server Error with an HTML body. A client that prefers a hypothetical future revision receives no supported list, cannot downgrade, and marks the server permanently incompatible — despite 2026-07-28 being available on both ends. The same server also returns 200 for Probe B, so a gateway routing on the header while the app executes on the body can be made to disagree.

    Sources