claude.ai connectors and local stdio servers yield zero tools at session start (desktop); only a manual connector re-toggle — which uses a different registration path (UUID vs display-name) — makes them appear
Environment
- Claude Desktop app 1.24012.9 on Windows 11 Pro (10.0.26200), Claude Code (CCD) 2.1.219 running inside it (
CLAUDE_CODE_ENTRYPOINT=claude-desktop) - 9 claude.ai OAuth connectors previously connected (Slack, Notion, Dropbox, Gmail, Google Calendar, Google Drive, Supabase, + 2 more), plus local stdio servers (an in-house file server, a desktop-automation server, a PDF viewer)
Symptom
When a new session starts, none of the claude.ai connectors' tools are loaded — and neither are several local stdio servers' tools — even though every connector toggle is ON in the UI. The session runs indefinitely in this state (observed: 8.5 hours, 7+ sessions in a row). Toggling any connector OFF→ON mid-session makes all of them (connectors AND local stdio servers) appear at once. Sometimes one OFF→ON cycle is not enough (reproduced on 2026-07-26 and 2026-07-31).
There are no auth errors: no 401/403, no token-refresh failures, nothing in [oauth-v2] besides using cached token. The needsAuthMcpServers list contains only plugin: servers — the connectors are simply absent, silently.
What the app's own logs show (%APPDATA%\Claude\logs\main.log)
Three code paths push MCP server lists to the SDK. Counts are from one day (2026-07-31):
| path | calls | servers passed | name format | ever yields tools? |
|---|---|---|---|---|
| LocalSessions.replaceEnabledMcpTools | 634 | 11 (no connectors) | display name | no |
| LocalSessions.replaceRemoteMcpServers | 438 | 18 | display name ('Slack', 'Notion', …) | no |
| LocalSessions.setMcpServers (1 server per call) | 222 | 11→18 stepwise | UUID (7984213a-…) | yes |
- At session start only the first two run. Example block (session start, 13:32:13 local):
````
[replaceEnabledMcpTools] Calling SDK with 11 total servers
LocalSessions.replaceRemoteMcpServers: serverCount=7
[replaceRemoteMcpServers] Calling SDK with 18 total servers
[CCD start-timing] preflight=16ms worktree=101ms mcp=436ms query=8ms enqueue=26ms init=11927ms
The CCD log says "18 total servers", but the session transcript's deferred_tools_delta attachment for that same session records 66 tools from 9 servers — zero connectors, zero affected stdio servers.
- Tools only ever materialize via the UUID path. Across 2,009 local session transcripts, tool-use references with UUID-prefixed names (
mcp__<uuid>__*): 364,585. References with display-name prefixes (mcp__Slack__*etc.): effectively 0. The display-name registration path appears to never produce usable tools.
- The toggle workaround works because it uses the UUID path. On toggle,
setMcpServersfires once per server: the count walks down 18→11 (all connectors removed) then back 11→18 (re-added, now with UUID names). ~90 s later the transcript records a singledeferred_tools_deltaadding 172 tools (7 connectors + the missing stdio servers together).
- A concurrency bug explains "one toggle is sometimes not enough". The three paths each push a full list computed independently (last-writer-wins). Observed: count recovers to 17, then two seconds later a competing push rolls it back to 14;
n=11(all connectors lost) occurred 20 times in one day. A toggle's re-add steps can be clobbered by a stale competing push.
- The toggle was performed in one session but the tools appeared in a different concurrently-running session, and afterwards brand-new sessions get tools without any toggle — the server list looks app-global, so one repair fixes all subsequent sessions until it breaks again.
Note: MCP_CONNECTION_NONBLOCKING=true is injected into the CCD process env by the desktop app; it never appears in either log, so its involvement is unconfirmed. %APPDATA%\Claude\logs\mcp.log only covers the desktop app's own MCP client (bursts once per app start), not CCD sessions — CCD-side connection success/failure is not logged anywhere we could find, which made this hard to diagnose.
Expected
Session start should register connectors via the same (working) path the toggle uses, or at least retry/self-heal when the initial registration yields no tools; and the SDK-side connection outcome should be logged.
Actual
Zero connector/stdio tools at session start; silent; no retry; manual OFF→ON per-connector is the only recovery, and it randomly needs repeating due to the last-writer-wins races above.
Repro
- Windows desktop app with several claude.ai connectors ON.
- Open new Code sessions over a day; when the list breaks (observed at app start and 20× during one day), every new session has no connector tools.
- Toggle any connector OFF→ON → ~1-3 min later all missing servers' tools appear in running sessions.