Skip to content

Commit c69aa55

Browse files
committed
fix(server): send JSON-RPC parse error when stdio transport fails to parse message
When the stdio transport cannot parse an incoming JSON-RPC message (e.g. deeply-nested JSON exceeding the recursion limit), the stdin_reader sends a raw Exception through the read_stream. Previously, the session only forwarded this Exception to the application layer via _handle_incoming, never sending a JSON-RPC error response. The client request would hang indefinitely waiting for a response that never arrived. This aligns stdio behaviour with the Streamable HTTP transport, which already returns a proper JSON-RPC parse error (code -32700) for unparseable messages. Fixes #2751 Signed-off-by: Willow Lopez <100782273+Oxygen56@users.noreply.github.com>
1 parent 616476f commit c69aa55

1 file changed

Lines changed: 16 additions & 0 deletions

File tree

src/mcp/shared/session.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from mcp.types import (
2222
CONNECTION_CLOSED,
2323
INVALID_PARAMS,
24+
PARSE_ERROR,
2425
REQUEST_TIMEOUT,
2526
CancelledNotification,
2627
ClientNotification,
@@ -427,6 +428,21 @@ async def _handle_session_message(message: SessionMessage) -> None:
427428

428429
async for message in self._read_stream:
429430
if isinstance(message, Exception):
431+
# The transport couldn't parse the incoming message
432+
# (e.g. deeply-nested JSON exceeding the recursion
433+
# limit on stdio). Per JSON-RPC spec §5, send a
434+
# Parse error with id=null so the client doesn't
435+
# hang waiting for a response that will never come.
436+
error_response = JSONRPCError(
437+
jsonrpc="2.0",
438+
id=None,
439+
error=ErrorData(
440+
code=PARSE_ERROR,
441+
message="Parse error",
442+
data=str(message),
443+
),
444+
)
445+
await self._write_stream.send(SessionMessage(message=error_response))
430446
await self._handle_incoming(message)
431447
continue
432448

0 commit comments

Comments
 (0)