fix(server): send JSON-RPC parse error when stdio transport fails to parse message#2755
Open
Oxygen56 wants to merge 1 commit into
Open
Conversation
…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 modelcontextprotocol#2751 Signed-off-by: Willow Lopez <100782273+Oxygen56@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
When the stdio transport cannot parse an incoming JSON-RPC message (e.g. a deeply-nested
pingrequest that exceeds pydantic's recursion limit duringvalidate_json),stdin_readersends a rawException` through the read stream.Previously,
BaseSession._receive_loop()only forwarded thisExceptionto the application layer via_handle_incoming()without sending a JSON-RPC error response through the write stream. This left the client`'s request permanently pending until a client-side timeout.Root Cause
The flow for deeply-nested JSON on stdio:
stdin_readercallsjsonrpc_message_adapter.validate_json(line)→ValidationError("recursion limit exceeded")Exceptionthroughread_stream_writer.send(exc)BaseSession._receive_loop()receives theException, calls_handle_incoming(exc), but never sends a JSON-RPC responseFix
Catch the transport-level
ExceptioninBaseSession._receive_loop()and send a proper JSON-RPC parse error (code: -32700) withid: nullthrough the write stream, matching JSON-RPC spec §5 and the existing Streamable HTTP transport behaviour.Before (broken):
After (fixed):
Changes
src/mcp/shared/session.py: AddedPARSE_ERRORimport; added JSON-RPC error response emission in theisinstance(message, Exception)branch of_receive_loop()The
_handle_incoming(message)call is preserved so the application layer can still observe transport-level failures.Fixes #2751