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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions