Repository navigation
Streamable HTTP server accepts mismatched header/body protocol versions and negotiates 2024-11-05 on initialize #852
Description
Describe the bug
When the initial initialize request carries a MCP-Protocol-Version HTTP header that disagrees with initialize.params.protocolVersion in the JSON-RPC body, the server accepts the request without error. In these tests, the negotiated version does not follow either the body or the header, the server returns a server-determined version (2024-11-05) regardless of both input values.
The current MCP 2025-11-25 specification does not explicitly require the server to check body/header consistency on initialize, so this is filed as an implementation observation rather than a strict spec-violation claim.
- Environment
- Reproduced with stable release
rmcp-v1.7.0(3529c367) - Also reproduced with a
mainsnapshot from 2026-05-15:cc66e309 - Transport: Streamable HTTP server (stateful profile)
- Reproduced with stable release
To reproduce
- Start a Rust SDK Streamable HTTP server.
- Send an
initializerequest where the bodyprotocolVersionis2025-11-25but theMCP-Protocol-Versionheader is2025-03-26(or vice versa). - Observe that the server returns HTTP 200 with a normal
initializeresult. - Check the negotiated protocol version in the response.
Expected behavior
Option A: the server rejects the mismatch before negotiation, for example with HTTP 400 or a JSON-RPC Invalid Request error.
Option B: the spec clarifies which field is authoritative, and the SDK documents that behavior and covers it with a regression test.
Logs
Both mismatch directions were accepted:
body=2025-11-25 header=2025-03-26 -> HTTP 200, negotiated version = 2024-11-05 (server-determined)
body=2025-03-26 header=2025-11-25 -> HTTP 200, negotiated version = 2024-11-05 (server-determined)
The server returned its own preferred protocol version (2024-11-05) regardless of both the body and header values. In the observed behavior, the negotiated version did not follow either mismatched input value. However, the negotiated version (2024-11-05) may still differ from what a client would expect from either signal.
With a Streamable HTTP server running, set ENDPOINT to the server endpoint and send an initial initialize request whose HTTP header and JSON-RPC body disagree:
ENDPOINT=http://127.0.0.1:8080/mcp
curl -i -sS --http1.1 -X POST "$ENDPOINT" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-03-26' \
--data '{"jsonrpc":"2.0","id":"init-conflict-1","method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"version-conflict-repro","version":"0.1.0"}}}'Then repeat with the values reversed: body 2025-03-26, header 2025-11-25.
Additional context
- Related: SEP-2575 introduces a related future-state requirement that, for HTTP requests, the
MCP-Protocol-Versionheader match_meta["io.modelcontextprotocol/protocolVersion"].
Activity
DaleSeo commentedon May 18, 2026
Thanks for reporting this, @cclabadmin! I realized that the report highlights two separate issues, so I've divided the fix into #853 and #855.
DaleSeo commentedon May 18, 2026
@alexhancock We also need to land #853 to resolve this issue.
alexhancock commentedon May 19, 2026
@DaleSeo It looks good - sorry I didn't review them in tandem