claude-code - 💡(How to fix) Fix [BUG] MCP 'needs-auth cache' blocks reconnection to claudeai-proxy servers even after successful re-authentication for SDK processes [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#48670Fetched 2026-04-16 06:54:11
View on GitHub
Comments
0
Participants
1
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×6cross-referenced ×1

Error Message

Error Messages/Logs

Root Cause

In cli.js, the connection logic for claudeai-proxy, http, and sse servers checks the file-based cache before attempting any connection:

if (await isInNeedsAuthCache(serverName)) {
    log("Skipping connection (cached needs-auth)");
    return { type: "needs-auth" };
}

The cache TTL is 900,000ms (15 minutes). The cache is shared across all Claude Code processes on the machine and has no invalidation mechanism tied to token refresh.

Fix Action

Workaround

Deleting the cache file after re-authenticating and before restarting the session:

rm -f ~/.claude/mcp-needs-auth-cache.json

Code Example

if (await isInNeedsAuthCache(serverName)) {
    log("Skipping connection (cached needs-auth)");
    return { type: "needs-auth" };
}

---

rm -f ~/.claude/mcp-needs-auth-cache.json

---
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

When a claudeai-proxy MCP server (managed by claude.ai) fails to connect due to an expired OAuth token, Claude Code writes an entry to ~/.claude/mcp-needs-auth-cache.json with a 15-minute TTL. During that window, all new Claude Code processes skip the connection attempt entirely — even if the user has since re-authenticated and the Keychain contains a valid token.

This is particularly problematic for SDK consumers like claude-agent-acp, where each session spawns a fresh Claude Code child process. The user cannot run /mcp to authenticate interactively in these environments, so the workflow is:

  1. Authenticate in a terminal Claude Code session (via /mcp)
  2. Restart the SDK-based session

Step 2 fails if done within 15 minutes of the original failure, because the new process reads the stale cache and never attempts a connection.

Steps to reproduce

  1. Start a Claude Code session via claude-agent-acp (or any SDK consumer) with claudeai-proxy MCP servers (e.g. GitHub)
  2. Let the OAuth token expire — servers are marked needs-auth and cached in mcp-needs-auth-cache.json
  3. Authenticate in a separate terminal Claude Code session via /mcp
  4. Restart the SDK-based session within 15 minutes

Expected: The new session reads the refreshed token from the Keychain and connects successfully.

Actual: The new session reads mcp-needs-auth-cache.json, sees entries younger than 15 minutes, logs "Skipping connection (cached needs-auth)", and never attempts a connection.d

Verified behavior

We confirmed this experimentally:

ScenarioResult
Fresh cache entries (<15 min) + valid Keychain tokenConnection skipped, only authenticate stubs available
Cache file deleted + valid Keychain tokenServers connect successfully

Root cause

In cli.js, the connection logic for claudeai-proxy, http, and sse servers checks the file-based cache before attempting any connection:

if (await isInNeedsAuthCache(serverName)) {
    log("Skipping connection (cached needs-auth)");
    return { type: "needs-auth" };
}

The cache TTL is 900,000ms (15 minutes). The cache is shared across all Claude Code processes on the machine and has no invalidation mechanism tied to token refresh.

Suggested fixes

Any of these would resolve the issue:

  1. Invalidate cache on token refresh — When the Keychain token is updated (e.g. after /mcp authentication), clear or invalidate the corresponding entries in the cache file.
  2. Scope cache to process lifetime — Use in-memory caching instead of a shared file, so new processes always attempt a fresh connection.
  3. Check token freshness before using cache — Before skipping a connection, compare the cache timestamp against the Keychain token's last-modified time. If the token is newer, ignore the cache.
  4. Expose cache clearing via SDK — Allow SDK consumers like claude-agent-acp to signal "auth state changed, retry connections" (the getOAuthToken callback infrastructure already exists).

Workaround

Deleting the cache file after re-authenticating and before restarting the session:

rm -f ~/.claude/mcp-needs-auth-cache.json

Environment

  • Claude Code v2.1.108
  • @agentclientprotocol/claude-agent-acp v0.27.0
  • @anthropic-ai/claude-agent-sdk v0.2.104
  • macOS (Keychain-based credential storage)

What Should Happen?

after successfully authenticated via/mcp in claude-code, SDK based applications reads the refreshed token from the Keychain and connects successfully.

Error Messages/Logs

Steps to Reproduce

  1. Start a Claude Code session via claude-agent-acp (or any SDK consumer) with claudeai-proxy MCP servers (e.g. GitHub)
  2. Let the OAuth token expire — servers are marked needs-auth and cached in mcp-needs-auth-cache.json
  3. Authenticate in a separate terminal Claude Code session via /mcp
  4. Restart the SDK-based session within 15 minutes

Claude Model

None

Is this a regression?

No, this never worked

Last Working Version

No response

Claude Code Version

v2.1.108

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

No response

extent analysis

TL;DR

The most likely fix is to invalidate the cache on token refresh by clearing or invalidating the corresponding entries in the cache file when the Keychain token is updated.

Guidance

  • Invalidate the cache when the Keychain token is refreshed to ensure new processes attempt a fresh connection.
  • Consider scoping the cache to process lifetime by using in-memory caching instead of a shared file.
  • Before skipping a connection, compare the cache timestamp against the Keychain token's last-modified time to determine if the token is newer.
  • Expose cache clearing via SDK to allow consumers like claude-agent-acp to signal "auth state changed, retry connections".

Example

// Example of invalidating cache on token refresh
if (tokenRefreshed) {
  // Clear or invalidate corresponding entries in the cache file
  await invalidateCache(serverName);
}

Notes

The provided workaround of deleting the cache file after re-authenticating and before restarting the session can be used temporarily, but a more permanent solution should be implemented to handle token refreshes and cache invalidation.

Recommendation

Apply the workaround of deleting the cache file after re-authenticating and before restarting the session, and consider implementing a more permanent solution to invalidate the cache on token refresh. This will ensure that new processes attempt a fresh connection and resolve the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING