Background subagents cannot access OAuth-authenticated MCP servers
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Background subagents spawned via the Agent tool cannot access MCP servers that require OAuth authentication. The parent session completes the OAuth flow and holds a valid token, but spawned agents start fresh connections without the authenticated session. This forces subagents to either skip OAuth-dependent tools entirely or attempt a full re-auth flow (e.g., via Playwright automation), adding 15-30 seconds of overhead per agent.
Affected MCP types:
- HTTP MCP servers with OAuth (e.g., Superhuman Mail at
https://mcp.mail.superhuman.com/mcp) - Built-in claude.ai connectors (e.g.,
mcp__claude_ai_Gmail__*) — these also require interactive/mcpauth and don't propagate to subagents
Not affected:
- stdio MCP servers (e.g., local Node.js servers via
command/args) — these work fine in subagents - SSE MCP servers on localhost (e.g., Obsidian, custom bots) — these work fine
Environment
- Claude Code version: 2.1.87
- OS: macOS 13.6.9 (Darwin 22.6.0)
- Subscription: Max plan
- MCP config: Project-level
.claude/.mcp.jsonwith HTTP and SSE servers
Steps to Reproduce
- Configure an HTTP MCP server requiring OAuth (e.g., Superhuman Mail)
- Authenticate via
/mcpin the main session — tools become available - Spawn a background agent:
Agent({ run_in_background: true, prompt: "Use mcp__superhuman-mail__list_threads to get recent emails" }) - The subagent receives authorization errors or only finds the
authenticatetool
Expected Behavior
Subagents spawned from an authenticated parent session should inherit or share the parent's MCP OAuth tokens. The token is already valid — the subagent just can't access it.
Actual Behavior
Each subagent process establishes its own MCP connection. For OAuth-protected servers, this connection is unauthenticated because:
- OAuth tokens appear to be held in-memory per transport connection
- No shared token store exists between parent and child processes
- The
authenticatetool (which triggers interactive browser flow) is the only tool exposed to the subagent
Workaround
We use Playwright MCP to drive the OAuth consent flow from within the subagent (4-click automated re-auth using persistent browser profile with saved Google session cookies). This works but adds complexity and latency.
Proposed Solutions (in order of preference)
- Token inheritance: Pass the parent's OAuth token to subagent processes via environment variable or shared credential file
- Shared token store: Persist OAuth tokens to a file-based store (e.g.,
~/.claude/mcp-tokens.json) readable by all Claude Code processes in the same user session - MCP proxy: Parent process acts as an MCP proxy, forwarding subagent tool calls through its authenticated connection
Related Issues
- #24317 — OAuth refresh token race condition with concurrent sessions (related but distinct: that's about token invalidation across parallel sessions; this is about token absence in child processes)
- #43397 — Cloud scheduled tasks can't access MCP connectors (same class of problem in cloud context)
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗