Skip to main content
sunpeak implements the resource-server side of MCP OAuth. It can publish OAuth 2.0 Protected Resource Metadata, return RFC 6750 bearer challenges, and pass verified token data to tool handlers. Your authorization server still owns login, consent, client registration, token issuance, and refresh tokens.

Configure OAuth metadata

Export oauth next to auth in src/server.ts:
sunpeak start then serves both protected-resource discovery forms:
Unauthenticated MCP requests receive a challenge like this:
Set resource to the exact public MCP resource identifier. Token verification must enforce that resource or audience so the server does not accept tokens minted for another service. OAuth resource and authorization server URLs must use HTTPS. Plain HTTP is accepted only for loopback development URLs.

Request more scopes

The auth function receives the parsed MCP request as its second argument. Return authorized: false with insufficient_scope when a request needs scopes the current token does not have. sunpeak returns a 403 challenge that clients can use for an OAuth scope upgrade.
Include every scope required for the current operation in scopes. The client combines that challenge with scopes requested earlier before it starts the new authorization flow, so the server does not need to repeat scopes required only by other operations.

Use the composable handlers

The same configuration works with Node and Web Standard handlers:
Mount a Web Standard handler at the MCP endpoint and route both /.well-known/oauth-protected-resource paths to it. The Node handler recognizes those paths itself and falls through for unrelated routes. For a custom router, createOAuthProtectedResourceMetadata, getOAuthProtectedResourceMetadataUrl, and createOAuthChallenge are exported from sunpeak/mcp.

Client behavior in the inspector

The inspector follows the MCP OAuth discovery flow and supports these registration paths in order:
  1. A pre-registered client ID, with an optional secret
  2. A URL-based client ID backed by an HTTPS Client ID Metadata Document
  3. Dynamic Client Registration when the authorization server advertises it
Authorization Code flows use PKCE and state validation. Callback responses also validate the authorization server issuer when RFC 9207 is used. Cached tokens, registration data, PKCE verifiers, and discovery state are invalidated through the MCP SDK lifecycle when they become stale. Before opening the authorization page, the inspector requires the authorization server metadata issuer to exactly match the advertised issuer and requires code_challenge_methods_supported to include S256. When protected-resource metadata advertises more than one authorization server, the inspector asks which issuer to use and keeps client credentials, tokens, and PKCE state separate for each issuer. For a pre-registered confidential client, choose automatic client authentication or explicitly select client_secret_basic, client_secret_post, or none. The selected method must be advertised by the authorization server when it publishes token_endpoint_auth_methods_supported. Runtime insufficient_scope challenges start a fresh authorization flow with the union of previously requested scopes and the scopes required for the current operation. The inspector does not use a refresh-token request as a substitute for user authorization of new scopes. The inspector advertises the refresh_token grant. It adds offline_access to the authorization request only when the selected authorization server lists that scope in scopes_supported. Use Clear local authorization to discard the inspector’s cached tokens, client registration, PKCE verifier, and discovery state. This does not revoke tokens at the authorization server. The Client ID Metadata Document URL must use HTTPS, include a non-root path, and omit embedded credentials and fragments. The document must list the inspector callback URL that appears in the authorization request.

Token verification

Verify all of these claims before returning AuthInfo:
  • Signature and signing algorithm
  • Issuer
  • Audience or resource indicator
  • Expiration and not-before time
  • Required scopes for the current MCP request
Do not pass an upstream token through to another service unless that service is its intended audience.

See also

Server Entry

The src/server.ts entry point and AuthInfo type reference.

MCP OAuth Authorization for MCP Apps

The protocol flow, client behavior, version differences, and server checklist.