A production-ready MCP server template authenticating users via WorkOS AuthKit. Implements bearer token authentication with Dynamic Client Registration for zero-config MCP client integration. Supports organizations out of the box.
- OAuth 2.0 with Dynamic Client Registration — MCP clients self-register, no pre-config required
- JWT verification — JWKS-based verification using WorkOS's public keys
- Bearer token authentication — verified WorkOS access tokens on every MCP request
- Multi-tenant support — organization-scoped authentication via
organization_id - Zero server-side OAuth code — clients talk to WorkOS directly; your server only verifies
WorkOS AuthKit is a complete authentication solution that handles user authentication (email/password, SSO, social), session management, OAuth 2.0 server, and Dynamic Client Registration. For MCP, AuthKit is your authorization server — your MCP server just verifies the tokens it issues.
- Node.js 20+ (22 recommended)
- pnpm 10+
- A WorkOS account — sign up at workos.com
- An AuthKit project — follow the AuthKit Quickstart to set one up
From the WorkOS Dashboard:
- Note your AuthKit subdomain under Connect → Configuration (e.g.
imaginative-palm-54-staging.authkit.app) - Copy your API key from the API Keys tab (starts with
sk_test_orsk_live_)
REQUIRED. Without DCR, MCP clients cannot register and OAuth will fail with CORS errors.
In the WorkOS Dashboard:
- Go to Connect → Configuration
- Enable Dynamic Client Registration
- Save your changes
cp .env.example .envMCP_USE_OAUTH_WORKOS_SUBDOMAIN=your-subdomain.authkit.app
WORKOS_API_KEY=sk_test_...pnpm install
pnpm devThe server starts on port 3000 with the inspector at http://localhost:3000/inspector.
- Open http://localhost:3000/inspector
- Connect to
http://localhost:3000/mcp - Sign in via WorkOS (you'll be redirected to your AuthKit subdomain)
- Call the available tools
| Tool | Description |
|---|---|
get-user-info |
Returns user id, email, name, and organization id (from JWT) |
get-user-permissions |
Returns roles, permissions, and scopes (from JWT) |
get-workos-user |
Fetches the full user profile from WorkOS using WORKOS_API_KEY |
WorkOS handles all OAuth operations directly with the MCP client. Your server only publishes resource metadata and verifies bearer tokens.
MCP Client ──(1) MCP request without token ─▶ MCP Server ──▶ 401 + WWW-Authenticate
MCP Client ──(2) GET /.well-known/oauth-protected-resource ─▶ MCP Server (points at WorkOS)
MCP Client ──(3) GET /.well-known/oauth-authorization-server ─▶ WorkOS
MCP Client ──(4) Dynamic Client Registration ─▶ WorkOS
MCP Client ──(5) PKCE authorization + token exchange ─▶ WorkOS
MCP Client ──(6) MCP request + Bearer <jwt> ─▶ MCP Server (verifies via WorkOS JWKS)
The provider auto-configures all WorkOS endpoints from your subdomain:
- Issuer:
https://{subdomain} - Authorization:
https://{subdomain}/oauth2/authorize - Token:
https://{subdomain}/oauth2/token - JWKS:
https://{subdomain}/oauth2/jwks
WorkOS AuthKit supports organizations natively. The organization_id claim is exposed via ctx.auth.user.organization_id — use it to scope data per-tenant in your tools.
npx mcp-use deployProduction checklist:
- Use a production API key (
sk_live_...) - Always run over HTTPS
- Rotate API keys regularly
- Monitor authentication logs in the WorkOS Dashboard
- CORS errors during registration — Dynamic Client Registration is not enabled. Toggle it on in WorkOS Dashboard → Connect → Configuration.
- All tool calls return 401 — confirm
MCP_USE_OAUTH_WORKOS_SUBDOMAINis the full AuthKit domain (e.g.my-company.authkit.app, not justmy-company); confirmWORKOS_API_KEYis valid. - JWT verification fails — double-check the subdomain matches your AuthKit instance exactly; tokens typically expire after 1 hour.
- OAuth metadata not found — verify
http://localhost:3000/.well-known/oauth-protected-resourcereturns JSON.
- WorkOS AuthKit Documentation
- WorkOS MCP Integration Guide
- mcp-use docs
- MCP Authorization spec
- RFC 7591 — Dynamic Client Registration
MIT