Streamable HTTP server silently drops in-flight request when client reuses a JSON-RPC id
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 68/100
Rechercherichtung
Beginne in src/mcp/server/streamable_http.py bei den Zeilen 534-536 und untersuche anschließend die Router-Logik bei den Zeilen 1004-1033. Verfolge, wie doppelte Request-IDs Einträge in _request_streams ersetzen und wie Antworten verteilt werden. Als erledigt gilt die Aufgabe, wenn die bestehende Anfrage weiterhin in Bearbeitung unverändert bestehen bleibt, die doppelte Anfrage JSON-RPC -32600 Invalid Request erhält und der Verstoß protokolliert wird.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Summary
When a client sends two JSON-RPC requests with the same id on the same Streamable HTTP session before the first response is delivered, StreamableHTTPServerTransport overwrites the per-id response stream slot without warning. The first request's caller hangs until its read times out, and the second response is delivered to whichever caller wins the race. The server logs nothing.
The MCP base protocol requires that "the request ID MUST NOT have been previously used by the requestor within the same session," so a duplicate id is a protocol violation by the client. But the server has no way to tell the client (or an operator) that the violation happened, which makes this very hard to diagnose downstream.
Where it happens
In src/mcp/server/streamable_http.py lines 534-536 at v1.27.1:
request_id = str(message.root.id)
self._request_streams[request_id] = anyio.create_memory_object_stream[EventMessage](0)
request_stream_reader = self._request_streams[request_id][1]
The assignment is unconditional. If request_id is already a key in _request_streams, the prior (send, receive) pair is dropped on the floor. The earlier request's writer eventually tries to push a response into a stream nobody is reading, and the earlier request's caller is reading a stream nobody will ever write to.
The router side at lines 1004-1033 uses the same str(id) keying to dispatch responses, so once the slot has been overwritten, response routing is undefined.
Reproduction signature
We hit this through an in-house client that was sending id: 1 for every concurrent tool call on a shared session. Under concurrent load, calls timed out and at least one caller received the wrong tool's response payload.
Proposed Behavior
When a request arrives with an id that already has an in-flight stream registered, the server should reject it with JSON-RPC -32600 Invalid Request and leave the existing in-flight request untouched. This:
- Surfaces the spec violation to the client immediately instead of timing out.
- Preserves the in-flight request that arrived first.
- Gives operators a log line to diagnose against.
A weaker variant (log-only, no error response) would still be a meaningful improvement over silent data loss.
- Vorherrschende Sprache
- Python
- Sterne
- 24.3k
- Forks
- 4k
- Ø Merge
- 1 T. 11 Std.
- Gemergte PRs (30 T.)
- 30
Beitragsleitfaden
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus modelcontextprotocol/python-sdk
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
modelcontextprotocol/python-sdk#3566 ·
-
v1 v2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
modelcontextprotocol/python-sdk#3546 · 5 Kommentare ·
-
v1 v2
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
modelcontextprotocol/python-sdk#3545 · 1 Kommentar ·
-
v1 v2
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 91/100
modelcontextprotocol/python-sdk#3508 · 2 Kommentare ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 64/100
modelcontextprotocol/python-sdk#3504 ·
Alle Issues in modelcontextprotocol/python-sdk
Ähnliche Issues
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
xinnan-tech/xiaozhi-fde-talk#263 ·
-
rules
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 90/100
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
huggingface/Repo2RLEnv#163 · 1 Kommentar ·
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 95/100
huggingface/sentence-transformers#4074 ·
-
comp/dashboard invalid P3
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
NousResearch/hermes-agent#121143 ·