Disabled MCP servers still trigger OAuth authentication popups on session start
Bug Description
MCP servers listed in disabledMcpServers (configured via the /mcp menu) still trigger OAuth authentication flows on session start, including opening browser windows for authorization.
Expected Behavior
Disabled MCP servers should not attempt any connection or authentication. The disabled check should prevent all network activity — including OAuth discovery, token refresh, and authorization flows — for servers the user has explicitly disabled.
Actual Behavior
Despite having multiple servers listed in disabledMcpServers, some still trigger browser auth popups on every new session. This is especially problematic for:
- stdio MCP servers using
npx mcp-remote— the subprocess appears to spawn before the disabled check, initiating its own OAuth flow independently - HTTP servers with expired/empty tokens — the OAuth flow fires before the disabled state is evaluated
Reproduction Steps
- Configure multiple MCP servers that require OAuth (HTTP type and/or stdio via
mcp-remote) - Open Claude Code, go to
/mcp, and disable several of them - Confirm they show as disabled in
/mcp - Close the session
- Open a new Claude Code session
- Observe: browser OAuth popups fire for servers that were disabled
The disabled state persists correctly in .claude.json under projects["<path>"].disabledMcpServers — verified by inspecting the file between sessions. The array contains the disabled server names. But auth popups still fire.
Environment
- Claude Code version: 2.1.63
- OS: macOS (Darwin 25.3.0, arm64)
- Installation method: Homebrew cask
Related Issues
- #13311 —
disabledMcpServerssetting not enforced at session startup (closed) - #11370 — Disabled MCP servers still load tool definitions (closed)
- #30135 — Disabled MCP servers still inject instructions (closed as duplicate)
The prior issues focused on tool definitions and context injection. This issue is specifically about OAuth authentication flows being triggered for disabled servers, which is a distinct and more disruptive code path (browser windows opening unexpectedly).
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗