Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MCP disconnects in asyncio operations #144

Open
alexgoller opened this issue Jan 9, 2025 · 7 comments
Open

MCP disconnects in asyncio operations #144

alexgoller opened this issue Jan 9, 2025 · 7 comments

Comments

@alexgoller
Copy link

alexgoller commented Jan 9, 2025

Describe the bug
After using a tool in my MCP server the server disconnects from Claude Desktop for no visible reason. The tool in question is sending a lot of content (I limit it to stay below 1048576 bytes and have code in my MCP to reduce the input down).

To Reproduce

This will be hard to reproduce. The logs in MCP server log shows:

`
2025-01-09 11:36:02,931 - mcp.server - INFO - Processing request of type CallToolRequest
2025-01-09 11:36:02,931 - mcp.server - DEBUG - Dispatching request of type CallToolRequest
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Handling tool call: get-traffic-flows with arguments: {'start_date': '2024-10-09', 'end_date': '2025-01-09'}
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - ================================================================================
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - GET TRAFFIC FLOWS CALLED
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Arguments received: {
"start_date": "2024-10-09",
"end_date": "2025-01-09"
}
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Start Date: 2024-10-09
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - End Date: 2025-01-09
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Include Sources: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Exclude Sources: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Include Destinations: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Exclude Destinations: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Include Services: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Exclude Services: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Policy Decisions: []
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Exclude Workloads from IP List: True
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Max Results: 10000
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - Query Name: None
2025-01-09 11:36:02,931 - illumio_mcp.server - DEBUG - ================================================================================
2025-01-09 11:36:02,935 - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1)
2025-01-09 11:36:19,766 - illumio_mcp.server - WARNING - Response size exceeds 1MB limit. Truncating to 10000 entries
2025-01-09 11:36:19,779 - illumio_mcp.server - DEBUG - Response size: 2107845 Step down: 0.8
2025-01-09 11:36:19,789 - illumio_mcp.server - DEBUG - Response size: 2107845 Step down: 0.7000000000000001
2025-01-09 11:36:19,799 - illumio_mcp.server - DEBUG - Response size: 2107845 Step down: 0.6000000000000001
2025-01-09 11:36:19,809 - illumio_mcp.server - DEBUG - Response size: 2107845 Step down: 0.5000000000000001
2025-01-09 11:36:19,819 - illumio_mcp.server - DEBUG - Response size: 2107845 Step down: 0.40000000000000013
2025-01-09 11:36:19,829 - illumio_mcp.server - DEBUG - Response size: 2107845 Step down: 0.30000000000000016
2025-01-09 11:36:19,838 - illumio_mcp.server - DEBUG - Response size: 2011229 Step down: 0.20000000000000015
2025-01-09 11:36:19,845 - illumio_mcp.server - DEBUG - Response size: 1340865 Step down: 0.10000000000000014
2025-01-09 11:36:19,848 - illumio_mcp.server - DEBUG - Response size: 670158 Step down: 1.3877787807814457e-16
2025-01-09 11:36:19,870 - mcp.server - DEBUG - Response sent
2025-01-09 11:36:19,875 - mcp.server - DEBUG - Received message: <mcp.shared.session.RequestResponder object at 0x11ab65760>
2025-01-09 11:36:19,875 - mcp.server - INFO - Processing request of type ListResourcesRequest
2025-01-09 11:36:19,875 - mcp.server - DEBUG - Dispatching request of type ListResourcesRequest
2025-01-09 11:36:19,885 - mcp.server - DEBUG - Response sent
2025-01-09 11:36:19,885 - mcp.server - DEBUG - Received message: <mcp.shared.session.RequestResponder object at 0x11c520350>
2025-01-09 11:36:19,885 - mcp.server - INFO - Processing request of type ListResourcesRequest
2025-01-09 11:36:19,885 - mcp.server - DEBUG - Dispatching request of type ListResourcesRequest
Traceback (most recent call last):
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/streams/memory.py", line 242, in send
self.send_nowait(item)
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/streams/memory.py", line 225, in send_nowait
raise WouldBlock
anyio.WouldBlock

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/server/init.py", line 446, in run
await message.respond(response)
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/shared/session.py", line 58, in respond
await self._session._send_response(
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/shared/session.py", line 205, in _send_response
await self._write_stream.send(JSONRPCMessage(jsonrpc_response))
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/streams/memory.py", line 248, in send
await send_event.wait()
File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1747, in wait
await self._event.wait()
File "/Users/alex.goller/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/locks.py", line 212, in wait
await fut
asyncio.exceptions.CancelledError: Cancelled by cancel scope 11c8f0740

During handling of the above exception, another exception occurred:

  • Exception Group Traceback (most recent call last):
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/server/stdio.py", line 83, in stdio_server
    | yield read_stream, write_stream
    | File "/Users/alex.goller/git/illumio-mcp/src/illumio_mcp/server.py", line 2304, in main
    | await server.run(
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/server/init.py", line 404, in run
    | async with ServerSession(
    | ^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/shared/session.py", line 122, in aexit
    | return await self._task_group.aexit(exc_type, exc_val, exc_tb)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 763, in aexit
    | raise BaseExceptionGroup(
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/shared/session.py", line 235, in _receive_loop
    | notification = self._receive_notification_type.model_validate(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/pydantic/main.py", line 627, in model_validate
    | return cls.pydantic_validator.validate_python(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | pydantic_core._pydantic_core.ValidationError: 5 validation errors for ClientNotification
    ProgressNotification.method
    Input should be 'notifications/progress' [type=literal_error, input_value='cancelled', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/literal_error
    ProgressNotification.params.progressToken
    Field required [type=missing, input_value={'requestId': 15, 'reason... -2: Request timed out'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing
    ProgressNotification.params.progress
    Field required [type=missing, input_value={'requestId': 15, 'reason... -2: Request timed out'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing
    InitializedNotification.method
    Input should be 'notifications/initialized' [type=literal_error, input_value='cancelled', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/literal_error
    RootsListChangedNotification.method
    Input should be 'notifications/roots/list_changed' [type=literal_error, input_value='cancelled', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/literal_error
    +------------------------------------

During handling of the above exception, another exception occurred:

  • Exception Group Traceback (most recent call last):
    | File "/Users/alex.goller/git/illumio-mcp/.venv/bin/illumio-mcp", line 8, in
    | sys.exit(main())
    | ^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/src/illumio_mcp/init.py", line 6, in main
    | asyncio.run(server.main())
    | File "/Users/alex.goller/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/runners.py", line 194, in run
    | return runner.run(main)
    | ^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/runners.py", line 118, in run
    | return self._loop.run_until_complete(task)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    | return future.result()
    | ^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/src/illumio_mcp/server.py", line 2303, in main
    | async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/.local/share/uv/python/cpython-3.12.7-macos-aarch64-none/lib/python3.12/contextlib.py", line 231, in aexit
    | await self.gen.athrow(value)
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/server/stdio.py", line 80, in stdio_server
    | async with anyio.create_task_group() as tg:
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 763, in aexit
    | raise BaseExceptionGroup(
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
    | Exception Group Traceback (most recent call last):
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/server/stdio.py", line 83, in stdio_server
    | yield read_stream, write_stream
    | File "/Users/alex.goller/git/illumio-mcp/src/illumio_mcp/server.py", line 2304, in main
    | await server.run(
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/server/init.py", line 404, in run
    | async with ServerSession(
    | ^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/shared/session.py", line 122, in aexit
    | return await self._task_group.aexit(exc_type, exc_val, exc_tb)
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 763, in aexit
    | raise BaseExceptionGroup(
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/mcp/shared/session.py", line 235, in _receive_loop
    | notification = self._receive_notification_type.model_validate(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | File "/Users/alex.goller/git/illumio-mcp/.venv/lib/python3.12/site-packages/pydantic/main.py", line 627, in model_validate
    | return cls.pydantic_validator.validate_python(
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | pydantic_core._pydantic_core.ValidationError: 5 validation errors for ClientNotification
    ProgressNotification.method
    Input should be 'notifications/progress' [type=literal_error, input_value='cancelled', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/literal_error
    ProgressNotification.params.progressToken
    Field required [type=missing, input_value={'requestId': 15, 'reason... -2: Request timed out'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing
    ProgressNotification.params.progress
    Field required [type=missing, input_value={'requestId': 15, 'reason... -2: Request timed out'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.10/v/missing
    InitializedNotification.method
    Input should be 'notifications/initialized' [type=literal_error, input_value='cancelled', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/literal_error
    RootsListChangedNotification.method
    Input should be 'notifications/roots/list_changed' [type=literal_error, input_value='cancelled', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/literal_error
    +------------------------------------
    `

Expected behavior
Do not disconnect

Screenshots

Desktop (please complete the following information):

  • OS: OSX, Claude Desktop 0.7.8
  • MCP version 1.2.0
  • Python 3.12.7
@robertgates-duco
Copy link

Same issue for me - also MCP 1.2.0

@alexgoller
Copy link
Author

It looks like there is no such notification in types.py, not sure what to make of it. The Typescript SDK defines the cancellation message in types.ts.

@alexgoller
Copy link
Author

Duplicate of #88

@alexgoller
Copy link
Author

Fixed this by adding a CancelledNotification. It likely is not handle, but will solve the disconnect.

@robertgates55
Copy link

Where did you add the notification to resolve/work around please?

@alexgoller
Copy link
Author

alexgoller commented Jan 13, 2025

@robertgates55 my fix looks exactly like: Fix which I found later.

--- types.py	2025-01-13 07:56:14
+++ types.py.new	2025-01-13 07:57:36
@@ -333,6 +333,15 @@

     method: Literal["notifications/progress"]
     params: ProgressNotificationParams
+
+class CancelledNotificationParams(NotificationParams):
+    """Parameters for Cancel notification"""
+    # requestId: int
+    reason: str | None = None
+
+class CancelledNotification(Notification):
+    method: Literal["cancelled"]
+    params: CancelledNotificationParams


 class ListResourcesRequest(PaginatedRequest):
@@ -997,7 +1006,7 @@

 class ClientNotification(
     RootModel[
-        ProgressNotification | InitializedNotification | RootsListChangedNotification
+        ProgressNotification | InitializedNotification | RootsListChangedNotification | CancelledNotificationParams
     ]
 ):
     pass
@@ -1019,6 +1028,7 @@
         | ResourceListChangedNotification
         | ToolListChangedNotification
         | PromptListChangedNotification
+        | CancelledNotification
     ]
 ):
     pass

@robertgates55
Copy link

Aha. Thanks.

What's actually going on here then - is Claude giving up on the mcp call as it's been waiting too long, sending a 'cancelled' and then the server crashes?

In my case the call was actually returning correctly, just after a little longer than Claude wants to wait for - but the next call would then fail as the server has disconnected.

Do we need to add progress notifications for longer operations maybe?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants