Skip to content

Custom connector fails at token exchange — server issues auth code correctly, claude.ai never calls /token (ofid_f35608ed2b59d7ad) #215

Description

@pdugan20

MCP server URL

https://mcp.rewind.rest/mcp

Where does the issue occur?

During OAuth token exchange — server issues authorization code correctly, claude.ai never POSTs to /token.

Transport used

streamable-http

Client registration type

Dynamic Client Registration (DCR) — also tried manual pre-registration via Advanced Settings with identical failure.

SSE only: Does your server return the expected status code for POST requests?

Not applicable (server does not use SSE)

When did you last reproduce this?

2026-04-22, 8:00 PM PDT

Browser and OS

Chrome on macOS / Claude iOS app

Describe the issue

Custom MCP connector worked reliably via claude.ai web and iOS until approximately April 15, 2026. Since the Connections → Customize UI migration, adding the connector fails with either "Couldn't reach the MCP server" (first attempt) or "Authorization with the MCP server failed" / mcp_token_exchange_failed (after pre-registering a client via Advanced Settings to bypass DCR).

The server is verifiably healthy at every step that we control:

  • /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource/mcp return valid JSON
  • POST /register returns 201 with a valid client record
  • GitHub upstream auth completes end-to-end through our /callback handler
  • completeAuthorization() (via @cloudflare/workers-oauth-provider@0.4.0) returns a valid MCP authorization code and we 302-redirect to https://claude.ai/api/mcp/auth_callback?code=…&state=…
  • curl -I https://mcp.rewind.rest/mcp returns a 401 with WWW-Authenticate: Bearer realm="OAuth", resource_metadata=… byte-identical in shape to Sentry, Notion, and Linear's working MCP servers

After the 302 redirect to claude.ai's callback, the Worker tail shows zero subsequent requests from claude.ai — no /token call, no /mcp call with a Bearer. The connector UI then displays "Authorization with the MCP server failed."

Either:

  1. claude.ai fails to parse / accept the authorization code we returned, or
  2. claude.ai silently aborts the OAuth flow before attempting the token exchange.

Either way the failure is on claude.ai's side — our 302 is the last step under our control, it carries a correctly-shaped code + state, and it lands at the claude.ai callback URL we were told to redirect to.

Related / probable duplicates:

Issue details

Reference IDs collected across multiple attempts today:

  • `ofid_a0225447065f6c7b`
  • `ofid_3656e96b3960e1b5`
  • `ofid_8e4ac9fece484c6f`
  • `ofid_f35608ed2b59d7ad`

Server-side log from a successful /callback leg, captured immediately before the UI "Authorization with the MCP server failed" error:

```
[callback] code=present state=present
[callback] github exchange ok: id=1837100 login=pdugan20
[callback] allowlist check: github_id=1837100 rewind_user_id=1 allowlist_keys=1837100
[callback] completeAuthorization redirectTo=https://claude.ai/api/mcp/auth_callback?code=&state=
```

After that 302, the Worker tail shows no /token request from claude.ai, only repeated unauth'd /mcp probes returning 401.

Server stack:

  • Cloudflare Worker
  • `@cloudflare/workers-oauth-provider@0.4.0` (latest published)
  • GitHub as upstream identity provider
  • All well-known endpoints return valid JSON
  • DCR and manual client registration both supported; both tried

Comparison with working listed connectors (byte-identical 401 shape):

```

rewind (broken in claude.ai web)

HTTP/2 401
content-type: application/json
www-authenticate: Bearer realm="OAuth", resource_metadata="https://mcp.rewind.rest/.well-known/oauth-protected-resource/mcp", error="invalid_token"

sentry (working in claude.ai web as a listed connector)

HTTP/2 401
content-type: application/json
www-authenticate: Bearer realm="OAuth", resource_metadata="https://mcp.sentry.dev/.well-known/oauth-protected-resource", error="invalid_token", resource_metadata="https://mcp.sentry.dev/.well-known/oauth-protected-resource/mcp"
```

Desktop stdio transport works perfectly against the same server code; only the claude.ai web/mobile custom connector OAuth flow is affected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions