-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Exception in ClientSessionGroup if streamable_http MCP server is not available #915
Copy link
Copy link
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
Description
Describe the bug
When I use the ClientSessionGroup for a remote MCP server via remote_http for a remote server that is not running, I get exception RuntimeError: Attempted to exit cancel scope in a different task than it was entered in
(complete output collapsed)
an error occurred during closing of asynchronous generator <async_generator object streamablehttp_client at 0xffffa53755d0>
asyncgen: <async_generator object streamablehttp_client at 0xffffa53755d0>
+ Exception Group Traceback (most recent call last):
| File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__
| raise BaseExceptionGroup(
| "unhandled errors in a TaskGroup", self._exceptions
| ) from None
| BaseExceptionGroup: unhandled errors in a TaskGroup (2 sub-exceptions)
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_transports/default.py", line 101, in map_httpcore_exceptions
| yield
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_transports/default.py", line 394, in handle_async_request
| resp = await self._pool.handle_async_request(req)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py", line 256, in handle_async_request
| raise exc from None
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_async/connection_pool.py", line 236, in handle_async_request
| response = await connection.handle_async_request(
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| pool_request.request
| ^^^^^^^^^^^^^^^^^^^^
| )
| ^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_async/connection.py", line 101, in handle_async_request
| raise exc
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_async/connection.py", line 78, in handle_async_request
| stream = await self._connect(request)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_async/connection.py", line 124, in _connect
| stream = await self._network_backend.connect_tcp(**kwargs)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_backends/auto.py", line 31, in connect_tcp
| return await self._backend.connect_tcp(
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ...<5 lines>...
| )
| ^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_backends/anyio.py", line 113, in connect_tcp
| with map_exceptions(exc_map):
| ~~~~~~~~~~~~~~^^^^^^^^^
| File "/usr/local/lib/python3.13/contextlib.py", line 162, in __exit__
| self.gen.throw(value)
| ~~~~~~~~~~~~~~^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
| raise to_exc(exc) from exc
| httpcore.ConnectError: All connection attempts failed
|
| The above exception was the direct cause of the following exception:
|
| Traceback (most recent call last):
| File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 391, in handle_request_async
| await self._handle_post_request(ctx)
| File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 251, in _handle_post_request
| async with ctx.client.stream(
| ~~~~~~~~~~~~~~~~~^
| "POST",
| ^^^^^^^
| ...<2 lines>...
| headers=headers,
| ^^^^^^^^^^^^^^^^
| ) as response:
| ^
| File "/usr/local/lib/python3.13/contextlib.py", line 214, in __aenter__
| return await anext(self.gen)
| ^^^^^^^^^^^^^^^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_client.py", line 1583, in stream
| response = await self.send(
| ^^^^^^^^^^^^^^^^
| ...<4 lines>...
| )
| ^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_client.py", line 1629, in send
| response = await self._send_handling_auth(
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ...<4 lines>...
| )
| ^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_client.py", line 1657, in _send_handling_auth
| response = await self._send_handling_redirects(
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ...<3 lines>...
| )
| ^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_client.py", line 1694, in _send_handling_redirects
| response = await self._send_single_request(request)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_client.py", line 1730, in _send_single_request
| response = await transport.handle_async_request(request)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_transports/default.py", line 393, in handle_async_request
| with map_httpcore_exceptions():
| ~~~~~~~~~~~~~~~~~~~~~~~^^
| File "/usr/local/lib/python3.13/contextlib.py", line 162, in __exit__
| self.gen.throw(value)
| ~~~~~~~~~~~~~~^^^^^^^
| File "/workspaces/test/.venv/lib/python3.13/site-packages/httpx/_transports/default.py", line 118, in map_httpcore_exceptions
| raise mapped_exc(message) from exc
| httpx.ConnectError: All connection attempts failed
+---------------- 2 ----------------
| Traceback (most recent call last):
| File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 492, in streamablehttp_client
| yield (
| ...<3 lines>...
| )
| GeneratorExit
+------------------------------------
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/streamable_http.py", line 464, in streamablehttp_client
async with anyio.create_task_group() as tg:
~~~~~~~~~~~~~~~~~~~~~~~^^
File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 778, in __aexit__
if self.cancel_scope.__exit__(type(exc), exc, exc.__traceback__):
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 457, in __exit__
raise RuntimeError(
...<2 lines>...
)
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in
Traceback (most recent call last):
File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/streams/memory.py", line 111, in receive
return self.receive_nowait()
~~~~~~~~~~~~~~~~~~~^^
File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/streams/memory.py", line 106, in receive_nowait
raise WouldBlock
anyio.WouldBlock
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/workspaces/test.py", line 14, in <module>
asyncio.run(main())
~~~~~~~~~~~^^^^^^^^
File "/usr/local/lib/python3.13/asyncio/runners.py", line 195, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File "/usr/local/lib/python3.13/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/usr/local/lib/python3.13/asyncio/base_events.py", line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File "/workspaces/test.py", line 10, in main
await client_session_group.connect_to_server(server_params)
File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/session_group.py", line 232, in connect_to_server
server_info, session = await self._establish_session(server_params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/session_group.py", line 267, in _establish_session
result = await session.initialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/client/session.py", line 133, in initialize
result = await self.send_request(
^^^^^^^^^^^^^^^^^^^^^^^^
...<15 lines>...
)
^
File "/workspaces/test/.venv/lib/python3.13/site-packages/mcp/shared/session.py", line 283, in send_request
response_or_error = await response_stream_reader.receive()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/streams/memory.py", line 119, in receive
await receive_event.wait()
File "/workspaces/test/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 1774, in wait
await self._event.wait()
File "/usr/local/lib/python3.13/asyncio/locks.py", line 213, in wait
await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope ffffa51c4050
To Reproduce
I tested this with this script:
import asyncio
from mcp.client.session_group import ClientSessionGroup, StreamableHttpParameters
async def main():
async with ClientSessionGroup() as client_session_group:
server_params = StreamableHttpParameters(url="http://localhost:3001/mcp/")
try:
await client_session_group.connect_to_server(server_params)
except Exception:
print("this is never reached")
if __name__ == "__main__":
asyncio.run(main())Expected behavior
I would like to be able to catch any error that happens during connect_to_server and handle it within my application code - in my case I am using the ClientSessionGroup for multiple MCP servers and want to provide the tools of the running MCP servers to the LLM.
Additional context
- I am using version
1.9.3
Reactions are currently unavailable
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
Type
Projects
Status
To triage