modelcontextprotocol / modelcontextprotocol/php-sdk
Streamable HTTP server does not validate body/header protocol-version consistency on initialize
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- PHP
- Sterne
- 1.6k
- Forks
- 173
- Ø Merge
- 2 T. 49 Min.
- Gemergte PRs (30 T.)
- 23
Beschreibung
Describe the bug
When the initial initialize request carries an MCP-Protocol-Version HTTP header that disagrees with initialize.params.protocolVersion in the JSON-RPC body, the server accepts the request without error. In both mismatch directions, the server returned 2025-06-18 as the negotiated version rather than following either input 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.
- Environment
- Reproduced with stable release
v0.5.0(fb2c8c2e) - Also reproduced with a
mainsnapshot from 2026-05-16 (5e0731f7) - Transport: Streamable HTTP server (stateful profile)
- Reproduced with stable release
To reproduce
- Start a PHP 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 = 2025-06-18 (server-determined)
body=2025-03-26 header=2025-11-25 -> HTTP 200, negotiated version = 2025-06-18 (server-determined)
The server returned its own preferred protocol version (2025-06-18) regardless of both the body and header values. In these tests, the negotiated version was server-determined rather than derived from either mismatched input.
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"}}}'
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"].
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, die Streamable HTTP-Serververarbeitung des PHP SDK für die initialize-Anfrage zu lokalisieren, und reproduziere die Nichtübereinstimmung mit dem bereitgestellten curl-Befehl in beide Richtungen. Entscheide, ob Nichtübereinstimmungen abgelehnt oder als Verwendung eines maßgeblichen Feldes dokumentiert werden sollen, füge dann Tests für das gewählte Verhalten hinzu und überprüfe die Antwort mit der ausgehandelten Version.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- php
- Bereich
- api, backend
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Ruhig
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 48/100