-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Open
Labels
P1Significant bug affecting many users, highly requested featureSignificant bug affecting many users, highly requested featurebugSomething isn't workingSomething isn't workingready for workEnough information for someone to start working onEnough information for someone to start working on
Milestone
Description
Initial Checks
- I confirm that I'm using the latest version of MCP Python SDK
- I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue
Description
Issue Description:
During testing, we encountered a critical issue in the Server-Sent Events (SSE) handling mechanism:
- Problem Trigger:
To some reason, the_handle_sse_eventmethod received a truncatedsse.datapayload, causing:
A JSON parsing exceptionmessage = JSONRPCMessage.model_validate_json(sse.data)
Then the exception handle sent the exc and returned false - Current Behavior Gap:
Despite the failed processing:
·No error propagation to the client occurs
·No cleanup/retry mechanism is triggered
·The client remains stuck in a perpetual wait state for a tool_call result until timeout - Critical Impact: The server has already completed the tool_call workflow and moved to the final /done state, creating a state desynchronization between client and server
- Root Cause Hypothesis:
It appears that the client failed to detect the reception of invalid responses. Theawait read_stream_writer.send(exc)did not work during exception handling
Or maybe I missed some configs such as the retry mechanism or other error handling methods?
Example Code
async def _handle_sse_event(
self,
sse: ServerSentEvent,
read_stream_writer: StreamWriter,
original_request_id: RequestId | None = None,
resumption_callback: Callable[[str], Awaitable[None]] | None = None,
is_initialization: bool = False,
) -> bool:
"""Handle an SSE event, returning True if the response is complete."""
if sse.event == "message":
try:
message = JSONRPCMessage.model_validate_json(sse.data) ##### threw the exception
logger.debug(f"SSE message: {message}")
# Extract protocol version from initialization response
if is_initialization:
self._maybe_extract_protocol_version_from_message(message)
# If this is a response and we have original_request_id, replace it
if original_request_id is not None and isinstance(message.root, JSONRPCResponse | JSONRPCError):
message.root.id = original_request_id
session_message = SessionMessage(message)
await read_stream_writer.send(session_message)
# Call resumption token callback if we have an ID
if sse.id and resumption_callback:
await resumption_callback(sse.id)
# If this is a response or error return True indicating completion
# Otherwise, return False to continue listening
return isinstance(message.root, JSONRPCResponse | JSONRPCError)
except Exception as exc:
##### handled exception but client did not receive ######
logger.exception("Error parsing SSE message")
await read_stream_writer.send(exc)
return False
else:
logger.warning(f"Unknown SSE event: {sse.event}")
return FalsePython & MCP Python SDK
python == 3.12
SDK == 1.11.0
GoginArtem, whichxjy, tanhaipeng, zxkane, IlyaGusev and 1 more
Metadata
Metadata
Assignees
Labels
P1Significant bug affecting many users, highly requested featureSignificant bug affecting many users, highly requested featurebugSomething isn't workingSomething isn't workingready for workEnough information for someone to start working onEnough information for someone to start working on