1
Set the signing secret
Must match your authorization server’ssigningSecret. Pass it by environment variable, not on the command line.2
Start the gateway
--mcp-resource is the token audience: your authorization server must set it as aud. Terminate TLS in front and route the public URL to port 3000.3
What MCP mode does
Per route scopes and agent policy
requiredPermissions checks the agent in the agent_id claim, against the gateway’s TheAuth database. No agent_id means 403. Use requiredScopes for tokens not tied to an agent.
Embedded mode
For a same-process authorization server or a revocation list, pass the real module.requireMcpAuth and getProtectedResourceMetadata are used, so a shared-key validation module is enough. The CLI does this.
Limits
- Path level only. Tool names sit in the unparsed JSON-RPC body. Enforce per tool rules upstream or split routes.
- The CLI cannot see revocations. Tokens stay valid until
exp. Use short lifetimes, or embedded mode with a sharedjtiDenylist. - HS256 shared secret. Anyone holding it can mint tokens. The CLI does not fetch JWKS.
- Not an authorization server. Registration, login, consent and issuing stay upstream.
- Well-known paths are shadowed. Upstream
/.well-known/oauth-protected-resourceroutes never run. - Sessions are not bound to tokens.
Mcp-Session-Idpasses through, and a second authenticated client that learns an ID could use it. Treat IDs as secrets. - Audit only with
agent_id. Other OAuth tokens are enforced but not logged. - Rate limits are in memory, per process.
- HTTP only. No TLS or WebSocket. The legacy stdio transport is out of scope.
- Not tested with a real MCP client. Unit and local socket tests only. Add headers missing from the default list to
cors.headers.