[BUG] Claude Desktop (Linux): MCP server tools nondeterministically unavailable despite successful protocol handshake
<html><head></head><body><h1>[BUG] Claude Desktop: MCP tools nondeterministically unavailable despite successful handshake (Linux)</h1>
<h2>Preflight Checklist</h2>
<ul>
<li>[x] I have searched existing issues and this hasn't been reported yet</li>
<li>[x] This is a single bug report (please file separate reports for different bugs)</li>
<li>[x] I am using the latest version of Claude Code</li>
</ul>
<h2>Bug Description</h2>
<p>Claude Desktop on Linux nondeterministically fails to expose MCP server tools to the model, despite all servers completing the full MCP protocol handshake successfully. 5 MCP servers are configured; all 5 show "running" in the UI; all 5 complete initialize/tools_list/prompts_list/resources_list exchanges with zero errors. Only a random subset of 2-3 servers' tools are actually available to the model in any given session. The failing subset changes on each restart.</p>
<p>This is NOT a server-side issue. Server logs prove the complete handshake succeeds. The bug is in the desktop app's internal pipeline between "received tool registrations from MCP server" and "made tools available to the model."</p>
<h2>Environment</h2>
<ul>
<li><strong>Claude Desktop</strong>: Linux (Ubuntu), latest version</li>
<li><strong>Platform</strong>: Linux x86_64</li>
<li><strong>MCP Servers</strong>: 5 configured (filesystem, github, kubernetes, notion, terraform)</li>
<li><strong>MCP Server binaries</strong>: Linuxbrew-installed Go binaries + Docker container</li>
<li><strong>Claude Code</strong>: 2.1.22 (does NOT exhibit this bug with same servers)</li>
</ul>
<h2>Configuration</h2>
<p><code>~/.config/claude-desktop/claude_desktop_config.json</code>:</p>
<pre><code class="language-json">{
"mcpServers": {
"filesystem": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--volume=/home/marc-mercer/work/:/work",
"ghcr.io/mark3labs/mcp-filesystem-server:latest",
"/work"
]
},
"github": {
"command": "/home/linuxbrew/.linuxbrew/bin/github-mcp-server",
"args": ["stdio"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "<redacted>"
}
},
"kubernetes": {
"command": "/home/linuxbrew/.linuxbrew/bin/kubernetes-mcp-server",
"args": ["--read-only", "--kubeconfig", "/home/marc-mercer/.kube/config"]
},
"notion": {
"command": "/home/linuxbrew/.linuxbrew/bin/notion-mcp-server",
"args": [],
"env": {
"NOTION_TOKEN": "<redacted>"
}
},
"terraform": {
"command": "/home/linuxbrew/.linuxbrew/bin/terraform-mcp-server",
"args": ["stdio"]
}
}
}
</code></pre>
<h2>Reproduction Steps</h2>
<ol>
<li>Configure 5 MCP servers as above in Claude Desktop on Linux</li>
<li>Launch Claude Desktop</li>
<li>Observe all 5 servers show "running" in the MCP status UI</li>
<li>Start a conversation and ask Claude which tools it has access to</li>
<li>Only 2-3 out of 5 servers' tools are available</li>
<li>Quit and relaunch Claude Desktop</li>
<li>A <strong>different</strong> random subset of 2-3 servers' tools are available</li>
</ol>
<h2>Observed Behavior Across Sessions</h2>
Session | Filesystem | GitHub | Kubernetes | Notion | Terraform
-- | -- | -- | -- | -- | --
1 | YES | no | YES | no | no
2 | no | no | YES | YES | no
3 | YES | no | YES | YES | no
<p>All 5 servers show "running" in every session. The subset that actually exposes tools to the model is random and changes per restart.</p>
<h2>Key Evidence: Server Logs Prove Perfect Handshake</h2>
<p>The GitHub MCP server log from Session 3 (where GitHub tools were NOT available to the model) shows a <strong>complete, error-free protocol exchange</strong>:</p>
<pre><code># Server starts successfully
2026-02-14T22:43:31.527Z [github] Server started and connected successfully
Server sends capability notifications
2026-02-14T22:43:31.544Z [github] Message from server: {"jsonrpc":"2.0","method":"notifications/tools/list_changed","params":{}}
2026-02-14T22:43:31.544Z [github] Message from server: {"jsonrpc":"2.0","method":"notifications/prompts/list_changed","params":{}}
2026-02-14T22:43:31.544Z [github] Message from server: {"jsonrpc":"2.0","method":"notifications/resources/list_changed","params":{}}
Client sends initialize -- server responds with full capabilities
2026-02-14T22:43:32.038Z [github] Message from client: {"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{"extensions":{"io.modelcontextprotocol/ui":{"mimeTypes":["text/html;profile=mcp-app"]}}},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}
Server responds with capabilities (success)
Client sends notifications/initialized (session confirmed)
Client requests tools/list -- server responds with ALL 30+ GitHub tools (full schemas, icons, metadata)
Client requests prompts/list -- server responds
Client requests resources/list -- server responds
ZERO ERRORS. ZERO TIMEOUTS. COMPLETE PROTOCOL SUCCESS.
</code></pre>
<p>Despite this perfect handshake, the GitHub server's tools were NOT available to the model in this session.</p>
<h2>Comparison: Claude Code Does NOT Have This Bug</h2>
<p>The same MCP servers (github, kubernetes, notion, terraform) configured in Claude Code's <code>~/.claude/settings.json</code> connect reliably to all 4 servers every session. Claude Code uses the identical binaries and identical token values. Only Claude Desktop exhibits the nondeterministic failure.</p>
<h2>Root Cause Hypothesis</h2>
<p>The bug is in the Claude Desktop app's internal pipeline between receiving MCP tool registrations and assembling them into the model's tool context. When multiple MCP servers complete their handshakes simultaneously at startup, some servers' tool registrations are silently dropped. This is likely a race condition or buffer/context limit during tool context assembly before the API call.</p>
<h2>Related Issues</h2>
<p>This is the same family of bugs as:</p>
<ul>
<li>#2682 -- MCP Tools Not Available in Conversation Interface Despite Successful Connection</li>
<li>#14807 -- Claude Desktop MCP tools stopped working - server connected, no errors, tools not available</li>
<li>#22299 -- Claude Desktop MCP: tool call responses dropped by client (race condition suspected)</li>
<li>#5241 -- MCP Tools Not Registering Despite Successful Server Connection</li>
</ul>
<p><strong>What distinguishes this report:</strong> The above issues describe total failure (0 tools from a server). This report documents <strong>nondeterministic partial failure</strong> -- a random subset of servers' tools are dropped each session while others succeed, proving the config and servers are correct and pointing to a race condition during startup.</p>
<h2>Additional Context</h2>
<ul>
<li>This is the first report of this bug class on <strong>Linux</strong>. All existing related issues are tagged platform:macos or platform:windows.</li>
<li>Tested with wrapper scripts, direct binaries, and various config approaches. The nondeterministic failure persists regardless of config method.</li>
<li>The server logs show the desktop app performs a shutdown/restart cycle for each server at launch. All servers survive this cycle and complete the handshake, but some are still dropped.</li>
</ul>
<h2>What Should Happen</h2>
<p>All 5 configured MCP servers that show "running" status and complete the full MCP protocol handshake should have their tools available to the model in every session, deterministically.</p></body></html>
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗