anthropics / anthropics/claude-ai-mcp

OAuth loopback callback rejected for federated IdPs (Referer host ≠ IdP host) — regression in 1.21459.0

Open
#618 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
No language data
Stars
471
Forks
76
PR merge metrics
No merged PRs in 30d

Description

### MCP server URL or name

`https://mcp.example.com/mcp` (a managed connector; its OAuth authorization server is **Google-federated** — user signs in at `accounts.google.com`. Hostname redacted.)

### How are you connecting to this server?

Managed/enterprise deployment via `managedMcpServers` with `oauth: { clientId, callbackHost: 127.0.0.1, callbackPort: 3120 }`, connected through the direct MCP host (`custom3p-mcp` / `directMcpHost`). `inferenceProvider: gateway`.

### Where does the issue occur?

Claude Desktop **1.21459.0** on macOS 15.6 (Darwin 24.6.0). Interactive OAuth (Connect button).

### When did you last reproduce this?

2026-07-15

### Browser and OS

Claude Desktop 1.21459.0 (Electron), macOS 15.6 / Darwin 24.6.0

### Describe the issue

After updating to **1.21459.0**, interactive OAuth re-authorization fails for any managed MCP connector whose sign-in is **federated to a different host** (e.g. an IdP that redirects through Google/Okta/Azure AD). The browser opens, the user completes sign-in, but the app **rejects the loopback callback** because the callback's `Referer` host is the upstream federation IdP (`accounts.google.com`) rather than the connector's own IdP host (`mcp.example.com`). The flow can never complete, so the connector cannot be (re)connected.

This connector authorized and refreshed successfully for months prior to this build; the failure is new after updating. Existing cached tokens masked it until the connector was disconnected, forcing a fresh interactive auth.

**Control (same build, self-contained IdPs succeed):** on the identical build/session, connectors whose login is on their own domain authorize fine — Intercom (`mcp.intercom.com`) and Slack (`slack.com`) both open the browser, save tokens, and connect. The only difference is federation: their final redirect is on their own host so `Referer` matches the IdP; the federated connector's final redirect comes from `accounts.google.com`.

### Error details

`~/Library/Logs/Claude/main.log`, repeated on every retry:

```
[custom3p-mcp] opening authorize URL { server: 'Knowledge Base', host: 'mcp.example.com', state: '…' }
[custom3p-mcp] waiting for OAuth callback (browser opened) { server: 'Knowledge Base' }
[custom3p-mcp] rejecting loopback callback: Referer host "accounts.google.com" != IdP "mcp.example.com" (Origin absent)
```

Successful control on the same build:

```
[custom3p-mcp] opening authorize URL { server: 'Intercom', host: 'mcp.intercom.com', … }
[custom3p-mcp] saved OAuth tokens { server: 'Intercom', hasRefresh: true }
[custom3p-mcp] server connected { name: 'Intercom', toolCount: 13 }
```

### Expected behavior

The loopback callback is accepted and tokens are saved (as before 1.21459.0). Callback authenticity should be bound to the CSRF `state` parameter, not to the `Referer`/`Origin` host — which is unreliable across federated redirects and is intentionally stripped by some IdPs' `Referrer-Policy`.

### Additional context

**Root cause hypothesis:** 1.21459.0 appears to have added a loopback-callback check requiring `Referer` host == connector IdP host. This assumption breaks for any federated login, where the last page before the `127.0.0.1` redirect is the upstream identity provider. `Origin` is absent on the redirect, so the check falls back to `Referer` and hard-rejects.

**Impact:** any managed OAuth connector using federated sign-in (corporate SSO via Google/Okta/Azure AD) becomes impossible to (re)authorize after the update.

**Suggested fix:** validate the callback on `state`; when `Referer`/`Origin` are absent or cross-origin, allow the callback if `state` matches rather than rejecting.

**Workarounds:** server-side only, if you control the IdP (make the final loopback redirect originate from the connector's own host, or set `Referrer-Policy: no-referrer` on the redirecting hop). Not possible for third-party IdPs. No client-side or managed-config workaround (no version-pin key; `disableAutoUpdates` only freezes the already-updated build).

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.