# Claude.ai Web: “Authorization with [site] failed” / mcp_token_exchange_failed

> Claude.ai web shows 'Authorization with [site] failed' and mcp_token_exchange_failed after Authorize. It is an upstream claude.ai bug; use Claude Desktop.

- Canonical: <https://royalplugins.com/support/royal-mcp/claude-ai-web-token-exchange-fails/>
- Last updated: 2026-09-21
- HTML version: <https://royalplugins.com/support/royal-mcp/claude-ai-web-token-exchange-fails/>

---

You clicked **Authorize** on Royal MCP’s consent screen, WordPress issued the code, then claude.ai redirected you back to `/settings/connectors?error_code=mcp_token_exchange_failed` with the message “Authorization with [your site] failed.” If your Royal MCP Activity Log shows the `oauth:authorize` SUCCESS entry but **no subsequent** `oauth:token` entry — you’re hitting an upstream bug at claude.ai’s web client, not a Royal MCP or hosting issue. This page confirms the diagnosis in 30 seconds and shows you the working alternatives.

### This is a claude.ai (Anthropic) client-side bug — not Royal MCP, not your host, not your OAuth setup

If Activity Log confirms the token POST never arrived, **no server-side change will fix this**. Discovery, permalinks, `.well-known/`, HTTPS, Cloudflare, your host’s WAF, plugin settings — none of them are the cause. The token exchange happens inside claude.ai’s backend and, on some accounts and some sessions, never leaves their infrastructure. Skip to the [working alternatives](#alternatives) and don’t spend days on `/.well-known/`.

## The Exact Symptom

#### What you see in the browser

- You added Royal MCP as a custom connector in claude.ai and clicked **Connect**
- Claude.ai opens Royal MCP’s OAuth consent screen — the site name, your admin account, and the requested scopes all appear correctly
- You click **Authorize**
- The browser redirects back to `https://claude.ai/api/mcp/auth_callback?code=…` for a split second
- Then lands on `https://claude.ai/settings/connectors?error_code=mcp_token_exchange_failed`
- A toast reads “Authorization with **[your site name]** failed.” Sometimes accompanied by a reference ID like `ofid_1d57ea224b045cb9`

**What’s misleading:** the error suggests something failed on your side. It didn’t. Every step up to and including code issuance completed correctly. The failure is in the step that never happened — claude.ai’s backend was supposed to POST that authorization code to your `/token` endpoint to exchange it for an access token, and it didn’t.

## Confirm the Diagnosis in 30 Seconds

The Royal MCP Activity Log is the definitive check. It records every OAuth event that reaches your server. If a `/token` POST from claude.ai *never arrived*, no entry appears — and that proves the failure is on their end.

#### Open Royal MCP → Activity Log

In WP Admin sidebar: **Royal MCP → Activity Log**. If you don’t see it, look for the “Logs” or “Events” submenu under Royal MCP — older versions labeled it differently.

#### Look at the entries around the time you clicked Authorize

You should see an `oauth:authorize` entry with status SUCCESS — that’s the moment WordPress issued the code and redirected back to claude.ai. The relevant detail line reads something like:

```
OAuth Server — oauth:authorize — SUCCESS
Request:  POST /authorize, client_id wp_[…]
Response: 302, code_issued, "Authorization code issued;
          redirecting to client callback."
```

#### Check for a follow-up `oauth:token` entry

Immediately after the authorize row, you’d expect an `oauth:token` row with one of:

- **`token_issued`** — success (your OAuth flow completed and claude.ai should have connected)
- **`invalid_client`** / **`invalid_grant`** / **`invalid_request`** — the POST arrived but was rejected (server-side issue to investigate)

If you see **none** of those — nothing after the authorize row at all — that’s the fingerprint of the upstream bug. Claude.ai took the redirect and never came back.

The definitive fingerprint

Activity Log shows: `oauth:authorize SUCCESS, code_issued`. Nothing after it. No `oauth:token` entry of any kind. That means **the POST to `/token` never arrived at your server**. Nothing you can do server-side will fix this.

If Activity Log DOES show an `oauth:token` entry with an error

Then you have a different problem — the POST arrived but was rejected. Look at the error code:

- `invalid_client` — client\_id/secret mismatch, or claude.ai sent auth via HTTP Basic header when we expect `client_secret_post`. Check [static OAuth client setup](https://royalplugins.com/support/royal-mcp/static-oauth-client-setup/) to test with fresh credentials.
- `invalid_grant` — the authorization code was already used, expired, or doesn’t match. Usually resolves on retry.
- `invalid_request` — missing required params (typically PKCE). See the PKCE-missing troubleshooting flow.

These are server-side signals worth digging into — but they’re NOT what this page is about. This page is specifically for “POST never arrived” = upstream bug.

## Why This Happens

Claude.ai’s custom-connector OAuth flow is split between the browser and their backend. The browser handles the authorize redirect (which is why step 2 — the redirect back to `/api/mcp/auth_callback?code=…` — always fires visibly). The *token exchange* then happens server-to-server: claude.ai’s backend POSTs the authorization code to your `/token` endpoint and receives the access token in response.

On a working flow, that POST fires within milliseconds of your Authorize click. On the affected accounts / regions / sessions, the POST is dropped inside claude.ai’s infrastructure and never leaves their side. Your server receives no request, has nothing to log, has nothing to fail on. From the browser’s perspective, claude.ai just gives up and shows the generic `mcp_token_exchange_failed` banner.

The pattern is documented across many self-hosted MCP backends — Cloudflare Workers, Salesforce, FastAPI, Clerk OAuth, n8n, FIIP, Microsoft 365 — and multiple Anthropic-owned github issues:

```
github.com/anthropics/claude-ai-mcp/issues/215
github.com/anthropics/claude-ai-mcp/issues/175
github.com/anthropics/claude-ai-mcp/issues/163
github.com/anthropics/claude-ai-mcp/issues/46
github.com/anthropics/claude-ai-mcp/issues/119
github.com/anthropics/claude-ai-mcp/issues/184
github.com/anthropics/claude-plugins-official/issues/1674
```

Issue #215 in particular matches this symptom exactly and is closed as “not planned.” The common thread across all of them is: authorize completes, code is issued, then nothing. Claude Desktop’s `mcp-remote` bridge works against the same servers, which proves the failure is specific to claude.ai’s web client — not to the MCP servers themselves.

Why we can’t fix this on the plugin side

There is no server-side change that induces claude.ai’s backend to send the POST it isn’t sending. We’ve tested every credible hypothesis on our end — schema shape, auth-method advertisement, redirect URI handling, session state, cache-busting headers — and none of them change the outcome. The fix has to come from Anthropic.

## Working Alternatives (in Order of Preference)

#### 1. Claude Desktop — recommended

Same Royal MCP endpoint. Not affected by this bug. Two setup options depending on how much OAuth machinery you want in the loop.

##### Option A — API key header (fastest, skips OAuth entirely)

Generate an API key in **WP Admin → Royal MCP → Settings**, then add to Claude Desktop’s config as an `Authorization: Bearer` header (Royal MCP also accepts `X-Royal-MCP-API-Key`; either works). Full walkthrough: [Connect Claude Desktop with an API key](https://royalplugins.com/support/royal-mcp/connect-claude-desktop-api-key/). No OAuth, no discovery, no `.well-known/` — skips every layer this bug touches.

##### Option B — OAuth via `mcp-remote` bridge

If you want the OAuth-per-user semantics of the web flow, Claude Desktop can consume Royal MCP’s HTTP endpoint via the `mcp-remote` bridge, which handles OAuth in a browser popup on your desktop. The token exchange happens locally — not through claude.ai’s backend — so it isn’t affected by this bug either. See [Using Royal MCP with Claude Desktop](https://royalplugins.com/support/royal-mcp/using-royal-mcp-with-claude-desktop/).

#### 2. Claude Code (CLI)

Same MCP endpoint, same config pattern as Claude Desktop — API key via `Authorization: Bearer` header. Not affected by the claude.ai web bug. Ideal if you’re a developer already using Claude Code for coding work and want your WordPress tools available in the same session.

#### 3. Try a different host as diagnostic (only if you’re also fighting other issues)

If claude.ai web works for you against a different Royal MCP install (on a different host) but fails on yours, that would be evidence of a host-specific factor. In practice we haven’t seen host correlation for this specific bug — it appears account-scoped or region-scoped on the claude.ai side — but if your OAuth is already brittle on the host for other reasons, moving is worth considering regardless. See [OAuth fails on managed hosts](https://royalplugins.com/support/royal-mcp/oauth-fails-on-managed-host/).

## Note: This Is Different from ChatGPT’s Cosmetic Banner

Some ChatGPT Dev Mode connectors show “action discovery failed” or “unknown error” after Authorize but the connector actually works in-chat — the modal error is cosmetic. That’s a different bug: see [Connecting to ChatGPT](https://royalplugins.com/support/royal-mcp/connecting-to-chatgpt/).

Claude.ai’s `mcp_token_exchange_failed`, by contrast, is a hard failure. The connector never actually completes; it doesn’t appear in your connector list; there’s no in-chat call to attempt. If Activity Log confirms no `/token` POST arrived, don’t retry the OAuth flow expecting it to work — move to the alternatives above.

## External References

If you want to follow the upstream tracking:

- [anthropics/claude-ai-mcp #215](https://github.com/anthropics/claude-ai-mcp/issues/215) — matches this symptom exactly, closed as not planned
- [anthropics/claude-ai-mcp #175](https://github.com/anthropics/claude-ai-mcp/issues/175) — same failure mode, different self-hosted backend
- [anthropics/claude-ai-mcp #163](https://github.com/anthropics/claude-ai-mcp/issues/163)
- [anthropics/claude-ai-mcp #46](https://github.com/anthropics/claude-ai-mcp/issues/46)
- [anthropics/claude-ai-mcp #119](https://github.com/anthropics/claude-ai-mcp/issues/119)
- [anthropics/claude-ai-mcp #184](https://github.com/anthropics/claude-ai-mcp/issues/184)
- [anthropics/claude-plugins-official #1674](https://github.com/anthropics/claude-plugins-official/issues/1674)

General web search: query `mcp_token_exchange_failed` and you’ll find the same failure reported against many self-hosted MCP servers, none of which have a server-side resolution.

## Still Stuck?

If Activity Log **does** show a `/token` entry with an error (not the empty pattern this page describes), or the alternatives above don’t apply to your setup, we can help.

### Community Support (free) — wp.org Plugin Forum

Post a new thread at [wordpress.org/support/plugin/royal-mcp/](https://wordpress.org/support/plugin/royal-mcp/). Include:

- The Activity Log entries around the failed authorize (both `oauth:authorize` and any `oauth:token` rows)
- Whether it’s claude.ai web, Claude Desktop, or Claude Code
- Royal MCP version
- The reference ID from claude.ai’s error toast (`ofid_...`) if visible

### Premium Support (paid)

For direct one-on-one help with 24-hour SLA, see [Premium Support](https://royalplugins.com/premium-support/) ($149/year).

## Related OAuth troubleshooting

[Connect Claude Desktop with an API key

The fastest path around the claude.ai web bug — skip OAuth entirely and use an API key header.](https://royalplugins.com/support/royal-mcp/connect-claude-desktop-api-key/)
[Static OAuth Client Setup

Useful diagnostic isolator — static credentials let you test /authorize + code issuance without any /.well-known/ dependency.](https://royalplugins.com/support/royal-mcp/static-oauth-client-setup/)
[Troubleshooting start here

If you’re not sure the diagnostic on this page applies to your symptom — start with the decision tree.](https://royalplugins.com/support/royal-mcp/troubleshooting-start-here/)

[Back to Troubleshooting Start Here](https://royalplugins.com/support/royal-mcp/troubleshooting-start-here/)
[Royal MCP Support Hub](https://royalplugins.com/support/royal-mcp/)
