Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive guide for building production-ready MCP servers with tools, resources, prompts, and React widgets using mcp-use.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/authentication/auth0.md
1# Auth0 Authentication23Setting up OAuth with Auth0. Two modes depending on whether you have access to Auth0's DCR feature:45- **DCR (built-in)** → use `oauthAuth0Provider`. Requires Auth0's Early Access program.6- **OAuth proxy** → use `oauthProxy` + `jwksVerifier` with a standard Auth0 Regular Web App. No Early Access required.78**Learn more:** [Auth0 MCP Authorization Guide](https://auth0.com/ai/docs/mcp/get-started/authorization-for-your-mcp-server) · [Standalone starter template](https://github.com/mcp-use/mcp-oauth-auth0-template) · [Runnable DCR example](https://github.com/mcp-use/mcp-use/tree/main/libraries/typescript/packages/mcp-use/examples/server/oauth/auth0) · [Runnable proxy example](https://github.com/mcp-use/mcp-use/tree/main/libraries/typescript/packages/mcp-use/examples/server/oauth/auth0-proxy)910---1112## Mode 1: DCR (`oauthAuth0Provider`)1314Auth0's built-in DCR feature is currently in **Early Access**. MCP clients register and authenticate directly with Auth0. To use this, join Auth0's Early Access program — see the [Auth0 MCP Authorization Guide](https://auth0.com/ai/docs/mcp/get-started/authorization-for-your-mcp-server).1516### Setup17181. **Auth0 Dashboard → Settings → Advanced** — enable **Resource Parameter Compatibility Profile**.192. Promote connections to domain-level so third-party clients (like MCP Inspector) can use them:20```bash21auth0 api get connections22auth0 api patch connections/YOUR_CONNECTION_ID --data '{"is_domain_connection": true}'23```243. Create an API with the `rfc9068_profile_authz` token dialect (this adds `permissions` to the access token):25```bash26auth0 api post resource-servers --data '{27"identifier": "https://your-api.example.com",28"name": "MCP Tools API",29"signing_alg": "RS256",30"token_dialect": "rfc9068_profile_authz",31"enforce_policies": true,32"scopes": [{"value": "read:data", "description": "Read data"}]33}'34```3536### Quick Start3738```typescript39import { MCPServer, oauthAuth0Provider, object } from "mcp-use/server";4041const server = new MCPServer({42name: "my-server",43version: "1.0.0",44oauth: oauthAuth0Provider(), // reads MCP_USE_OAUTH_AUTH0_DOMAIN + _AUDIENCE45});4647server.tool(48{ name: "whoami", description: "Get authenticated user info" },49async (_args, ctx) =>50object({51userId: ctx.auth.user.userId,52email: ctx.auth.user.email,53permissions: ctx.auth.permissions,54})55);5657server.listen();58```5960With a `.env` file:6162```bash63MCP_USE_OAUTH_AUTH0_DOMAIN=your-tenant.auth0.com64MCP_USE_OAUTH_AUTH0_AUDIENCE=https://your-api.example.com65```6667### Configuration Options6869Zero-config (reads from env vars):7071```typescript72oauth: oauthAuth0Provider()73```7475Explicit config:7677```typescript78oauth: oauthAuth0Provider({79domain: "your-tenant.auth0.com",80audience: "https://your-api.example.com",81verifyJwt: process.env.NODE_ENV === "production", // default: true82scopesSupported: ["openid", "profile", "email", "offline_access"],83})84```8586| Option | Type | Default | Description |87|--------|------|---------|-------------|88| `domain` | `string` | env var | Auth0 tenant domain (e.g. `your-tenant.auth0.com`) |89| `audience` | `string` | env var | Auth0 API identifier |90| `verifyJwt` | `boolean?` | `true` | Set `false` to skip JWT verification (**development only**) |91| `scopesSupported` | `string[]?` | `["openid", "profile", "email", "offline_access"]` | Override advertised scopes |9293---9495## Mode 2: OAuth Proxy (`oauthProxy`)9697Use a standard Auth0 **Regular Web Application** — no Early Access required. Your server mediates the token exchange using pre-registered credentials.9899### Setup1001011. **Auth0 Dashboard → Applications → Create Application** — choose **Regular Web Application**.1022. Under **Allowed Callback URLs**, add your MCP client's redirect URI (e.g. `http://localhost:3000/inspector/oauth/callback`).1033. Copy the **Client ID** and **Client Secret**.1044. **APIs → Create API** — set an identifier (e.g. `https://my-mcp-api/`), leave signing as RS256. This is required so Auth0 issues **JWT** access tokens instead of opaque tokens.105106### Quick Start107108```typescript109import { MCPServer, oauthProxy, jwksVerifier, object } from "mcp-use/server";110111const domain = process.env.AUTH0_DOMAIN!;112const audience = process.env.AUTH0_AUDIENCE ?? "";113114const server = new MCPServer({115name: "my-server",116version: "1.0.0",117oauth: oauthProxy({118authEndpoint: `https://${domain}/authorize`,119tokenEndpoint: `https://${domain}/oauth/token`,120issuer: `https://${domain}/`,121clientId: process.env.AUTH0_CLIENT_ID!,122clientSecret: process.env.AUTH0_CLIENT_SECRET,123scopes: ["openid", "email", "profile"],124extraAuthorizeParams: { audience }, // required for JWT access tokens125verifyToken: jwksVerifier({126jwksUrl: `https://${domain}/.well-known/jwks.json`,127issuer: `https://${domain}/`,128audience,129}),130}),131});132133server.tool(134{ name: "whoami", description: "Get authenticated user info" },135async (_args, ctx) =>136object({137userId: ctx.auth.user.userId,138email: ctx.auth.user.email,139scopes: ctx.auth.scopes,140})141);142143server.listen();144```145146With a `.env` file:147148```bash149AUTH0_DOMAIN=your-tenant.us.auth0.com150AUTH0_CLIENT_ID=<from Regular Web App>151AUTH0_CLIENT_SECRET=<from Regular Web App>152AUTH0_AUDIENCE=https://my-mcp-api/153```154155> **Why `extraAuthorizeParams: { audience }`?** Without the `audience` parameter on `/authorize`, Auth0 issues opaque access tokens (no JWT, can't be verified locally). The audience turns it into a standard JWT signed by your API.156157See [custom.md](custom.md) for full `oauthProxy` options.158159---160161## Accessing user info in tools162163```typescript164server.tool(165{ name: "get-user-info", description: "Get authenticated user info" },166async (_args, ctx) =>167object({168userId: ctx.auth.user.userId,169email: ctx.auth.user.email,170name: ctx.auth.user.name,171nickname: ctx.auth.user.nickname,172picture: ctx.auth.user.picture,173permissions: ctx.auth.permissions,174scopes: ctx.auth.scopes,175})176);177```178179---180181## Permissions182183Auth0 includes permissions directly in the access token when you use the `rfc9068_profile_authz` token dialect. Check them in tool callbacks:184185```typescript186server.tool(187{188name: "delete-document",189description: "Delete a document (requires delete:documents)",190},191async ({ documentId }, ctx) => {192if (!ctx.auth.permissions?.includes("delete:documents")) {193return error("Forbidden: delete:documents permission required");194}195196await db.documents.delete({ id: documentId });197return text("Document deleted");198}199);200```201202---203204## Which mode should I use?205206| | DCR (`oauthAuth0Provider`) | Proxy (`oauthProxy`) |207|---|---|---|208| Requires Early Access | Yes | No |209| MCP clients self-register | Yes | No (single pre-registered app) |210| Your server mediates `/token` | No | Yes |211| Best for | Multi-client public MCP servers | Private/internal MCP servers |212213If you aren't on the Auth0 DCR Early Access, use the proxy.214215---216217## Next Steps218219- **Auth overview** → [overview.md](overview.md)220- **Custom providers + OAuth proxy reference** → [custom.md](custom.md)221- **WorkOS setup** → [workos.md](workos.md)222- **Build tools** → [../server/tools.md](../server/tools.md)223