Skip to content

FastMCP.run(transport="stdio") produces noisy traceback on KeyboardInterrupt instead of clean exit #2663

Description

@MikeNjoroge

Initial Checks

Description

Running a FastMCP stdio server from the terminal and interrupting with Ctrl-C produces a multi-frame traceback through anyio.run() → asyncio.runners → mcp.server.lowlevel.server.run → anyio.streams.memory.receive. The server is correctly waiting on stdin in an async loop; the trace surfaces because anyio/asyncio don't suppress the cancellation chain. Suggested fix: catch KeyboardInterrupt (or asyncio.CancelledError at the outer boundary) inside FastMCP.run and exit cleanly. Cosmetic but reduces user confusion when testing MCP servers from the terminal.

Example Code

Python & MCP Python SDK

Python 3.13.5
MCP Python SDK 1.27.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Nice to haves, rare edge casesbugSomething isn't workingfix proposedBot has a verified fix diff in the commentready for workEnough information for someone to start working on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions