-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Open
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
When a client cancels a long-running tool call (e.g., user hits Escape in Claude Code), the MCP server crashes with an assertion error and becomes unresponsive.
What I'm seeing:
- Server crashes with "AssertionError: Request already responded to"
- All subsequent requests fail
- Server must be restarted
What I expect:
- Server should handle cancellation gracefully
- Server should remain responsive for subsequent requests
Root cause:
In Server._handle_request
, when a CancelledError occurs:
- RequestResponder.cancel() has already sent an error response
- The CancelledError propagates to _handle_request
- It tries to send another error response
- This triggers "already responded to" assertion
Example Code
from mcp.server import Server
import asyncio
server = Server("test-server")
@server.call_tool()
async def slow_tool(name: str, arguments: dict):
# Any long-running operation
await asyncio.sleep(30)
return [{"type": "text", "text": "Done"}]
# When client calls slow_tool and cancels (e.g., hits Escape in Claude Code)
# Server crashes with: AssertionError: Request already responded to
Python & MCP Python SDK
Python 3.8+ (tested on 3.11)
MCP Python SDK: Latest version from main branch
Related issues: jlowin/fastmcp#508, jlowin/fastmcp#823
Metadata
Metadata
Assignees
Labels
No labels