[BUG] Claude Desktop: chat-initiated tools/call never reaches a healthy local MCP (stdio) server
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Report finalized at scratchpad/claude-desktop-mcp-bug.md. Yes — the Desktop version is included: 1.24012.1 (in the Environment table). Here is the full
text to paste into a GitHub issue:
---
Claude Desktop: chat-initiated tools/call never reaches a healthy local MCP (stdio) server
Summary
Chat-triggered tool invocations against a local stdio MCP server (filesystem) fail every time with a bare "Tool execution failed". The Desktop app
completes the initialize + tools/list handshake with the server on every launch, but no tools/call line ever appears in ~/Library/Logs/Claude/mcp.log for a
chat-triggered call. The request is dropped app-side, before it reaches the server's stdio. The server itself is proven healthy in isolation.
Environment
┌──────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Component │ Version │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Claude Desktop │ 1.24012.1 (build 1.24012.1) │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ macOS │ 15.7.7 (24G720) │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Hardware │ Apple Silicon (M3), arm64 │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Node (server │ v26.5.0 (Homebrew) │
│ runtime) │ │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MCP server │ @modelcontextprotocol/server-filesystem@2026.7.10 │
│ package │ │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Server binary │ /opt/homebrew/bin/mcp-server-filesystem → …/lib/node_modules/@modelcontextprotocol/server-filesystem/dist/index.js (npm global, │
│ │ #!/usr/bin/env node ESM script) │
└──────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Server config (both as a manual mcpServers entry and, later, as a UI-managed Desktop extension):
"filesystem": {
"command": "/opt/homebrew/bin/mcp-server-filesystem",
"args": ["/Users/<user>/PycharmProjects"]
}
Symptom (precise)
- Every app launch, the server lifecycle in mcp.log is:
Initializing server...
Using MCP server command: /opt/homebrew/bin/mcp-server-filesystem
Server started and connected successfully
client → method="initialize" id=0 → server id=0 result
client → method="notifications/initialized"
client → method="tools/list" id=1 → server id=1 result
⟵ then idle. No further lines.
- When a chat asks for a filesystem operation, the UI shows "Tool execution failed" and mcp.log gains no new line at that timestamp — not a tools/call, not
an error. The invocation never leaves the app for the server.
- The last real tools/call reaching this server in the logs was 2026-06-24; every attempt since fails this way.
Server is proven healthy (isolation test)
Drove the exact same binary + args directly over stdio from a standalone Python script (no Claude Desktop involved): sent initialize →
notifications/initialized → tools/list → tools/call (list_directory).
Result:
initialize : OK
tools/list : OK (15 tools)
tools/call : OK — real directory listing returned
process exit code: 0
stderr: "Secure MCP Filesystem Server running on stdio"
The server accepts and correctly executes tools/call. The fault is not in the server, its Node runtime, its arguments, or filesystem access.
Everything ruled out (each verified with NO change to the failure)
- Full app quit + relaunch — clean handshake re-established; tools/call still never reaches the server.
- Node upgrade 25.9 → 26.5 (old runtime removed by brew cleanup) — the live server processes were confirmed spawned against the current, existing Node
26.5.0; not an orphaned-runtime problem.
- Removing remoteToolsDeviceName from config (bridge device m3-macbook-pro-local) — no change. Note: the app re-serializes this key back into the config
on next launch, so a config-file removal is not durable.
- Full account sign-out / sign-in — no change.
- Removing the manual mcpServers entry entirely and re-adding filesystem as a UI-managed Desktop extension — fails identically whether configured as a
manual mcpServers entry or as a managed extension.
Additional observations:
- Two identical server instances are spawned on every launch (each node …/mcp-server-filesystem under a disclaimer helper → main Claude process), i.e. two
independent hosts hold their own copy of the server — consistent with a local app path plus a remote-tools/desktop-connector bridge. The duplication is
structural (survives restart), not a stale leftover.
- Some earlier crash cycles showed the server being spawned via /opt/homebrew/bin/npx (dying with "transport closed unexpectedly … process exiting early");
those predated the config being finalized to the direct binary path and are not the current failure mode. The current handshake is clean.
Conclusion
The fault is in Claude Desktop's routing between a chat session and a local/desktop connector. tools/list reaches the server (tools are enumerated and
shown), but chat-issued tools/call invocations are dropped inside the app before they are written to the server's stdin. This is independent of the server,
its runtime, its arguments, the config style (manual vs. managed extension), the account session, and the remoteToolsDeviceName bridge device — none of
which changed the behavior.
Reproduction
- Configure any stdio MCP server (e.g. @modelcontextprotocol/server-filesystem) in Claude Desktop, manually or as an extension.
- Observe successful initialize + tools/list in ~/Library/Logs/Claude/mcp.log.
- In a chat, request an operation that calls one of its tools.
- Observe "Tool execution failed" in the UI and no tools/call line appearing in mcp.log.
- Confirm the server is healthy by driving the same binary/args over stdio directly (isolation script) — tools/call succeeds there.
---
One small note for accuracy before you file: the report states the config-based removal of remoteToolsDeviceName isn't durable because the app
re-serializes it on launch — that's a directly observed fact from this session, and it's worth keeping in the issue since it tells the maintainers the
bridge device can't be disabled from the config file. If you'd like, I can also attach the isolation Python script (scratchpad/mcp_isolation_test.py) as a
reproducible artifact reviewers can run.
✻ Cogitated for 1m 8s
What Should Happen?
The MCP Server should work
Error Messages/Logs
Steps to Reproduce
Report finalized at scratchpad/claude-desktop-mcp-bug.md. Yes — the Desktop version is included: 1.24012.1 (in the Environment table). Here is the full
text to paste into a GitHub issue:
---
Claude Desktop: chat-initiated tools/call never reaches a healthy local MCP (stdio) server
Summary
Chat-triggered tool invocations against a local stdio MCP server (filesystem) fail every time with a bare "Tool execution failed". The Desktop app
completes the initialize + tools/list handshake with the server on every launch, but no tools/call line ever appears in ~/Library/Logs/Claude/mcp.log for a
chat-triggered call. The request is dropped app-side, before it reaches the server's stdio. The server itself is proven healthy in isolation.
Environment
┌──────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Component │ Version │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Claude Desktop │ 1.24012.1 (build 1.24012.1) │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ macOS │ 15.7.7 (24G720) │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Hardware │ Apple Silicon (M3), arm64 │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Node (server │ v26.5.0 (Homebrew) │
│ runtime) │ │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ MCP server │ @modelcontextprotocol/server-filesystem@2026.7.10 │
│ package │ │
├──────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Server binary │ /opt/homebrew/bin/mcp-server-filesystem → …/lib/node_modules/@modelcontextprotocol/server-filesystem/dist/index.js (npm global, │
│ │ #!/usr/bin/env node ESM script) │
└──────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Server config (both as a manual mcpServers entry and, later, as a UI-managed Desktop extension):
"filesystem": {
"command": "/opt/homebrew/bin/mcp-server-filesystem",
"args": ["/Users/<user>/PycharmProjects"]
}
Symptom (precise)
- Every app launch, the server lifecycle in mcp.log is:
Initializing server...
Using MCP server command: /opt/homebrew/bin/mcp-server-filesystem
Server started and connected successfully
client → method="initialize" id=0 → server id=0 result
client → method="notifications/initialized"
client → method="tools/list" id=1 → server id=1 result
⟵ then idle. No further lines.
- When a chat asks for a filesystem operation, the UI shows "Tool execution failed" and mcp.log gains no new line at that timestamp — not a tools/call, not
an error. The invocation never leaves the app for the server.
- The last real tools/call reaching this server in the logs was 2026-06-24; every attempt since fails this way.
Server is proven healthy (isolation test)
Drove the exact same binary + args directly over stdio from a standalone Python script (no Claude Desktop involved): sent initialize →
notifications/initialized → tools/list → tools/call (list_directory).
Result:
initialize : OK
tools/list : OK (15 tools)
tools/call : OK — real directory listing returned
process exit code: 0
stderr: "Secure MCP Filesystem Server running on stdio"
The server accepts and correctly executes tools/call. The fault is not in the server, its Node runtime, its arguments, or filesystem access.
Everything ruled out (each verified with NO change to the failure)
- Full app quit + relaunch — clean handshake re-established; tools/call still never reaches the server.
- Node upgrade 25.9 → 26.5 (old runtime removed by brew cleanup) — the live server processes were confirmed spawned against the current, existing Node
26.5.0; not an orphaned-runtime problem.
- Removing remoteToolsDeviceName from config (bridge device m3-macbook-pro-local) — no change. Note: the app re-serializes this key back into the config
on next launch, so a config-file removal is not durable.
- Full account sign-out / sign-in — no change.
- Removing the manual mcpServers entry entirely and re-adding filesystem as a UI-managed Desktop extension — fails identically whether configured as a
manual mcpServers entry or as a managed extension.
Additional observations:
- Two identical server instances are spawned on every launch (each node …/mcp-server-filesystem under a disclaimer helper → main Claude process), i.e. two
independent hosts hold their own copy of the server — consistent with a local app path plus a remote-tools/desktop-connector bridge. The duplication is
structural (survives restart), not a stale leftover.
- Some earlier crash cycles showed the server being spawned via /opt/homebrew/bin/npx (dying with "transport closed unexpectedly … process exiting early");
those predated the config being finalized to the direct binary path and are not the current failure mode. The current handshake is clean.
Conclusion
The fault is in Claude Desktop's routing between a chat session and a local/desktop connector. tools/list reaches the server (tools are enumerated and
shown), but chat-issued tools/call invocations are dropped inside the app before they are written to the server's stdin. This is independent of the server,
its runtime, its arguments, the config style (manual vs. managed extension), the account session, and the remoteToolsDeviceName bridge device — none of
which changed the behavior.
Reproduction
- Configure any stdio MCP server (e.g. @modelcontextprotocol/server-filesystem) in Claude Desktop, manually or as an extension.
- Observe successful initialize + tools/list in ~/Library/Logs/Claude/mcp.log.
- In a chat, request an operation that calls one of its tools.
- Observe "Tool execution failed" in the UI and no tools/call line appearing in mcp.log.
- Confirm the server is healthy by driving the same binary/args over stdio directly (isolation script) — tools/call succeeds there.
---
One small note for accuracy before you file: the report states the config-based removal of remoteToolsDeviceName isn't durable because the app
re-serializes it on launch — that's a directly observed fact from this session, and it's worth keeping in the issue since it tells the maintainers the
bridge device can't be disabled from the config file. If you'd like, I can also attach the isolation Python script (scratchpad/mcp_isolation_test.py) as a
reproducible artifact reviewers can run.
✻ Cogitated for 1m 8s
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
1.24012.1
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗