Overview
MCP Apps can protect tools behind OAuth-based authorization, as defined in the MCP specification. There are two approaches:- Per-server authorization — every MCP request requires a valid token. Simple when all tools are sensitive.
- Per-tool authorization — only specific tools require authorization. Public tools work without a token, and the OAuth flow triggers only when the user calls a protected tool.
src/server.ts auth export.
Server auth with src/server.ts
Export an auth() function from src/server.ts. sunpeak calls it on every MCP request and populates extra.authInfo in tool handlers.
AuthInfo to authenticate, or null to reject with 401.
Per-tool authorization
Checkextra.authInfo in tool handlers to scope data to the authenticated user. For per-tool auth, return a valid AuthInfo even without a token (for public tools), but include the token data when present.
UI-initiated auth escalation
A powerful pattern: load the app with public data (no auth required), then trigger the OAuth flow only when the user performs a protected action.- A public tool loads the UI without authorization
- The user clicks a button that calls a protected tool via
useCallServerTool - The host receives HTTP 401, automatically runs the OAuth flow
- After the user completes OAuth, the host retries the tool call with the token
- The protected data appears in the UI
OAuth discovery endpoints
The MCP specification requires servers to implement OAuth discovery so hosts know how to obtain authorization. Protected Resource Metadata (/.well-known/oauth-protected-resource) — describes the resource server and identifies which authorization server(s) can issue tokens. The MCP SDK’s mcpAuthRouter handles this automatically.
Authorization Server Metadata (/.well-known/oauth-authorization-server) — advertises authorization and token endpoints, supported scopes, and client registration support.
For custom server setups (using createMcpHandler), you may need to implement these endpoints yourself. See the MCP authorization spec for full requirements.
Token verification
Verify access tokens as JWTs against the identity provider’s JWKS endpoint. The jose library handles key fetching and caching:Best practices
Defence-in-depth
Defence-in-depth
Always check
extra.authInfo in protected tool handlers, even with HTTP-level enforcement. If the HTTP layer is misconfigured or bypassed, the tool handler catches unauthorized access.Prefer per-tool auth for mixed apps
Prefer per-tool auth for mixed apps
If your app has both public and protected features, use per-tool auth. The initial load is fast (no login wall), and OAuth triggers only when needed. This creates a better user experience.
Keep auth stateless
Keep auth stateless
Use JWTs and verify them on every request. Don’t store session state on the server — MCP connections may be distributed across multiple instances.
See also
Server Entry
The
src/server.ts auth export and AuthInfo type reference.MCP Auth Specification
Full OAuth authorization specification for MCP servers.