Desktop: MCP Apps bridge drops in-flight local-MCP tool calls bidirectionally on 'oncalltool handler replaced' (4-min timeouts on sub-50ms completed calls)
Summary
Claude Desktop's local-MCP bridge ("MCP Apps" in its own logs) loses in-flight tool calls in both directions — requests silently dropped before reaching the server, and responses silently dropped after the server completes — causing 4-minute client timeouts on calls the server finished in milliseconds. Evidence points to a last-writer-wins singleton oncalltool handler registration that orphans in-flight calls whenever the handler is re-registered, which under real multi-conversation usage happens constantly (2,213 occurrences of the replacement warning in a single claude.ai-web.log).
This is not a server-side issue: the stdio MCP server involved logs every completion, and every "timed-out" call that reached it completed in <50ms.
Environment
- Claude Desktop 1.24012.1, macOS 26.5.2 (Apple Silicon)
- Local stdio MCP server (Node 26, TypeScript,
@modelcontextprotocol/sdk), file-backed knowledge base with git audit trail (every write produces a commit — which is what made these incidents provable) - Heavy multi-session usage: Chat + Cowork + multiple concurrent conversations calling the same local MCP server
Symptoms
Tool calls (reads and writes, any tool) intermittently hang for exactly ~4 minutes, then fail with:
"No result received from the Claude Desktop app after waiting 4 minutes. The local MCP server providing this tool may be unresponsive, crashed, or not running."
The server is in fact healthy. Failures are bursty (2–3 consecutive calls fail, then spontaneous recovery), and worsen with more concurrent conversations.
Evidence
1. Server completes; client never hears (response-side loss). Multiple confirmed incidents where a "timed-out" write had actually committed to the KB's git repo within seconds of dispatch (commit timestamps match the call time). Server-side per-call completion logging shows e.g.:
[kb-response] kb_update_topic 49ms ok
[kb-response] kb_recent_activity 30ms ok
[kb-response] kb_read_topic 1ms ok
No slow calls, no errors — ever — while clients simultaneously reported 4-minute timeouts on these same tools.
2. Request never arrives (request-side loss). Other timeout incidents where NO corresponding git commit and NO server-side completion log exists — the call was dropped before reaching the server. Both loss modes observed in the same session.
3. The bridge logs its own defect. claude.ai-web.log contains storms of:
2026-07-13 11:45:36 [warn] [MCP Apps] oncalltool handler replaced. Previous handler will no longer be called.
2026-07-13 11:45:39 [warn] [MCP Apps] oncalltool handler replaced. Previous handler will no longer be called.
(× 2,213 total in one log file; bursts of 10+/minute during active multi-conversation use)
Timeout incidents correlate with these bursts. The message says it plainly: any tool result destined for the "previous handler" is discarded.
4. Real cost beyond the hang. Agents that can't learn whether a write succeeded retry it — producing duplicate entries in the data store. We had to build idempotency guards and a "verify-before-retry" protocol into our server purely to defend against this bridge behavior.
Hypothesis
In-flight tool calls appear to be correlated to the handler instance live at dispatch time rather than to a persistent per-request routing table. When any conversation/window (re)mounts its MCP context, it re-registers the singleton handler; calls in flight under the previous handler are orphaned (response-side loss), and calls dispatched during a swap are dropped (request-side loss). Concurrent conversations thrash the registration continuously, which matches the burstiness, the call-agnosticism, the spontaneous recovery when a conversation goes idle, and the 2,213-replacement count.
The bridge already has per-call identity (toolId appears in tool_approval_gate log entries) — routing results by toolId through a dispatcher that survives handler re-registration (and queuing during transitions instead of dropping) would fix both directions.
Reproduction suggestion
Run two or more concurrent Desktop conversations that both call tools on the same local stdio MCP server (long-running session, tools called every few minutes). Watch claude.ai-web.log for oncalltool handler replaced bursts and correlate with client-side tool-call timeouts whose server (instrumented to log completions) shows fast, successful completion.
Happy to provide fuller log excerpts or run instrumented builds — this reproduces regularly under our workload.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗