Remote OAuth MCP server shows "✔ Connected" but registers 0 tools in-session (Linear / mcp.linear.app)
ENVIRONMENT
- Claude Code 2.1.191, macOS (Darwin 25.1.0), model Opus 4.8
- Server: linear-server → https://mcp.linear.app/mcp (type: http, OAuth), added via
claude mcp add, stored at project/local scope in ~/.claude.json - ~23 MCP servers configured total; linear-server is the LAST entry in the project's mcpServers
SUMMARY
A remote OAuth HTTP MCP server reports "✔ Connected" in claude mcp list and its
server-instructions block loads into the session, but ZERO of its tools are registered
(ToolSearch finds no mcp__linear-server__* tools; the model cannot call any). The OAuth
token is valid and the server returns tools fine on a direct call — Claude Code fetches
them and fails to register them.
EXPECTED: linear-server's 46 tools (list_issues, save_issue, list_teams, …) are available
in the session.
ACTUAL: 0 tools registered. select:mcp__linear-server__list_issues,… → "No matching
deferred tools found."
DECISIVE EVIDENCE (this is the key part)
claude mcp list→ linear-server: ✔ Connected.- linear-server is NOT in disabledMcpServers; it IS in the project mcpServers config.
- Keychain blob "Claude Code-credentials" → mcpOAuth["linear-server|<hash>"]: VALID,
scope="read write", refresh token present, not expired.
- Using that SAME token, a raw MCP
initialize+tools/listPOST to
https://mcp.linear.app/mcp returns HTTP 200 and 46 tools.
=> Auth, scope, token, and the server are all fine. Claude Code is failing to
register tools it can successfully fetch.
- The unauthenticated
initializehandshake succeeds (hence "Connected" + instructions
load), but the tool-registration path comes up empty with no surfaced error.
- Other OAuth HTTP servers in the same config (sentry, supabase, n8n, stripe) correctly
show "! Needs authentication" — so the "Connected" status is decoupled from whether
tools were actually registered. The status is misleading.
ALREADY RULED OUT / TRIED (no effect)
- Not account/workspace gating: direct tools/list with the user's token returns all 46 tools.
- Cleared ~/.mcp-auth (stale mcp-remote client registrations).
- Removed a duplicate keychain mcpOAuth entry (an old server name sharing the same URL hash).
- Full restart of Claude Code. Still 0 tools.
- Linear's API key cannot be used as a static header bypass (endpoint 401 invalid_token;
only the 24h OAuth token is accepted), so the OAuth path can't be avoided.
IMPACT
The server is unusable despite a green "Connected" status, and the status gives no
indication anything is wrong. Appears correlated with having many MCP servers (the
affected server is last in the list) — possibly a startup contention / registration
race / tool-budget issue, but a single restart does not resolve it.
LIKELY RELATED ISSUES
#54710 (stale cached state for direct-config servers; reconnect doesn't re-fetch tools),
#10250 (OAuth succeeds, in-session reconnect fails), #44535 (mcp list "Connected"
diverges from in-session tool/auth state), #26917 (initialize succeeds, tools/list
unauthorized swallowed), #51736 (tools not populating the deferred-tools registry).
SUGGESTED FIX DIRECTIONS
- Surface a real error when tools/list fails or returns 0 instead of showing "Connected".
- Make
claude mcp liststatus reflect actual tool registration, not just the initialize handshake. - Add a retry/refresh on the post-OAuth tools/list registration step, especially under
many-server startup contention.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗