Choosing an OAuth provider for your MCP server
A decision guide comparing Auth0, Stytch, Supabase Auth, and self-hosted Hydra as MCP authorization servers: signup friction, DCR support, token quirks, and CIMD, all from having set up and token-tested each one live.
multi-client · updated 2026-08-22
We set up all four as authorization servers in front of MCP resource servers, ran tokens through each, and hit each one’s quirks. Every claim below came from a live setup. Each provider also has its own full walkthrough linked below.
At a glance
| Auth0 | Stytch | Supabase Auth | Hydra (self-hosted) | |
|---|---|---|---|---|
| Signup friction | Email + code, no card | Magic link, no card | GitHub/email (email has CAPTCHA) | You run it |
| DCR | ✅ tenant flag | ✅ Connected Apps toggle | ✅ Management-API flag | ✅ config |
| CIMD (ChatGPT) | ✅ flag | ✅ toggle | not yet | via your proxy |
Native resource param |
✅ (audience profile, 2026) | via scopes | via scopes | via your proxy |
| Token signing | RS256 | RS256 | ES256 | RS256 |
Token aud |
your MCP URL | client/project ID | "authenticated" |
your MCP URL |
| Hosted consent page | ✅ | ❌ you host it | ❌ you host it | ❌ you host it |
| RFC 7592 client management | ❌ | ❌ | ❌ | ✅ |
| Per-user pricing | yes | yes | yes | none |
| Full guide | Auth0 | Stytch | Supabase | Hydra |
How to pick
You want the least work and a hosted login page → Auth0. It’s the only one
of the four with a hosted consent screen (the others delegate the authorize UI
to you). 2026 tenants also natively map the MCP resource parameter to the
audience, so tokens carry your MCP URL as aud and you no longer need the
proxy workaround. Watch the trailing slash on the
issuer, and prune DCR clients yourself (no RFC 7592).
You already use Stytch, or want B2B/orgs → Stytch. Connected Apps turns the
project into a clean OIDC provider. The one trap: only
the project domain (customers.stytch.dev) serves the RFC 8414 metadata
with a registration endpoint; the legacy API path silently omits it. Tokens
carry the project/client ID as aud, not your URL, so validate on issuer +
signature, not audience.
Your users already live in Supabase → Supabase Auth. The OAuth Server beta
lets your MCP connector log in with your existing user base directly. Two
gotchas: the issuer lives under /auth/v1 (not the project root), and tokens
are ES256, so your verifier must import EC keys, not just RSA. The “Allow
Dynamic OAuth Apps” dashboard toggle didn’t persist for us; set it via the
Management API instead.
You want no per-user pricing, no vendor, tokens on your own disk → self-hosted Hydra. More to operate (you run the service and host login + consent), but it’s the only option with real RFC 7592 client management, and the only one with zero per-user cost. It needs a small DCR scrub proxy to satisfy ChatGPT’s strict schema. Full details in the Hydra guide.
The part that’s the same everywhere
Whichever you pick, your MCP resource server behaves identically: serve
/.well-known/oauth-protected-resource, answer unauthenticated requests with
401 + a WWW-Authenticate challenge, and validate the provider’s JWT offline
against its JWKS. Our ~150-line dependency-free reference server
(RL/testbeds/lib/resource-worker.mjs) runs unchanged against all four;
only the issuer, JWKS URL, and audience policy differ per provider.
Next steps
- Pick a provider above and follow its walkthrough end to end; each one ends with a finish-the-setup checklist.
- Build (or reuse) the resource server, then run the connector checklist four-curl self-test.
- Connect in Claude, then make it portable across Claude, ChatGPT, and Grok.
To hand it to an agent instead, every provider has a copy-paste prompt in the prompt library.
Metadata
- Commit
- c6eb99c
- Browser
- —
- Current Time
- —
- Dimensions
- —
- Source
- guides
- Last Updated
- 2026-08-22