> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcp-use.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Auth0 Provider

> Configure Auth0 OAuth 2.1 authentication for your MCP server

Auth0 supports two integration modes depending on whether you have access to Auth0's Dynamic Client Registration (DCR) feature.

<Tabs>
  <Tab title="DCR (Built-in)">
    Auth0's built-in DCR feature is currently in **Early Access**. MCP clients register and authenticate directly with Auth0

    <Note>
      To use the built-in Auth0 provider, you need to 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) for details on how to get access.
    </Note>

    ## Auth0 Setup

    ### 1. Configure your tenant

    In the [Auth0 Dashboard](https://manage.auth0.com):

    1. Go to **Settings → Advanced** and enable **Resource Parameter Compatibility Profile**
    2. Promote connections to domain-level so third-party clients (like MCP Inspector) can use them:
       ```bash theme={null}
       # List connections to get their IDs
       auth0 api get connections

       # Promote a connection (e.g. username-password database)
       auth0 api patch connections/YOUR_CONNECTION_ID --data '{"is_domain_connection": true}'
       ```

    ### 2. Create an API

    ```bash theme={null}
    auth0 api post resource-servers --data '{
      "identifier": "https://your-api.example.com",
      "name": "MCP Tools API",
      "signing_alg": "RS256",
      "token_dialect": "rfc9068_profile_authz",
      "enforce_policies": true,
      "scopes": [
        {"value": "read:data", "description": "Read data"}
      ]
    }'
    ```

    The `rfc9068_profile_authz` token dialect includes the `permissions` claim in access tokens, enabling scope-based access control.

    ### 3. Environment variables

    ```bash theme={null}
    MCP_USE_OAUTH_AUTH0_DOMAIN=your-tenant.auth0.com
    MCP_USE_OAUTH_AUTH0_AUDIENCE=https://your-api.example.com
    ```

    ## Configuration

    ```typescript theme={null}
    import { MCPServer, oauthAuth0Provider } from 'mcp-use/server'

    // Zero-config: reads MCP_USE_OAUTH_AUTH0_DOMAIN and MCP_USE_OAUTH_AUTH0_AUDIENCE
    const server = new MCPServer({
      name: 'my-server',
      version: '1.0.0',
      oauth: oauthAuth0Provider()
    })

    await server.listen(3000)
    ```

    Or pass config explicitly:

    ```typescript theme={null}
    oauth: oauthAuth0Provider({
      domain: 'your-tenant.auth0.com',
      audience: 'https://your-api.example.com',

      // Disable JWT verification during development only
      verifyJwt: process.env.NODE_ENV === 'production',

      // Override advertised scopes
      scopesSupported: ['openid', 'profile', 'email', 'offline_access'],
    })
    ```
  </Tab>

  <Tab title="OAuth Proxy">
    Use `oauthProxy` with a standard Auth0 **Regular Web Application**  -  no Early Access required. Your server mediates the token exchange using pre-registered credentials.

    ## Auth0 Setup

    ### 1. Create a Regular Web Application

    In the [Auth0 Dashboard](https://manage.auth0.com):

    1. Go to **Applications → Create Application**
    2. Choose **Regular Web Application**
    3. Under **Allowed Callback URLs**, add your MCP client's redirect URI:
       ```
       http://localhost:3000/inspector/oauth/callback
       ```
    4. Copy the **Client ID** and **Client Secret**

    ### 2. Create an API

    This gives you JWT access tokens (required  -  opaque tokens can't be verified locally):

    1. Go to **APIs → Create API**
    2. Set an identifier, e.g. `https://my-mcp-api/`
    3. Leave signing algorithm as RS256

    ### 3. Environment variables

    ```bash theme={null}
    AUTH0_DOMAIN=your-tenant.us.auth0.com
    AUTH0_CLIENT_ID=<from Regular Web App>
    AUTH0_CLIENT_SECRET=<from Regular Web App>
    AUTH0_AUDIENCE=https://my-mcp-api/
    ```

    ## Configuration

    ```typescript theme={null}
    import { MCPServer, oauthProxy, jwksVerifier } from 'mcp-use/server'

    const domain = process.env.AUTH0_DOMAIN!
    const audience = process.env.AUTH0_AUDIENCE ?? ''

    const server = new MCPServer({
      name: 'my-server',
      version: '1.0.0',
      oauth: oauthProxy({
        authEndpoint: `https://${domain}/authorize`,
        tokenEndpoint: `https://${domain}/oauth/token`,
        issuer: `https://${domain}/`,
        clientId: process.env.AUTH0_CLIENT_ID!,
        clientSecret: process.env.AUTH0_CLIENT_SECRET,
        scopes: ['openid', 'email', 'profile'],
        extraAuthorizeParams: { audience },
        verifyToken: jwksVerifier({
          jwksUrl: `https://${domain}/.well-known/jwks.json`,
          issuer: `https://${domain}/`,
          audience,
        }),
      }),
    })

    await server.listen(3000)
    ```

    The OAuth flow in proxy mode:

    ```
    Client → /register         → receives pre-registered client_id
    Client → /authorize        → MCP server redirects to Auth0 /authorize
    Auth0  → redirect_uri      → returns authorization code to client
    Client → /token            → MCP server injects credentials, forwards to Auth0
    Auth0  → access_token (JWT)→ returned to client
    Client → /mcp/...          → MCP server verifies JWT via Auth0 JWKS
    ```
  </Tab>
</Tabs>

## Accessing user info in tools

```typescript theme={null}
server.tool(
  {
    name: 'get-user-info',
    description: 'Get authenticated user info',
  },
  async (_args, ctx) => ({
    userId: ctx.auth.user.userId,
    email: ctx.auth.user.email,
    name: ctx.auth.user.name,
    nickname: ctx.auth.user.nickname,
    picture: ctx.auth.user.picture,
    permissions: ctx.auth.permissions,
    scopes: ctx.auth.scopes,
  })
)
```

## Permissions

Auth0 includes permissions directly in the access token when you use the `rfc9068_profile_authz` token dialect. Check them in tool callbacks:

```typescript theme={null}
server.tool(
  {
    name: 'delete-document',
    description: 'Delete a document (requires delete:documents)',
  },
  async ({ documentId }, ctx) => {
    if (!ctx.auth.permissions?.includes('delete:documents')) {
      return { content: [{ type: 'text', text: 'Forbidden: delete:documents permission required' }], isError: true }
    }

    await db.documents.delete({ id: documentId })
    return { content: [{ type: 'text', text: 'Document deleted' }] }
  }
)
```

## Resources

* [Runnable mcp-use + Auth0 DCR example](https://github.com/mcp-use/mcp-use/tree/main/libraries/typescript/packages/mcp-use/examples/server/oauth/auth0)
* [Runnable mcp-use + Auth0 proxy example](https://github.com/mcp-use/mcp-use/tree/main/libraries/typescript/packages/mcp-use/examples/server/oauth/auth0-proxy)
* [Auth0 MCP Authorization Guide](https://auth0.com/ai/docs/mcp/get-started/authorization-for-your-mcp-server)
* [Auth0 Documentation](https://auth0.com/docs)

## Next Steps

* [User Context](/typescript/server/authentication/user-context)  -  Access user information in tools
