anthropics / anthropics/claude-ai-mcp
Custom connector: rotating OAuth credentials does not invalidate cached token — proxy keeps authenticating as old client_id until upstream 401
- Dominant language
- No language data
- Stars
- 471
- Forks
- 76
- PR merge metrics
- No merged PRs in 30d
Description
### What's wrong?
When a custom MCP connector's OAuth credentials are changed (new client_id/secret) and the connector is disconnected + reconnected via the claude.ai web UI, the proxy (mcp-proxy.anthropic.com) continues to authenticate to the upstream server using the **previous** client_id. The disconnect/reconnect cycle does not invalidate the cached access/refresh token. The new credentials are only picked up after the OLD token is forcibly invalidated server-side (e.g. suspending/revoking the old client at the authorization server), which forces a 401 and triggers a fresh token exchange.
### Expected behavior
Disconnecting a custom connector — or updating its credentials and reconnecting — should invalidate the cached token and run a fresh OAuth token exchange with the current credentials. The user should not have to revoke the old credential at their own authorization server to force re-auth.
### Actual behavior
- Connector reconnects and reports "connected" successfully.
- All subsequent tool calls continue to authenticate as the OLD client_id (verified in the upstream MCP server's access logs).
- The cached token is only dropped when the upstream server returns a 401 (after the old client is revoked/suspended server-side). After that forced 401, reconnect correctly picks up the new client_id.
### Steps to reproduce
1. Add a custom MCP connector (OAuth) with client_id **A**. Confirm calls authenticate as A in the upstream server logs.
2. Change the connector's credentials to client_id **B** (and/or disconnect -> reconnect with B).
3. Make a tool call. **Observed:** the upstream server logs show the request still authenticating as **A**, not B.
4. Server-side, suspend/revoke client_id **A** so its token hard-fails.
5. Make another tool call -> upstream returns 401 -> proxy re-runs the OAuth exchange -> subsequent calls now correctly authenticate as **B**.
### Impact
Credential rotation is silently ineffective. Users self-hosting OAuth MCP servers cannot swap credentials through the connector UI alone; recovery requires revoking the old credential at the authorization server, which is non-obvious and not always possible.
### Connection path
- claude.ai web UI custom connector -> mcp-proxy.anthropic.com (cloud proxy path)
### Related (not duplicates)
- #228 — proxy doesn't re-run /token on expiry (token *refresh*, not *rotation*)
- #48275 — UI disconnect doesn't propagate across cache layers
- #52565 — stale DCR client registrations not cleaned up
This is distinct: the prior token is **valid** and **cached**, and rotation/reconnect never invalidates it — only an upstream 401 does.
### Environment
- Client: claude.ai web Chrome/MacOS
- MCP server: OAuth
- Last reproduced: 7am ET
- Reference ID:
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.