Skip to content

tokio task not closed at shutdown #220

Open
@3DRaven

Description

@3DRaven

Describe the bug
When performing a graceful shutdown with a Tokio cancellation token, the task that reads from stdin does not terminate properly, causing the process to remain running.

To Reproduce

  1. Attached full project example with the problem. mcp-problem-example.zip
  2. Add integration with this MCP server to MCP inspector or cursor IDE with stdio transport.
    As example integration with cursor IDE
{
  "mcpServers": {
    "mcp-problem-example": {
      "command": "sh",
      "args": [
        "path/to/mcp-problem-example/start.sh"
      ],
      "env": []
    },
}
  1. Run in terminal tokio-console https://crates.io/crates/tokio-console
  2. Disconnect/Turn off from the MCP server in client (IDE or inspector)

Expected behavior
After stopping the MCP server, the process should be terminated.

Logs
All code has finished executing, but the task remains unclosed.

2025-05-25T13:24:17.338Z  INFO mcp_problem_example: Tracing initialized successfully
2025-05-25T13:24:17.338Z  INFO mcp_problem_example: Starting server in work directory: example/mcp-problem-example    
2025-05-25T13:24:17.340Z  INFO runtime.spawn{kind=task task.name= task.id=24 size.bytes=1336 loc.file="src/main.rs" loc.line=17 loc.col=11}: mcp_problem_example: Starting MCP service
2025-05-25T13:24:17.341Z  INFO runtime.spawn{kind=task task.name= task.id=24 size.bytes=1336 loc.file="src/main.rs" loc.line=17 loc.col=11}:serve_inner: rmcp::service: Service initialized as server peer_info=InitializeRequestParam { protocol_version: ProtocolVersion("2024-11-05"), capabilities: ClientCapabilities { experimental: None, roots: Some(RootsCapabilities { list_changed: Some(false) }), sampling: None }, client_info: Implementation { name: "cursor-vscode", version: "1.0.0" } }
2025-05-25T13:24:17.342Z  INFO runtime.spawn{kind=task task.name= task.id=24 size.bytes=1336 loc.file="src/main.rs" loc.line=17 loc.col=11}: mcp_problem_example: MCP server initialized
2025-05-25T13:24:17.342Z DEBUG runtime.spawn{kind=task task.name= task.id=30 size.bytes=928 loc.file="/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.1.5/src/service.rs" loc.line=495 loc.col=18}: rmcp::service: new event evt=PeerMessage(Request(ListToolsRequest(Request { method: ListToolsRequestMethod, params: None }), Number(1)))
2025-05-25T13:24:17.342Z  INFO runtime.spawn{kind=task task.name= task.id=30 size.bytes=928 loc.file="/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.1.5/src/service.rs" loc.line=495 loc.col=18}: rmcp::service: received request id=1 request=ListToolsRequest(Request { method: ListToolsRequestMethod, params: None })
2025-05-25T13:24:17.343Z  INFO runtime.spawn{kind=task task.name= task.id=32 size.bytes=1168 loc.file="/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.1.5/src/service.rs" loc.line=604 loc.col=25}: rmcp::service: response message id=1 result=ListToolsResult(ListToolsResult { next_cursor: None, tools: [Tool { name: "search_implemented", description: "Search for implemented symbols in the project", input_schema: {"$schema": String("http://json-schema.org/draft-07/schema#"), "properties": Object {"first": Object {"items": Object {"type": String("string")}, "type": String("array")}, "second": Object {"items": Object {"type": String("string")}, "type": String("array")}}, "required": Array [String("first"), String("second")], "title": String("McpRequest"), "type": String("object")} }] })
2025-05-25T13:24:17.344Z DEBUG runtime.spawn{kind=task task.name= task.id=30 size.bytes=928 loc.file="~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.1.5/src/service.rs" loc.line=495 loc.col=18}: rmcp::service: new event evt=ToSink(Response(ListToolsResult(ListToolsResult { next_cursor: None, tools: [Tool { name: "search_implemented", description: "Search for implemented symbols in the project", input_schema: {"$schema": String("http://json-schema.org/draft-07/schema#"), "properties": Object {"first": Object {"items": Object {"type": String("string")}, "type": String("array")}, "second": Object {"items": Object {"type": String("string")}, "type": String("array")}}, "required": Array [String("first"), String("second")], "title": String("McpRequest"), "type": String("object")} }] }), Number(1)))
2025-05-25T13:24:30.801Z DEBUG runtime.spawn{kind=task task.name= task.id=23 size.bytes=160 loc.file="src/main.rs" loc.line=21 loc.col=6}: tokio_graceful_shutdown::signal_handling: Received SIGTERM.
2025-05-25T13:24:30.802Z  INFO tokio_graceful_shutdown::toplevel: Shutting down ...
2025-05-25T13:24:30.802Z  INFO runtime.spawn{kind=task task.name= task.id=30 size.bytes=928 loc.file="~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.1.5/src/service.rs" loc.line=495 loc.col=18}: rmcp::service: task cancelled
2025-05-25T13:24:30.802Z  INFO runtime.spawn{kind=task task.name= task.id=30 size.bytes=928 loc.file="~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rmcp-0.1.5/src/service.rs" loc.line=495 loc.col=18}: rmcp::service: serve finished quit_reason=Cancelled
2025-05-25T13:24:30.802Z  INFO runtime.spawn{kind=task task.name= task.id=24 size.bytes=1336 loc.file="src/main.rs" loc.line=17 loc.col=11}: mcp_problem_example: MCP server shutdown with reason: Cancelled
2025-05-25T13:24:30.803Z  INFO tokio_graceful_shutdown::toplevel: Shutdown finished.
2025-05-25T13:24:30.803Z  INFO mcp_problem_example: Finall message    

Final message indicates the last log entry generated by the logger.

Additional context
The previous process is not terminated properly, so each rerun spawns an additional process that continues running in the background:

ps -A|grep mcp
 880290 ?        00:00:00 mcp-problem-exa
 889850 ?        00:00:00 mcp-problem-exa

tokio-console shows the issue — a task is not properly terminated.:

30 ⏫            8m15s    2ms  8m02s    13s 6     task     <cargo>/rmcp-0.1.5/src/service.rs:495:18      size.bytes=928 target=tokio::task                       │
33 ▶             8m15s  8m15s    0ns  131µs 1     blocking <cargo>/tokio-1.45.1/src/io/blocking.rs:76:46 fn=<tokio::io::blocking::Blocking<std::io::stdio::Stdin>

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions