FastMCP SSE server hangs on Ctrl-C after a client connects; how to fix?
I run a minimal FastMCP server (python-sdk) with mcp.run(transport='sse') and call a tool from the Python MCP SDK client. Before any client connects, Ctrl-C shuts uvicorn down cleanly; after one request, Ctrl-C prints "Waiting for background tasks to complete. (CTRL+C to force quit)" and the process never exits. Is this a known bug, and is there a fix or workaround?
Originally asked on GitHub: https://github.com/modelcontextprotocol/python-sdk/issues/514
6 answers
Status: still open. One comment says "Fixed in #586", but the issue remains open, and a later report on mcp 1.14.0 with Cursor holding the SSE connection says the hang still happens; a 2026 comment also describes the active-SSE-connection shutdown case as still needing work.
The likely cause, as stated in the thread, is that uvicorn is waiting for the open SSE connection to close. With the minimal FastMCP SSE server, the sequence GET /sse, then POST /messages/?session_id=..., then CallToolRequest is enough to make Ctrl-C stop at "Shutting down" and then "Waiting for background tasks to complete. (CTRL+C to force quit)". Even forced Ctrl-C does not exit the process; the only reliable stop is killing the process. Disabling VS Code Remote's "Auto Forward Ports" did not help.
The only mitigation mentioned in the thread is an unconfirmed suggestion: add timeout_graceful_shutdown=3 to the uvicorn.Config(...) call inside run_streamable_http_async() so uvicorn forces shutdown after a few seconds. This is a uvicorn setting, not an MCP SDK option, the suggestion was aimed at the streamable HTTP path rather than the SSE transport, and nobody in the thread reported testing it, so treat it as a possible direction rather than a verified fix. Also note that the MCP Inspector's "Disconnect" button does not terminate the session, so an open client session may be what keeps uvicorn waiting.
Did this work for you?What a GitHub user tried on GitHub (Didn't work)
Reproduced with a minimal FastMCP SSE server and the Python MCP SDK client: after the client called the echo tool, Ctrl-C left the server stuck on "Waiting for background tasks to complete. (CTRL+C to force quit)".
Source: https://github.com/modelcontextprotocol/python-sdk/issues/514 (opens external site)
Did this work for you?What @voidwisp tried on GitHub (Didn't work)
On mcp 1.14.0 with Cursor holding the SSE connection, repeated Ctrl-C could not stop the server.
Did this work for you?What @sealpp tried on GitHub (Didn't work)
Disabled VS Code Remote's "Auto Forward Ports" to rule it out as the cause, but the shutdown hang still occurred.
Did this work for you?What @growler tried on GitHub (Didn't work)
Reported that with one established connection, even forced Ctrl-C does not shut the server down; only killing the process works.
Did this work for you?What @lanstonchu tried on GitHub (Outcome unclear)
Suggested adding timeout_graceful_shutdown=3 to the uvicorn.Config used by run_streamable_http_async() to force shutdown after a few seconds, but nobody reported testing this.
Did this work for you?
Related questions
- MCP python-sdk simple-chatbot: 'Attempted to exit cancel scope in a different task than it was entered in'
- Why is my MCP resource template (greeting://{name}) not available in Claude Desktop?
- How to disable TLS certificate verification (verify=False) in MCP streamablehttp_client?
- anyio.ClosedResourceError in MCP StreamableHTTP message router on fast-failing requests?
- Python MCP SDK streamable HTTP: 'Error in message router' ClosedResourceError after 307 redirect