Add OAuth 2.1 support for MCP server#14
Merged
rafalzawadzki merged 5 commits intomainfrom Mar 24, 2026
Merged
Conversation
Wraps the Cloudflare Worker with @cloudflare/workers-oauth-provider to enable OAuth 2.1 authentication (DCR, PKCE, token management) alongside the existing API key auth. Users connecting via Claude Desktop or Claude.ai are redirected to the Supadata dashboard for login, which returns a signed JWT containing the user's API key. Legacy API key headers (x-api-key, x-api-token, supadata-api-key) continue to work unchanged. - Add auth-handler.ts (Hono router for /authorize + /callback) - Wrap worker.ts with OAuthProvider, serve PRM metadata - Add KV namespace binding for OAuth token storage - Add routes for OAuth endpoints (.well-known/*, /authorize, /token, etc.) - Add @cloudflare/workers-oauth-provider, hono, jose dependencies Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supadata-mcp | 0717d88 | Mar 24 2026, 09:51 PM |
MCP clients (Claude Desktop, Claude.ai) need the resource_metadata URL in the WWW-Authenticate header to discover the OAuth server (RFC 9728). The library's default 401 response doesn't include it, so we use the onError callback to add it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The /authorize path was being intercepted by a conflicting route on the api.supadata.ai zone (likely the API gateway). Moving all OAuth endpoints under /oauth/ avoids any conflicts: - /authorize → /oauth/authorize - /token → /oauth/token - /register → /oauth/register - /callback → /oauth/callback Also simplified wrangler routes to use a single /oauth/* wildcard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude sends resource=https://api.supadata.ai/ (with trailing slash) in the authorize request. This gets stored as the token audience. When validating the token on /mcp, the library computes the resource server as protocol://host (no trailing slash) and does strict equality — which fails. Strip trailing slashes from the resource parameter before storing the grant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The root cause from worker logs: 1. Claude sends resource=https://api.supadata.ai/ (trailing slash) in both the authorize request and token exchange POST body 2. The library stores this as the token audience 3. When validating tokens on /mcp, the library computes the resource server as protocol://host (no trailing slash) and does strict equality 4. "https://api.supadata.ai" !== "https://api.supadata.ai/" → 401 Fix: strip the resource parameter from two places: - auth-handler.ts: delete resource from the grant before completeAuthorization - worker.ts: strip resource from the token exchange POST body before it reaches the OAuthProvider This prevents any audience from being stored in tokens, skipping the audience validation entirely on MCP requests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@cloudflare/workers-oauth-providerto enable OAuth 2.1 authentication (DCR, PKCE, token management)x-api-key,x-api-token,supadata-api-key) continue to work unchanged — fully backward compatibleNew files
src/auth-handler.ts— Hono router handling/authorize(redirect to dashboard) and/callback(JWT validation +completeAuthorization)Modified files
src/worker.ts— Wrapped withOAuthProvider, added PRM metadata endpoint, legacy API key bypasswrangler.toml— Added KV namespace binding and routes for OAuth endpointspackage.json— Added@cloudflare/workers-oauth-provider,hono,jose,@cloudflare/workers-typestsconfig.json— Added@cloudflare/workers-typesWorker secrets required
MCP_JWT_SECRET— shared HMAC secret for validating dashboard-signed JWTsDASHBOARD_URL—https://dash.supadata.aiCOOKIE_ENCRYPTION_KEY— for OAuth flow session cookiesDepends on
/oauth/mcpTest plan
/.well-known/oauth-protected-resourcereturns correct PRM metadata/.well-known/oauth-authorization-serverreturns correct AS metadataPOST /register(DCR) successfully registers clientsx-api-keyheader) still works🤖 Generated with Claude Code