Skip to main content
The Model Context Protocol (MCP) authorization spec has MCP servers delegate authentication to an OAuth 2.0 authorization server. Prelude Auth is that authorization server: enable the OAuth server surface on your app and MCP clients — Claude, IDE agents, or any spec-compliant client — sign users into your MCP server against your existing Prelude Auth users, with no extra identity provider to run. This guide configures the authorization server. Your MCP server stays the OAuth resource server: it advertises Prelude Auth as its authorization server and verifies the access tokens Prelude issues.

How it works

Prelude Auth implements the authorization-code flow with PKCE (RFC 6749 + RFC 7636) and publishes RFC 8414 authorization-server metadata. Clients register themselves — no manual onboarding — through either mechanism the MCP authorization spec allows:
  • Dynamic Client Registration (DCR, RFC 7591) — the client POSTs its metadata to a registration endpoint and receives a generated client_id.
  • Client ID Metadata Document (CIMD, MCP 2025-11-25 / SEP-991) — the client’s client_id is an https URL that serves its metadata document. Prelude fetches and caches it on first use; there is no registration call.
A login looks like this:
1

Discovery

The client reads GET /.well-known/oauth-authorization-server to learn the authorize, token, registration, and JWKS endpoints.
2

Registration

The client registers via DCR or presents a CIMD client_id URL — whichever you enabled.
3

Authorize

The client redirects the browser to /v1/session/oauth/authorize with PKCE. Prelude persists the request and 302s to your login UI.
4

Login & consent

The user signs in with any method your app supports (OTP, password, passkey, social, SAML). Your login UI then shows the consent screen with the client name and requested scopes.
5

Code & token

On approval, Prelude redirects back to the client’s redirect_uri with a one-time code. The client exchanges it at /v1/session/oauth/token (with its PKCE code_verifier) for an access token and refresh token.
The issued session is a child of the user’s browser session. Its scopes are the intersection of the requested scopes and the parent session’s scopes (or the parent’s full set when the client requests the prld:oauth:inherit scope). A session minted through the OAuth flow cannot itself start another OAuth flow — the chain is capped at one level.

Prerequisites

Before you start, make sure you have:
  • A Prelude account with access to Prelude Auth
  • An Application ID (appID) — see Applications
  • Your Management API key for backend calls
  • A verified custom domain, or your default ${APP_ID}.session.prelude.dev host — the authorization-server endpoints are anchored to this auth domain
  • A login UI built with the Web SDK that can host the sign-in and consent screens (see Host the login and consent screens)

Enable the OAuth authorization server

Configure the OAuth server on your app with a single PUT. The presence of the registration.dcr and registration.cimd sub-objects is what enables each mechanism — omit one to leave it disabled.
1

Configure the authorization server

You can enable DCR, CIMD, or both. Modern MCP clients prefer CIMD (no registration round trip); DCR remains the widest-supported fallback. Enabling both lets each client use whichever it implements.
Read the current config back with GET /v2/session/apps/${APP_ID}/oauth, and turn the surface off entirely with DELETE /v2/session/apps/${APP_ID}/oauth. See the OAuth Server Config API reference for the full schema.

Register a client manually (optional)

For a known integration you can pre-register a client instead of relying on DCR or CIMD. This is also the only way to give a single client its own login UI, distinct from the app’s default_provider_url.
The response returns the generated client_id (an oac_… identifier). List clients with GET …/oauth/clients and remove one with DELETE …/oauth/clients/{clientID}.

Authorization server endpoints

Once enabled, Prelude serves the OAuth surface on your auth domain — your verified custom domain, or https://${APP_ID}.session.prelude.dev by default. Each is documented under the OAuth Server API reference:
PKCE with S256 is mandatory: /authorize rejects a request with no code_challenge, and plain is not accepted. Authorization codes are single-use and expire after 60 seconds.
Prelude handles the OAuth protocol but hands the browser to your login UI (default_provider_url) to authenticate the user and collect consent. Build two routes with the Web SDK:
1

Sign-in route (`/sign-in`)

Prelude redirects here with an ?oauth_req=<oar_…> query parameter. Read it, sign the user in with any method your app supports, then resume the flow by calling the SDK’s OAuth continue action with that oauth_req. Prelude returns the consent URL to navigate to next.
2

Consent route (`/oauth/consent`)

Prelude redirects here with the same ?oauth_req=. Fetch the pending request to display the requesting client name, redirect URI, and requested scopes, then submit the user’s Approve or Deny decision. Prelude returns the client redirect_uri (with code and state on approval, or error=access_denied on denial) for the browser to follow back to the client.
The continue, pending, and decision calls run against the user’s live session and are bound to it with DPoP. The Web SDK manages the session and the DPoP proof for you — you do not construct these requests by hand.

Point your MCP server at Prelude

On the MCP server side, advertise Prelude Auth as your authorization server so clients discover it, then verify the tokens Prelude issues:
  • Serve OAuth protected-resource metadata that points at your Prelude auth domain as the authorization_servers entry.
  • Validate incoming access tokens against the JWKS endpoint and check the scopes your MCP tools require.
Clients follow the discovery chain from your MCP server to Prelude’s /.well-known/oauth-authorization-server and run the flow above with no further configuration.

What’s next?

Web SDK

Build the sign-in and consent screens your login UI hosts.

Verify tokens (JWKS)

Verify the access tokens Prelude issues on your MCP server.

Custom domains

Anchor the authorization-server endpoints to your own domain.

Groups & scopes

Control which scopes a session — and its OAuth children — can carry.