oauth, tool, resource, and prompt callbacks receive verified authentication data on ctx.auth. The provider determines the static type of ctx.auth.user; there is no generic UserInfo shape.
Auth shape
Every provider exposes this top-level shape:useris the provider’s normalized user type.payloadcontains the verified token claims or introspection data.accessTokenis the verified bearer token. Forward it only when calling an upstream API on behalf of the user. On an OAuth Proxy server it is the proxy’s own token, which upstream APIs do not accept.scopesare copied from the auth information returned by the token verifier.permissionsare produced by the provider’s mapping.clientIdis present when the token has a client identifier.expiresAtis a Unix timestamp in seconds.resourceis the protected resource validated by the verifier.upstreamis set only on an OAuth Proxy server. It holds the upstream provider’s token for the user; read it withupstreamToken(ctx.auth)frommcp-use/oauth.
Use provider-specific fields
All built-in users haveid. Optional profile and organization fields vary:
The OAuth Proxy is the exception: its user is
{ subject, profile }, where subject is the provider’s stable user ID and profile holds the provider’s fields. Pass mapUser to oauthProxy to return a user with id.
payload only when you deliberately need a provider claim that is not mapped.
Check scopes and permissions
Scopes describe OAuth grants. Permissions describe provider-mapped application authorization.client:role, and Supabase maps AAL to aal:<level>.
Map custom claims
For another authorization server,oauthCustomProvider separates verification from application mapping:
createTokenVerifier receives the canonical MCP resource. The verifier rejects a token by throwing OAuthError with OAuthErrorCode.InvalidToken, so the client gets 401 with a WWW-Authenticate challenge, or, for a ChatGPT tools/call request, an isError tool result carrying the same challenge (see Mixed auth). An error that is not an OAuthError is answered with 500. The auth information it returns must carry resource as a URL matching that resource, clientId as a string ("" when the token has no client), and expiresAt in Unix seconds in the future. mapAuthInfo runs only after SDK auth information has been verified and must return { user, payload, permissions }. It does not rewrite ctx.auth.scopes; those come from the verifier’s verified auth info.
Next steps
Authentication
Choose and configure an OAuth provider.
Custom Provider
Implement resource-bound token verification and claim mapping.
Middleware
Apply shared authorization checks.