Auth0
The Auth0 plugin provides authentication for your MCP server using Auth0 with scope-based authorization.
Installation
Install the Auth0 plugin:
Auth0 Tenant Setup
MCP clients use Dynamic Client Registration (DCR) and the OAuth 2.0 Resource Parameter to authenticate. Your Auth0 tenant requires specific configuration for this to work.
1. Enable Dynamic Client Registration
MCP clients register themselves automatically with your Auth0 tenant.
- Go to Auth0 Dashboard → Settings → Advanced
- Enable "OIDC Dynamic Application Registration"
- Save changes.
2. Enable Resource Parameter Compatibility Profile
- Go to Auth0 Dashboard → Settings → Advanced
- Enable "Resource Parameter Compatibility Profile"
- Save changes.
3. Promote Connection to Domain Level
DCR-registered clients are third-party by default and can only use domain-level connections.
- Go to Auth0 Dashboard → Authentication → Database
- Select your connection (e.g.,
Username-Password-Authentication) - Enable "Enable for third-party clients" (or "Promote to domain level")
- Save changes.
4. Create the API
- Go to Auth0 Dashboard → Applications → APIs
- Click Create API
- Set:
- Name: e.g.,
MCP Server API - Identifier: Your server URL (for development we will use
http://localhost:3001/)
- Name: e.g.,
5. Set Default Audience
- Go to Auth0 Dashboard → Settings → General
- Under API Authorization Settings, set Default Audience to your API identifier.
- Save changes.
6. Note your Domain, Client ID, and Client Secret
- In your Dashboard, go to Applications and create an M2M application.
- Go to Settings and under Basic Information, you will find your Domain (following the format
<tenant>.<region>.auth0.com), Client ID, and Client Secret. - Save these values in your environment variables under
DOMAIN,CLIENT_ID, andCLIENT_SECRET.
7. Enable Management API
Required for permission checking. The plugin queries Auth0 to determine which tools require permissions.
- In your M2M application, go to APIs tab
- Enable Auth0 Management API
- Grant the following permissions:
read:resource_servers: Check which tool permissions are definedread:users: Verify user has the required permissions
Environment Variables
Configure the following environment variables in your .env file:
AUDIENCE must match your Auth0 API identifier.
Set up the Provider
Create a middleware.ts file in your xmcp app's src directory:
Configuration Options
domain: Your Auth0 domain (e.g.,your-tenant.auth0.com)audience: The API identifier configured in Auth0.baseURL: Base URL of your MCP server.clientId: Application client ID.clientSecret: Application client secret.scopesSupported: (Optional) Array of additional OAuth scopes beyond the defaults (openid,profile,email)management: (Optional) Override configuration for the Management API.audience: (Optional) Custom audience for the Management API.resourceServerIdentifier: (Optional) Resource server identifier.
Public vs Protected tools
By default, all tools are public and accessible by any user that is authenticated. This means any user with a valid Auth0 token can access the tool, regardless of their roles or permissions.
Use public tools for:
- General-purpose utilities that all users need.
- Non-sensitive operations like greeting users or displaying public information.
- Tools that don't access or modify restricted resources.
Protected Tools
Protected tools require specific permissions to access. Use them to restrict sensitive operations to authorized users only.
Use protected tools for:
- Operations that modify critical resources.
- Features limited to specific user tiers or roles.
- Access to Token Vault.
How It Works
The plugin queries Auth0 Management API on each request:
- xmcp constructs the permission name as
tool:<name>using the tool'smetadata.name - Check if permission exists → queries
read:resource_serversto see iftool:<name>is defined - If permission exists → queries
read:usersto verify the user has it assigned - If permission does not exist → tool is public, any authenticated user can access
Users without the required permission will see: "You don't have permission to use the 'tool-name' tool."
If Management API calls fail, the secure default is to deny access.
Configure roles and RBAC for protected tools
This section is optional, only needed when you want to use permission-protected tools.
Enable RBAC
- Go to Auth0 Dashboard → Applications → APIs → your API
- Go to Settings tab
- Enable "Enable RBAC"
- Enable "Add Permissions in the Access Token"
- Save changes
Create Roles and Assign Permissions
- Go to Auth0 Dashboard → User Management → Roles
- Click Create Role (e.g., "MCP Admin")
- Go to Permissions tab → Add Permissions
- Select your API and add permissions (e.g.,
tool:greet,tool:whoami) - Go to Users tab → Add Users to assign the role to users
Get a user session
Access the authenticated user's session in your tools using getAuthInfo().
Example: Greet the user with their Auth0 identity
The authInfo object contains token data and user claims:
authInfo.token: The raw access tokenauthInfo.clientId: OAuth client ID.authInfo.scopes: Array of granted scopes.authInfo.permissions: Array of additional permissions from the token.authInfo.expiresAt: Token expiration timestamp.authInfo.user.sub: User ID (subject claim).
Access the clients
The getClient() and getManagement() functions give you access to the full Auth0 SDKs, allowing you to leverage all Auth0 features in your MCP tools.
Example: Exchange tokens to call external APIs
Use getClient() to exchange tokens and call external APIs on behalf of authenticated users using Auth0's Custom Token Exchange flow:
This example demonstrates how to use getTokenByExchangeProfile() to exchange the user's MCP access token for a new token with a different audience, allowing your MCP server to call external APIs on the user's behalf.
Example: Update user metadata
The getManagement() function provides typed methods for all Auth0 Management operations and is only available when the management configuration is provided.
Troubleshooting
These are the most common errors you may encounter when using the Auth0 plugin:
unauthorized: The request is missing the Authorization header. The client needs to authenticate before accessing protected resources.token_expired: The access token has expired. MCP clients should automatically refresh tokens; users can disconnect and reconnect to get fresh tokens.invalid_token: Token verification failed. Check that your Auth0 configuration matches your tenant settings.InsufficientScopeError: The token doesn't have the required scopes for the tool. Ensure the scope is defined in your Auth0 API and requested during login.Service not found: The API identifier must match yourBASE_URLexactly, including the trailing slash. MCP clients send aresourceparameter that Auth0 uses as the audience, and any mismatch causes this error.
OAuth Init Failed
If you see "OAuth init failed" when connecting:
- Ensure Dynamic Client Registration is enabled in Auth0 Settings → Advanced
- Enable the Resource Parameter Compatibility Profile in Auth0 Settings → Advanced
Access Denied / Service Not Found
If you see "access denied" or "Service not found" errors:
- Your Auth0 API identifier must match
BASE_URLexactly (including trailing slash) - Promote your database connection to domain level (Authentication → Database → Enable for third-party clients)
- Set the Default Audience in Settings → General → API Authorization Settings
Token Expired Errors
Access tokens are short-lived. If you see token_expired errors:
- MCP clients should automatically refresh tokens
- Users can disconnect and reconnect to get fresh tokens
Invalid Token Errors
If token verification fails:
- Verify
DOMAINmatches your Auth0 tenant - Verify
AUDIENCEmatches your API identifier exactly (including trailing slash)
Permission Check Failed
If you see "You don't have permission..." errors for tools that should be public:
- Your M2M app needs
read:resource_serversandread:userspermissions on the Auth0 Management API - Ensure
CLIENT_IDandCLIENT_SECRETare set correctly - Verify the permissions are granted in the M2M app's APIs tab
Session Not Initialized
If getAuthInfo() throws an error:
- Ensure
auth0Provideris exported as default frommiddleware.ts - Ensure the tool is called on a route under
/mcp/* - Don't call
getAuthInfo()at module load time—only inside tool handlers