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

Open
#379 0 comments 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.