MCP python-sdk simple-chatbot: 'Attempted to exit cancel scope in a different task than it was entered in'
Running examples/clients/simple-chatbot/mcp_simple_chatbot/main.py from the modelcontextprotocol/python-sdk (as of March 2025) on Windows 10 or Ubuntu logs: 'Error during cleanup of server sqlite: Attempted to exit cancel scope in a different task than it was entered in' followed by an error closing the stdio_client async generator. This happens right after the LLM returns an OK response. What causes this and is there a fix?
Originally asked on GitHub: https://github.com/modelcontextprotocol/python-sdk/issues/252
5 answers
Status: the issue is closed (COMPLETED) in the repository, but no maintainer patch or fixed version number is mentioned in the thread. The usable fix is a user workaround, not an official SDK change.
The error text itself says the code tried to exit a cancel scope from a different task than the one that entered it, which is an async programming invariant violation. The thread does not establish exactly which SDK code path triggers it.
One commenter reported success by changing the
cleanup_serversmethod in the example (around line 283) to run cleanup sequentially instead of in parallel:pythonasync def cleanup_servers(self) -> None: """Clean up all servers properly.""" for server in self.servers: await server.cleanup()They said this worked and that they did not create a pull request. Another commenter agreed this should work but pointed out it is slower because servers are then initialized and closed serially. The thread does not provide a working parallel alternative; one comment noted that
asyncio.gather()cannot be used because initialization order is unknown and servers should be closed in reverse initialization order, but no parallel solution was posted.If you need parallel startup, that remains unsolved in this thread. As general advice, try the sequential cleanup workaround first and measure whether the slowdown matters for your use case.
Did this work for you?What @dasoran tried on GitHub (Worked)
Changed
cleanup_serversin the simple-chatbot example to a plainforloop withawait server.cleanup(), avoidingasyncio.gather()in that path. The commenter reported it worked and noted they did not create a PR.Did this work for you?What @xiongzhp tried on GitHub (Didn't work)
Ran the simple-chatbot example on Windows 10 and Ubuntu. The sqlite server cleanup logged the cancel-scope error, followed by an async generator close error for stdio_client.
Source: https://github.com/modelcontextprotocol/python-sdk/issues/252 (opens external site)
Did this work for you?What @s-konnex-engine tried on GitHub (Outcome unclear)
Asked Claude for a diagnosis and received the explanation that a cancel scope was exited from a different task than the one that entered it. A proposed fix was mentioned but never tested or posted in the thread.
Did this work for you?What @Broyojo tried on GitHub (Outcome unclear)
Suggested that
asyncio.gather()cannot be used because server initialization order is unknown, making it impossible to close servers in reverse initialization order. No working parallel solution was provided.Did this work for you?
Related questions
- 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
- Why don't dynamic MCP resources (URI templates) appear in Claude Desktop?