OAuth 2.1 for MCP clients
The deployment is a spec-compliant OAuth 2.1 protected resource, so MCP clients that speak the MCP authorization spec (claude.ai custom Connectors, MCP Inspector, …) can connect with no pre-shared token — just the endpoint URL (https://<host>/mcp). A signed-in human approves scoped access on a consent page.
The flow
- An unauthenticated
POST /mcpreturns401withWWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource". - That metadata (RFC 9728) names the api as the authorization server; its RFC 8414 metadata at
/.well-known/oauth-authorization-serveradvertises the endpoints. - The client registers itself (RFC 7591 dynamic client registration,
POST /api/oauth/register), then sends the user toGET /api/oauth/authorize(PKCE S256 required). The RFC 8707resourceparameter is required and must equal the deployment's MCP resource URL (MCP_PUBLIC_URL, the same URL the protected-resource metadata advertises) — any other value is rejected withinvalid_target. - The user signs in (existing account) and approves the requested scopes on the consent page.
- The client exchanges the code at
POST /api/oauth/tokenand calls/mcpwith the resulting Bearer token. Refresh tokens rotate on every use; reusing a rotated refresh token revokes the whole grant (and its live access tokens).
What the tokens are
OAuth-issued access tokens are ordinary scoped tokens on the consenting human — same scopes, same per-token rate limits — short-lived (1 h) and silently renewed via refresh. Two OAuth-specific behaviors:
- Audience-bound (RFC 8707). They are bound to the resource the grant named, so they are only accepted at that MCP endpoint. Hand-minted
kbt_tokens carry no audience and are unaffected. - Grant-scoped revocation. Revoking one (
DELETE /api/tokens/:id) revokes the entire grant — refresh token included — so the client can't mint a replacement.
Scopes
The default grant is boards:read boards:write cards:read cards:write comments:write. A client may request a narrower/different set with the scope parameter. tokens:write can never be granted over OAuth — delegation chains stay rooted in an explicit human mint.
Configuration
MCP_PUBLIC_URL— the RFC 9728 resource identifier; grants are bound to it.PUBLIC_BASE_URL— the public origin; base of the advertised metadata URLs.OAUTH_ISSUER_URL— the issuer identifier (defaults toPUBLIC_BASE_URL).
See Configuration. For the non-OAuth transports (Bearer token, stdio proxy) see MCP.