Skip to content

Streamable HTTP server accepts mismatched MCP-Protocol-Version header and body protocolVersion on initialize #2618

@cclabadmin

Description

@cclabadmin

Initial Checks

Description

When the initial Streamable HTTP initialize request carries a MCP-Protocol-Version HTTP header that disagrees with initialize.params.protocolVersion in the JSON-RPC body, the Python SDK server accepts the request without error.

In both mismatch directions, the server returned HTTP 200 with a normal initialize result. The negotiated protocol version followed the JSON-RPC body rather than the MCP-Protocol-Version request header:

body=2025-11-25 header=2025-03-26 -> HTTP 200, negotiated version follows body (2025-11-25)
body=2025-03-26 header=2025-11-25 -> HTTP 200, negotiated version follows body (2025-03-26)

After initialization, subsequent responses used the body-negotiated version in the MCP-Protocol-Version header, not the original mismatched header value.

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.

Expected behavior would be one of these:

  • The server rejects the mismatch before negotiation, for example with HTTP 400 or a JSON-RPC Invalid Request error.
  • The spec clarifies which field is authoritative, and the Python SDK documents that behavior and covers it with a regression test.

Related context: SEP-2575 introduces a related requirement that, for HTTP requests, the MCP-Protocol-Version header match _meta["io.modelcontextprotocol/protocolVersion"].

Example Code

'''
With a Python SDK Streamable HTTP server running, set `ENDPOINT` to the server endpoint.

Then 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`.

Observed result in both stateful and stateless Streamable HTTP profiles:

'''

HTTP/1.1 200 OK

{"jsonrpc":"2.0","id":"init-conflict-1","result":{"protocolVersion":"<body protocolVersion>", ...}}

Python & MCP Python SDK

- Python used for reproduction: `3.12.3`
- Python SDK stable release: `v1.27.1` (`77431ebe`)
- Also reproduced with pinned `main` snapshot from 2026-05-11: `161834d4`
- SDK `pyproject.toml` declares `requires-python = ">=3.10"`
- Transport: Streamable HTTP server, stateful and stateless profiles

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions