Claude Desktop (3P) keeps retrying a rejected MCP OAuth refresh token instead of prompting sign-in
What's wrong
When a custom MCP server's token endpoint returns invalid_grant on a refresh, Claude Desktop (3P) retries the same refresh token every 30 minutes, sometimes for days. It never prompts the user to sign in again, so the connector stays dead until the user clicks Reconnect.
Desktop also sends refresh tokens that the server has already rotated. These arrive 35 to 70 minutes after a refresh that succeeded server-side, which suggests Desktop didn't persist the rotated token. Desktop's own log points the same way:
[custom3p-mcp] mid-session refresh did not rotate { server: '...', failCount: 92, backoffMs: 1800000, reason: 'saveTokens reported rotated but persisted bearer unchanged (encrypt-fail?)' }
Against a server with refresh token rotation and reuse detection (RFC 9700), the replayed token revokes the whole token family, and the user loses the connector until they re-authenticate.
Expected
- Treat
invalid_granton refresh as terminal and show the sign-in prompt. - Persist a rotated refresh token before discarding the old one.
Environment
Claude Desktop (3P) builds 2.26454.x through 2.31226.x, macOS, custom remote MCP server using OAuth with DCR + PKCE and rotating refresh tokens.
Related
- #85236 (Claude Code CLI sessions racing refresh against rotation-strict servers)
- #65036 (MCP OAuth tokens not auto-refreshed)