[BUG] claude.ai connector tools missing from the deferred-tool index for minutes-to-hours after session start; ToolSearch cannot distinguish it from a nonexistent tool
Preflight
- Searched existing issues (closest neighbours listed at the bottom; none is this exact case).
- Single bug.
- Running the latest version, 2.1.227.
Environment
- Claude Code 2.1.227
- macOS 26.x, Anthropic API
- 15 claude.ai connectors + 8 plugin/local MCP servers = 23 servers total
- Reproduced in both the desktop app and non-interactive agent sessions
What happens
claude.ai connector tools are absent from the deferred-tool index for minutes to hours after session start, while the servers themselves are fully connected.
During that window, ToolSearch with the exact, complete, correct tool name returns:
ToolSearch { query: "select:mcp__<uuid>__<tool_name>" }
→ No matching deferred tools found
That response is byte-identical to the one for a tool that does not exist. There is no not_yet_loaded state, no pending-server count, no index epoch — nothing that marks the empty result as provisional. Registration eventually arrives as a "deferred tools are now available" block appended to an unrelated tool result. There is a signal at the end of the blind window and none at the start.
The servers are not down. Taken in the same session in which ToolSearch had been returning empty for ~40 minutes:
$ claude mcp list
claude.ai Notion: https://mcp.notion.com/mcp - ✔ Connected
claude.ai Vercel: https://mcp.vercel.com - ✔ Connected
claude.ai Dropbox: https://mcp.dropbox.com/mcp - ✔ Connected
claude.ai GitHub: https://api.githubcopilot.com/mcp - ✔ Connected
plugin:figma:figma: https://mcp.figma.com/mcp (HTTP) - ✔ Connected
... 21 of 23 Connected; the 2 exceptions genuinely need auth and are unused
So claude mcp list and the deferred-tool index disagree, and only the latter is visible to the model.
Expected
Either the connector's tools are indexed by the first turn, or an unresolved select: on a syntactically valid tool name returns a distinct, typed state — e.g. servers_still_connecting, ideally with a pending count — rather than the same empty result as a genuine miss.
Impact
This is a correctness failure, not a latency annoyance. The agent cannot distinguish "not yet" from "not there", so it concludes the connector is unavailable or unauthorized, and then:
- writes that conclusion into durable artifacts — commit messages, PR bodies, documentation pages, hand-off notes — where it outlives the session that made it and misinforms whoever reads it next;
- skips work that was entirely possible, handing manual steps back to the user;
- invents workarounds (shell,
curl, browser automation) around capabilities that were about to become available.
The user-facing shape of this is a person being told, session after session, that connectors they have correctly configured are unavailable — while claude mcp list says otherwise.
Reproduction
Non-deterministic. Observed pattern:
- Configure ~15 claude.ai connectors, all authorized.
- Start a session; in the first turn,
ToolSearchfor a connector tool by its exact full name. - Intermittently:
No matching deferred tools found. claude mcp listin the same window reports that server✔ Connected.- Continue with unrelated work; the tools appear later, attached to an unrelated tool result.
Evidence
Measured over local session transcripts on one machine:
- 1,256 transcripts; 35 contain
No matching deferred tools found; 240 total occurrences. - Across the 34 sessions where it occurred, time from session start to the last such miss:
- median 355 s (5.9 min)
- max 10,575 s (2.94 h)
- 19 of 34 sessions exceeded 5 minutes
- Throughout,
claude mcp listreported the connectors✔ Connected.
The misses are not fuzzy-search failures: they follow select: queries carrying the full literal mcp__<uuid>__<tool> name.
Secondary amplifier worth fixing at the same time. Once the index comes back empty, retries tend to drift to a near-miss UUID (one hex digit off, reconstructed from memory rather than copied). That produces a second empty result for a genuinely different reason, which makes the wrong "connector unavailable" conclusion feel confirmed. A typed error state would cut this off at the first retry.
Related issues
- #83296 — connector tools activate silently after a multi-turn delay; notes that "unavailable-yet" and "never-going-to-be-available" look identical. Scoped to a fresh in-session OAuth authorization; this report is about already-authorized connectors absent at the start of a new session.
- #86080 — same end state, but onset is a mid-session drop announced by a "no longer available" message. Here there is no message at either boundary; the tools are never registered in the first place, which implicates initial registration rather than a lost connection.
- #45411 (closed) — names this mechanism and records the interactive case as resolving in "2–3 turns (~seconds)". The measurements above are the regression that makes it no longer benign.
- #82912 — startup connection starvation under large server pools; a plausible contributing cause, not asserted here.
- #86909 — proposes essentially the remedy below: a typed
loaded_tool_index_emptystate instead of ordinary zero hits.
Suggested fix, in priority order
- Return a typed state rather than an empty result when a
select:names a syntactically valid tool and any server is still connecting. This alone removes the false conclusions, even if the latency stands. - Surface a pending-server count in the session's opening context, so the blind window is announced at its start and not only at its end.
- Investigate startup connection scheduling — a ~3 hour registration delay against a server that reports
✔ Connectedlooks like starvation rather than slowness.