Skip to content

CORS preflight on POST /oauth/token blocks browser-based OAuth clients (Cloudflare MCP Portal admin UI) #999

@mdura-zbi

Description

@mdura-zbi

Summary

POST https://mcp.sentry.dev/oauth/token does not include CORS response headers, so any browser-based OAuth client running on a different origin is blocked by the browser at the preflight step. This breaks the Cloudflare MCP Server Portal admin UI ("Add MCP server" form at https://dash.cloudflare.com), which performs the OAuth authorization-code exchange in the browser.

The same Cloudflare Portal works correctly against other hosted MCP servers (Amplitude, included below as a positive comparison case) because they do set CORS headers on the same endpoint.

Reproduction

No credentials needed — just an HTTP client.

curl -i -X OPTIONS https://mcp.sentry.dev/oauth/token \
  -H 'Origin: https://dash.cloudflare.com' \
  -H 'Access-Control-Request-Method: POST' \
  -H 'Access-Control-Request-Headers: content-type'

Actual response (no Access-Control-* headers)

HTTP/2 204
date: Mon, 25 May 2026 09:02:34 GMT
report-to: ...
nel: ...
server: cloudflare
cf-ray: ...
alt-svc: ...

Expected (CORS allow-list present)

For comparison, the same preflight against https://mcp.amplitude.com/oauth/token:

HTTP/2 204
vary: Origin
access-control-allow-origin: https://dash.cloudflare.com
access-control-allow-credentials: true
access-control-allow-methods: GET,POST,PUT,OPTIONS,DELETE
access-control-allow-headers: Content-Type,Authorization,MCP-Protocol-Version,Mcp-Session-Id,X-Upload-Token

Amplitude's MCP server connects to the Cloudflare Portal without any issue. Sentry's does not.

User-visible error

When adding Sentry as a server in the Cloudflare MCP Server Portal admin UI:

MCP server authentication in progress
An error occurred while authenticating your MCP server.
Failed to fetch

Browser DevTools console shows the standard CORS preflight failure message:

Access to fetch at 'https://mcp.sentry.dev/oauth/token' from origin 'https://dash.cloudflare.com'
has been blocked by CORS policy: Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

Why this matters

OAuth is currently the only supported authentication path for mcp.sentry.dev (per #833). That means any browser-based OAuth client that lives on a different origin — Cloudflare MCP Portal admin UI, MCP Inspector, future browser-resident MCP hosts — cannot complete the code-for-token exchange against Sentry's hosted MCP. The Cloudflare Portal is the practical blocker today; the same class of failure is reported against MCP Inspector in modelcontextprotocol/inspector#817.

Workarounds (confirmed working — proves the OAuth backend is fine, CORS is the only gap)

  1. Register via Cloudflare's REST API (POST /accounts/{ACCOUNT_ID}/access/ai-controls/mcp/servers). Server-to-server, no CORS involved. Bypasses the broken dashboard form.
  2. Launch Chrome with --disable-web-security --user-data-dir=/tmp/chrome-cors-off for the one-time admin registration step. Sentry's OAuth dance then completes normally.

Both confirm the OAuth implementation works end-to-end — only CORS headers on /oauth/token are missing.

Suggested fix

Add CORS response headers on the /oauth/token endpoint:

Vary: Origin
Access-Control-Allow-Origin: <reflected origin or *>
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

For consistency, the same treatment likely belongs on:

  • POST /oauth/register (Dynamic Client Registration)
  • GET /.well-known/oauth-authorization-server
  • GET /.well-known/oauth-protected-resource
  • POST /oauth/revoke (token revocation)

Likely minimum diff

mcp.sentry.dev is itself built on @cloudflare/workers-oauth-provider (confirmed by server: cloudflare headers and Sentry's own architecture docs). The library auto-wraps /token, /register, and /.well-known/* responses with addCorsHeaders() starting in v0.7.0 (source).

The smallest fix is likely:

-"@cloudflare/workers-oauth-provider": "^0.4.x"
+"@cloudflare/workers-oauth-provider": "^0.7.0"

…followed by a deploy.

Environment

  • Tested: Brave 148, Chrome 148, Firefox 130 — same result on all (CORS is browser-agnostic, this is a server-side gap).
  • Cloudflare MCP Server Portal accessed at https://dash.cloudflare.com/<account-id>/one/access-controls/ai-controls/mcp-server/...
  • mcp.sentry.dev accessed: 2026-05-25.

Related

  • modelcontextprotocol/inspector#817 — same class of CORS failure affecting MCP Inspector.
  • getsentry/sentry-mcp#833 — adjacent: request for non-OAuth auth on the remote endpoint. Sentry's stated position there is to keep OAuth as the only supported method, which makes correct CORS support on the OAuth endpoints more important.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions