Skip to content

Runtime Error when running mcp server #5

@dpeet

Description

@dpeet

Hey @elusznik! I saw this cool server and have been looking for a way to cut down the ridiculous mcp token bloat, especially from chrome dev tools. I got it installed but ran into the error below. I had claude generate an issue for me, is there anything else you need to help fix it?

RuntimeError with anyio cancel scopes on Python 3.14

Description

When using mcp-server-code-execution-mode with Python 3.14 and attempting to proxy an MCP server (e.g., mcp-server-time), the server crashes with a RuntimeError related to anyio cancel scope management.

The server works fine for basic run_python calls (including runtime.capability_summary() and standard library code), but crashes when attempting to load/proxy another MCP server via the servers=["time"] parameter.

Environment

Component Version
OS Ubuntu 22.04.5 LTS
Kernel 5.19.0-051900-generic x86_64
Python (via uvx) 3.14.0
uv 0.9.11
mcp-server-code-execution-mode 1.22.0 (from git main)
mcp 1.22.0
anyio 4.11.0
pydantic 2.12.4
pydantic_core 2.41.5
Docker 29.0.2
Claude Code CLI 2.0.53

Configuration

Claude Code MCP config (~/.claude.json):

{
  "type": "stdio",
  "command": "uvx",
  "args": [
    "--python",
    "3.14",
    "--from",
    "git+https://github.com/elusznik/mcp-server-code-execution-mode",
    "mcp-server-code-execution-mode",
    "run"
  ],
  "env": {
    "MCP_BRIDGE_RUNTIME": "docker",
    "MCP_SERVERS_CONFIG": "/path/to/mcp-servers.json"
  }
}

Proxied servers config (mcp-servers.json):

{
  "mcpServers": {
    "time": {
      "command": "uvx",
      "args": ["mcp-server-time"],
      "env": {},
      "description": "Timezone utilities - get current time, convert timezones"
    }
  }
}

Steps to Reproduce

  1. Configure mcp-server-code-execution-mode with Python 3.14 as shown above
  2. Configure at least one proxied MCP server (e.g., mcp-server-time)
  3. Start a Claude Code session
  4. Run a basic command that works:
    use run python to ask time to get the current time
    
  5. Attempt to use a proxied server:
    # This triggers the crash
    # (passed servers=["time"] parameter to run_python)

Expected Behavior

The server should successfully load the proxied time MCP server and allow calling its tools.

Actual Behavior

The server crashes with nested ExceptionGroup errors after loading the proxied server:

INFO:mcp-server-code-execution-mode:Loaded MCP server time

Then approximately 2-3 minutes later (possibly during cleanup/timeout):

RuntimeError: Attempted to exit a cancel scope that isn't the current tasks's current cancel scope

Full Stack Trace

ERROR:root:Fatal error in main loop
  + Exception Group Traceback (most recent call last):
  |   File ".../mcp_server_code_execution_mode.py", line 2633, in main
  |     async with stdio_server() as (read_stream, write_stream):
  |   File ".../contextlib.py", line 235, in __aexit__
  |     await self.gen.athrow(value)
  |   File ".../mcp/server/stdio.py", line 85, in stdio_server
  |     async with anyio.create_task_group() as tg:
  |   File ".../anyio/_backends/_asyncio.py", line 781, in __aexit__
  |     raise BaseExceptionGroup(
  |         "unhandled errors in a TaskGroup", self._exceptions
  |     ) from None
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Exception Group Traceback (most recent call last):
    |   File ".../mcp/server/stdio.py", line 88, in stdio_server
    |     yield read_stream, write_stream
    |   File ".../mcp_server_code_execution_mode.py", line 2634, in main
    |     await app.run(
    |         read_stream, write_stream, app.create_initialization_options()
    |     )
    |   File ".../mcp/server/lowlevel/server.py", line 616, in run
    |     async with AsyncExitStack() as stack:
    |   File ".../contextlib.py", line 768, in __aexit__
    |     raise exc
    |   File ".../contextlib.py", line 751, in __aexit__
    |     cb_suppress = await cb(*exc_details)
    |   File ".../mcp/shared/session.py", line 220, in __aexit__
    |     return await self._task_group.__aexit__(exc_type, exc_val, exc_tb)
    |   File ".../anyio/_backends/_asyncio.py", line 781, in __aexit__
    |     raise BaseExceptionGroup(
    |         "unhandled errors in a TaskGroup", self._exceptions
    |     ) from None
    | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
    +-+---------------- 1 ----------------
      | Exception Group Traceback (most recent call last):
      |   File ".../mcp/server/lowlevel/server.py", line 627, in run
      |     async with anyio.create_task_group() as tg:
      |   File ".../anyio/_backends/_asyncio.py", line 781, in __aexit__
      |     raise BaseExceptionGroup(
      |         "unhandled errors in a TaskGroup", self._exceptions
      |     ) from None
      | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
      +-+---------------- 1 ----------------
        | Traceback (most recent call last):
        |   File ".../mcp_server_code_execution_mode.py", line 2482, in _patched_handle_message
        |     return await _orig_handle_message(
        |         self, message, session, lifespan_context, raise_exceptions
        |     )
        |   File ".../mcp/server/lowlevel/server.py", line 649, in _handle_message
        |     with responder:
        |   File ".../mcp/shared/session.py", line 116, in __exit__
        |     self._cancel_scope.__exit__(exc_type, exc_val, exc_tb)
        |   File ".../anyio/_backends/_asyncio.py", line 467, in __exit__
        |     raise RuntimeError(
        |     ...
        |     )
        | RuntimeError: Attempted to exit a cancel scope that isn't the current tasks's current cancel scope
        +------------------------------------

Additional error during cleanup:

ERROR:asyncio:an error occurred during closing of asynchronous generator <async_generator object stdio_client at 0x...>
...
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in

Analysis

This appears to be a Python 3.14 + anyio compatibility issue. Python 3.14 introduced changes to asyncio's task cancellation semantics that may conflict with how anyio manages cancel scopes.

The issue specifically occurs in mcp/shared/session.py:116 when the RequestResponder.__exit__ method tries to exit its cancel scope, but the scope is being exited from a different task than it was entered in.


Note: This issue was generated with assistance from Claude Code (Opus 4.5) based on log analysis

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions