/mcp dialog hangs for several seconds when an HTTP MCP server has stale OAuth tokens but reports "Connected"
Summary
A connected HTTP MCP server with an expired/stale OAuth token (where silent
refresh fails or the refresh token is no longer valid) causes the /mcp
dialog to hang for several seconds every time it's opened. The server is
shown as ✓ Connected the entire time — there is no UI signal that the
slowness is auth-related, which made this very hard to diagnose.
Repro
- Have any HTTP MCP server with OAuth configured. In my case it was the
official Granola MCP (https://mcp.granola.ai/mcp), but the symptom looks
transport/server-agnostic.
- Let its access token reach a state where it cannot be silently refreshed.
- Open
/mcp.
Expected: dialog opens promptly. If a server cannot serve tools because of
auth, it should be marked "Needs auth" / "Disconnected", not "Connected".
Actual: dialog stalls for several seconds while Claude Code apparently
retries against the stale token. The server is shown as ✓ Connected the
entire time. Re-authenticating that one server via /mcp makes the dialog
load instantly again.
Diagnosis
Bisecting and per-server connect timings in~/.claude/debug/<session>.txt showed only normal connect times
(150ms–650ms) for every server. The hang was not visible as a connection
failure; it appeared only during /mcp dialog open. The fix that worked
was clicking "Reconnect" / re-authenticating the offending server.
Suggestions
- Surface stale-auth state explicitly (e.g. "Needs reauth") instead of
"Connected" when a token refresh has failed or the token is past expiry
and the server has not responded successfully.
- Cap or short-circuit the refresh attempt during
/mcpdialog open so a
single misbehaving server can't stall the whole dialog.
- Consider proactively prompting for re-auth on next session start when
the refresh token is known to be invalid.
Environment
- Claude Code: 2.1.123
- Platform: macOS (Darwin 25.3.0)
- Transport: HTTP MCP with OAuth
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗