1
Create the authorization module
Storage is passed as callbacks. The in-memory maps are for illustration; back them with your own database.auth.ts
2
Mount the OAuth endpoints
The adapter serves the metadata routes,POST /mcp/register, GET /mcp/authorize and POST /mcp/token. The client then exchanges its code with the PKCE verifier and the resource. The full endpoint table is in MCP OAuth 2.1.server.ts
3
Wrap the MCP routes
requireMcpAuth checks the signature, issuer, expiry and audience, then the scopes you name. It runs your handler only when all of those pass, and passes in the verified principal.server.ts
userId, clientId, agent, delegationChain, scopes, resource, tokenId and expiresAt. Use principal.userId for ownership checks. Do not trust a user id from the request body.4
Mount revocation
The TypeScript adapters do not serve/mcp/revoke by default, so pass the request to mcp.revoke yourself.server.ts
5
Check the result
A request with no token gets a 401 and aWWW-Authenticate challenge that points at the protected resource metadata. A valid token runs the handler.What is enforced
For agent tokens, set
tokenExchange and jtiDenylist in the MCP config. See MCP server grants. The Go version of this flow on SQLite is OAuth 2.1 on SQLite, which is Go only.