File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -291,13 +291,16 @@ def run(
291291 if transport not in TRANSPORTS .__args__ : # type: ignore # pragma: no cover
292292 raise ValueError (f"Unknown transport: { transport } " )
293293
294- match transport :
295- case "stdio" :
296- anyio .run (self .run_stdio_async )
297- case "sse" : # pragma: no cover
298- anyio .run (lambda : self .run_sse_async (** kwargs ))
299- case "streamable-http" : # pragma: no cover
300- anyio .run (lambda : self .run_streamable_http_async (** kwargs ))
294+ try :
295+ match transport :
296+ case "stdio" :
297+ anyio .run (self .run_stdio_async )
298+ case "sse" : # pragma: no cover
299+ anyio .run (lambda : self .run_sse_async (** kwargs ))
300+ case "streamable-http" : # pragma: no cover
301+ anyio .run (lambda : self .run_streamable_http_async (** kwargs ))
302+ except KeyboardInterrupt :
303+ return
301304
302305 async def _handle_list_tools (
303306 self , ctx : ServerRequestContext [LifespanResultT ], params : PaginatedRequestParams | None
Original file line number Diff line number Diff line change @@ -74,6 +74,14 @@ def test_dependencies(self):
7474 mcp_no_deps = MCPServer ("test" )
7575 assert mcp_no_deps .dependencies == []
7676
77+ def test_stdio_keyboard_interrupt_exits_cleanly (self ):
78+ mcp = MCPServer ("test" )
79+
80+ with patch ("mcp.server.mcpserver.server.anyio.run" , side_effect = KeyboardInterrupt ) as run :
81+ mcp .run ("stdio" )
82+
83+ run .assert_called_once_with (mcp .run_stdio_async )
84+
7785 async def test_sse_app_returns_starlette_app (self ):
7886 """Test that sse_app returns a Starlette application with correct routes."""
7987 mcp = MCPServer ("test" )
You can’t perform that action at this time.
0 commit comments