fix(mcp): an abandoned tool call tells the server to stop
`try_call_tool` wrapped `call_tool` in a bare `tokio::time::timeout`. On a timeout or a cancelled turn the future dropped and the server kept working: no `notifications/cancelled` ever left the client. `call_tool_cancel_aware` sends the request through `send_cancellable_request` and holds a guard armed with the request id. A settled call disarms it. A dropped future (cancelled turn) spawns the cancel from the guard's drop. A timeout sends the cancel inline, before returning: the HTTP timeout arm resets the transport next, and dropping the last service handle killed a spawned cancel before it left. The inline send waits 500 ms at most. rmcp 2.2.0 awaits its own timeout-cancel without a bound, and its streamable-HTTP worker awaits each POST in turn, so against a JSON-mode server the cancel queues behind the hung call: with rmcp's timeout path the call returned after 3.0 s against a 1 s budget. That server class cannot receive the cancel until rmcp 3.x; the budget elapses, a warn is logged, and AGENTS.md records the limitation. stdio and SSE-mode servers receive it. Tests: dropped call, timed-out call followed by a service drop, settled call; the HTTP outer-timeout test now asserts the return time. Ported from upstream (grok-build mcp/servers.rs call_tool_cancel_aware, 1.0.33); upstream leans on rmcp 3.2's timeout path.
This commit is contained in:
3 files changed
+267
-29
No files matched your search
@@ -30,6 +30,14 @@ that stops reading still blocks exit-path prints behind std's stderr lock
|
||||
builder re-checks `Path::exists("/data")` and can omit the devbox bind on
|
||||
a stat error that the profile classification treated as present.
|
||||
|
||||
Known limitation left by the 0.1.16 sync: `notifications/cancelled` for a
|
||||
timed-out MCP call cannot reach a streamable-HTTP server that answers
|
||||
`tools/call` with a plain JSON body. rmcp 2.2.0's HTTP worker awaits each
|
||||
POST in turn, so the cancel queues behind the hung call;
|
||||
`servers/cancel_aware.rs` waits 500 ms, warns, and the transport reset
|
||||
then drops the connection. stdio and SSE-mode servers get the cancel.
|
||||
The cure is rmcp 3.x (upstream runs 3.2), a major bump not yet taken.
|
||||
|
||||
## Hard constraints
|
||||
|
||||
- **Zero egress**: only `auth.kimi.com`, `api.kimi.com`, `api.moonshot.cn`,
|
||||
|
||||
Reference in new issue
Block a user