Bug
The stable server-sse-multiple-streams scenario initializes through StreamableHTTPClientTransport, but its three raw follow-up POSTs hard-code:
'mcp-protocol-version': '2025-03-26'
With --spec-version 2025-11-25, the SDK and a current server negotiate 2025-11-25. A server that enforces the negotiated session version therefore correctly returns HTTP 400 to all three raw POSTs, and the concurrency scenario fails before testing concurrency.
This is present in @modelcontextprotocol/conformance 0.1.16 and current main:
https://github.com/modelcontextprotocol/conformance/blob/main/src/scenarios/server/sse-multiple-streams.ts
Reproduction
Run the scenario against a stateful server that stores the protocolVersion returned by initialize and requires a matching MCP-Protocol-Version on subsequent requests:
conformance server \
--url http://127.0.0.1:8930/mcp \
--scenario server-sse-multiple-streams \
--spec-version 2025-11-25
Observed result:
Server rejected some requests. Statuses: 400, 400, 400
The same server passes the other 30 stable 2025-11-25 scenarios, its official SDK client round trip, and a concurrent POST test when all requests use the negotiated version.
Expected
The raw POSTs should use the actual version selected during initialization. The SDK transport exposes it as transport.protocolVersion, so the stateful headers can use that value rather than a fixed historical revision.
The MCP lifecycle requires both parties to respect the negotiated protocol version during operation:
https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle
Suggested change
After await client.connect(transport), require transport.protocolVersion alongside the session ID and use it for mcp-protocol-version in requestHeaders. A regression test should cover a server that rejects a globally supported but non-negotiated revision.
Bug
The stable
server-sse-multiple-streamsscenario initializes throughStreamableHTTPClientTransport, but its three raw follow-up POSTs hard-code:With
--spec-version 2025-11-25, the SDK and a current server negotiate2025-11-25. A server that enforces the negotiated session version therefore correctly returns HTTP 400 to all three raw POSTs, and the concurrency scenario fails before testing concurrency.This is present in
@modelcontextprotocol/conformance0.1.16 and currentmain:https://github.com/modelcontextprotocol/conformance/blob/main/src/scenarios/server/sse-multiple-streams.ts
Reproduction
Run the scenario against a stateful server that stores the
protocolVersionreturned by initialize and requires a matchingMCP-Protocol-Versionon subsequent requests:Observed result:
The same server passes the other 30 stable 2025-11-25 scenarios, its official SDK client round trip, and a concurrent POST test when all requests use the negotiated version.
Expected
The raw POSTs should use the actual version selected during initialization. The SDK transport exposes it as
transport.protocolVersion, so the stateful headers can use that value rather than a fixed historical revision.The MCP lifecycle requires both parties to respect the negotiated protocol version during operation:
https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle
Suggested change
After
await client.connect(transport), requiretransport.protocolVersionalongside the session ID and use it formcp-protocol-versioninrequestHeaders. A regression test should cover a server that rejects a globally supported but non-negotiated revision.