| --- |
| title: "OAuth 2.1 Server" |
| description: "Dynamic client registration, authorization, and token exchange endpoints that back the World Monitor MCP server's OAuth 2.1 authentication flow." |
| --- |
|
|
| WorldMonitor runs a minimal OAuth 2.1 authorization server whose only client-facing purpose today is **granting access to the MCP server** at `/api/mcp`. It implements: |
|
|
| - [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591) β Dynamic Client Registration |
| - [RFC 7636](https://datatracker.ietf.org/doc/html/rfc7636) β PKCE (required, S256 only) |
| - [RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414) β Authorization Server Metadata |
| - [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) β Protected Resource Metadata |
|
|
| |
|
|
| | URL | Purpose | |
| |-----|---------| |
| | `/.well-known/oauth-authorization-server` | AS metadata (endpoints, supported grants, PKCE methods) | |
| | `/.well-known/oauth-protected-resource` | Resource metadata (authorization servers, scopes) | |
|
|
| `/.well-known/oauth-protected-resource` currently advertises the public resource scope `mcp`. Pro authorization-code grants return the internal scope value `mcp_pro`; legacy API-key grants and `client_credentials` return `mcp`. |
|
|
| |
|
|
| |
|
|
| Dynamic Client Registration. Returns a `client_id` (public clients, no secret). |
|
|
| **Request**: |
| ```json |
| { |
| "redirect_uris": ["https://claude.ai/api/mcp/auth_callback"], |
| "client_name": "Claude Desktop", |
| "token_endpoint_auth_method": "none" |
| } |
| ``` |
|
|
| **Response**: |
| ```json |
| { |
| "client_id": "7c3b08f0-0c1f-4a9c-8a52-69e13d2a5d5e", |
| "client_name": "Claude Desktop", |
| "redirect_uris": ["https://claude.ai/api/mcp/auth_callback"], |
| "grant_types": ["authorization_code", "refresh_token"], |
| "response_types": ["code"], |
| "token_endpoint_auth_method": "none" |
| } |
| ``` |
|
|
| **Redirect URI allowlist**: only these prefixes are accepted: |
|
|
| - `https://claude.ai/api/mcp/auth_callback` |
| - `https://claude.com/api/mcp/auth_callback` |
| - `http://localhost:<port>` / `http://127.0.0.1:<port>` β any port |
| |
| **Rate limit**: 5 registrations / 60 s / IP. |
|
|
| **Client TTL**: 90 days sliding (every successful token exchange refreshes). |
|
|
| |
|
|
| Starts the OAuth flow. Renders a consent page that redirects to Clerk for sign-in, then issues an authorization code bound to the caller's PRO entitlement. |
| |
| **Required query params**: |
| |
| - `response_type=code` |
| - `client_id` β from DCR |
| - `redirect_uri` β must match the one registered |
| - `code_challenge` β PKCE S256 |
| - `code_challenge_method=S256` |
| - `state` β opaque |
| - `scope` (optional) |
| |
| **Code TTL**: 10 minutes. Single-use (atomic `GETDEL` on exchange). |
| |
| ### `POST /api/oauth/token` |
| |
| Exchanges an authorization code for an access token, or refreshes an existing token. |
| |
| **Grant type: `authorization_code`**: |
| ``` |
| grant_type=authorization_code |
| code=<from /authorize> |
| code_verifier=<PKCE> |
| client_id=<from DCR> |
| redirect_uri=<same as /authorize> |
| ``` |
| |
| **Response**: |
| ```json |
| { |
| "access_token": "6f13d8fa-89b6-4a02-a527-7f6f61a2df55", |
| "token_type": "Bearer", |
| "expires_in": 3600, |
| "refresh_token": "6ba38313-9a4d-4797-9186-3d2c3c1cfe02", |
| "scope": "mcp_pro" |
| } |
| ``` |
| |
| **Grant type: `refresh_token`**: |
| ``` |
| grant_type=refresh_token |
| refresh_token=<from previous exchange> |
| client_id=<from DCR> |
| ``` |
| |
| **Rate limit**: 10 token requests / minute. The limiter is keyed by `client_secret` hash for `client_credentials`, by `client_id` when present (`authorization_code` and `refresh_token`), and falls back to caller IP only when neither identifier is available. |
| |
| **Token TTLs**: |
| |
| - Access token: 1 hour |
| - Refresh token: 7 days |
| |
| Access and refresh tokens are opaque UUIDs. All token-endpoint responses include `Cache-Control: no-store, Pragma: no-cache`. |
| |
| ## Using tokens |
| |
| Pass the access token on every MCP request: |
| |
| ``` |
| Authorization: Bearer 6f13d8fa-89b6-4a02-a527-7f6f61a2df55 |
| ``` |
| |
| Tokens are bound to the user's account and re-check entitlement on every call β a downgrade revokes access on the next request. |
|
|
| |
|
|
| Per [RFC 6749 Β§5.2](https://datatracker.ietf.org/doc/html/rfc6749 |
|
|
| ```json |
| { "error": "invalid_grant", "error_description": "..." } |
| ``` |
|
|
| Common errors: `invalid_request`, `invalid_client`, `invalid_grant`, `unsupported_grant_type`, `invalid_scope`. |
|
|