MCP OAuth: client performs full re-authorization at session start while valid refresh tokens exist

Status Open
Maintainer reply None cached
Activity 1 comment · opened Jul 30, 2026

Summary

Claude Code intermittently discards its stored MCP OAuth credentials and runs a full authorization-code flow at session start, without ever attempting a token refresh. As the operator of the MCP server on the other side of this, I can confirm the refresh tokens it abandoned were still valid and would have been honored.

Evidence (server-side)

I run the OAuth server for the MCP in question, so I have the authoritative view of what the client did and did not send. On a re-auth event today:

  • Full code flow observed: code_issuedcode_consumedtoken_issued
  • At that moment the grant held 4 live, unexpired refresh tokens (newest issued ~40 minutes earlier)
  • No refresh attempt was made before the re-auth: no invalid_grant, no rejection, no request at all
  • The grant was never revoked (revoked_at is null, created 12 days earlier)
  • Zero refresh rejections for this user in the preceding 36 hours; 6,170 successful refreshes across all users in a 21-day window

This is not the server rejecting a refresh. The client is deciding locally that it has no credentials.

Frequency

Full interactive re-auths for a single user on 7/11, 7/14, 7/15, 7/18, 7/21, 7/22, 7/28, 7/30 — each at session startup. On 7/28 the re-auth timestamp matched the exact minute a VS Code session started.

The disconnect surfaces mid-session as the MCP's tools vanishing from the tool list, which interrupts any in-flight tool call.

Expected behavior

At session start, attempt a refresh with the stored refresh token before falling back to interactive authorization.

Actual behavior

Interactive authorization is triggered directly, while valid refresh tokens are on hand.

Environment

  • Claude Code in VS Code
  • macOS 15 (Darwin 25.5.0)
  • Remote MCP server, OAuth 2.1 + Dynamic Client Registration, rotating single-use refresh tokens
  • Access token TTL 12h, refresh TTL 60d

Possibly related

#25245 (keychain read-back failures), #24317 (concurrent session credential clobbering), #28901 (4096-byte security -i truncation), #65036 (no proactive refresh at startup).

#65036 looks closest, but the credential loss pattern suggests a storage failure rather than only a missing refresh call — the client behaves as though the credentials are absent, not as though it forgot to use them.

Impact

Low severity, but it recurs several times a week and interrupts in-flight tool calls. Happy to supply further server-side audit detail if useful for triage.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗