How to Configure the Auth0 MCP Server for Private Cloud Tenants Using Client Credentials

To configure the Auth0 MCP Server for Private Cloud tenants, pass the --auth0-domain, --auth0-client-id, and --auth0-client-secret options to the init command, which automatically switches authentication from the default device flow to the OAuth client-credentials grant.

The auth0/auth0-mcp-server repository enables AI assistants to manage Auth0 tenants through the Model Context Protocol (MCP). While public cloud tenants use an interactive device authorization flow, Private Cloud environments require you to configure the Auth0 MCP Server using client credentials for non-interactive authentication.

Authentication Flow Overview

The MCP server supports two distinct authentication methods depending on your tenant type:

  • Device Authorization Flow: The default interactive flow for public cloud tenants where users authenticate via a browser.
  • Client Credentials Flow: Required for Private Cloud tenants where interactive browser-based authentication is not available or permitted.

When you provide the three credential parameters during initialization, the server detects Private Cloud mode and bypasses the device flow entirely, obtaining an access token directly through the OAuth 2.0 client-credentials grant.

Prerequisites for Private Cloud Setup

Before initializing the server for a Private Cloud tenant, ensure you have:

  1. Domain: Your Private Cloud tenant domain (e.g., my-tenant.private.auth0.com)
  2. Client ID: An Auth0 application client ID with the client-credentials grant enabled
  3. Client Secret: The corresponding client secret for the application
  4. Audience: Optional. Defaults to https://<domain>/api/v2/ if not specified

Step-by-Step Configuration

Initialize via CLI

Run the init command with all three authentication parameters to trigger the client-credentials flow:

auth0-mcp init \
  --client claude \
  --tools '*' \
  --auth0-domain my-tenant.private.auth0.com \
  --auth0-client-id A1B2C3D4E5F6G7H8I9J0 \
  --auth0-client-secret superSecretValue123

This command calls the initialization logic in src/commands/init.ts, detects the presence of the credential triad (lines 43-47), and logs "Using client credentials flow for authentication" before proceeding.

Initialize Programmatically

You can also configure the server programmatically using TypeScript:

import init from './src/commands/init.js';

await init({
  client: 'windsurf',
  tools: ['auth0_list_*', 'auth0_get_*'],
  auth0Domain: 'my-tenant.private.auth0.com',
  auth0ClientId: 'A1B2C3D4E5F6G7H8I9J0',
  auth0ClientSecret: 'superSecretValue123',
});

The init function checks for auth0Domain, auth0ClientId, and auth0ClientSecret properties and routes to requestClientCredentialsAuthorization when all three are present.

How the Client Credentials Flow Works

Understanding the internal mechanism helps troubleshoot configuration issues. The flow follows these steps according to the source code:

Detection and Routing

In src/commands/init.ts (lines 43-47), the CLI inspects the options object. If auth0Domain, auth0ClientId, and auth0ClientSecret are all provided, the server immediately selects the client-credentials path instead of the interactive device flow.

Token Acquisition

The function requestClientCredentialsAuthorization in src/auth/client-credentials-flow.ts (lines 30-48) handles the OAuth exchange:

// Simplified representation of the flow
const authClient = await getAuthenticationClient(domain, clientId, clientSecret);
const { data } = await authClient.oauth.clientCredentialsGrant({
  audience: `https://${domain}/api/v2/`,  // Defaults to Management API v2
});

If the audience parameter is omitted, the code automatically constructs the default Auth0 Management API v2 endpoint for your domain.

Secure Storage

The received tokens are persisted in the system keychain via src/utils/keychain.ts (lines 60-78):

  • keychain.setToken(data.access_token) stores the bearer token
  • keychain.setDomain(domain) saves the tenant domain
  • keychain.setTokenExpiresAt(Date.now() + data.expires_in * 1000) records expiration

This ensures credentials survive server restarts without residing in plain text files.

Configuration Validation

Before each API call, the server uses loadConfig and validateConfig from src/utils/config.ts to verify that:

  • A domain is configured
  • The access token exists in the keychain
  • The token has not expired

If validation fails, the server prompts you to re-run the initialization command.

Verifying Your Configuration

After initialization, confirm that credentials are properly stored and valid:

import { loadConfig, validateConfig } from './src/utils/config.js';

const cfg = await loadConfig();
if (await validateConfig(cfg)) {
  console.log('MCP is ready – token valid for domain', cfg?.domain);
} else {
  console.error('Configuration invalid – re-run `auth0-mcp init` with correct credentials');
}

A successful validation indicates the MCP server can now call the Auth0 Management API on your Private Cloud tenant.

Summary

  • Private Cloud tenants must use the client-credentials flow because they cannot execute the interactive device authorization flow.
  • Trigger the flow by providing --auth0-domain, --auth0-client-id, and --auth0-client-secret to the init command or programmatic init function.
  • Automatic detection occurs in src/commands/init.ts when all three credential parameters are present.
  • Token management happens automatically through src/auth/client-credentials-flow.ts and secure storage in src/utils/keychain.ts.
  • Validation ensures the server only starts when valid credentials are available in the system keychain.

Frequently Asked Questions

What is the difference between device flow and client credentials in the Auth0 MCP Server?

Device flow requires a user to authenticate through a browser and enter a device code, which is suitable for public cloud tenants. Client credentials use a machine-to-machine OAuth grant where the server authenticates directly using a client ID and secret, which is required for Private Cloud tenants that cannot run interactive browser sessions.

How do I know if my tenant requires client credentials authentication?

If your tenant uses a Private Cloud deployment (typically domains ending in .private.auth0.com or custom private domains) and lacks public internet access for browser-based authentication, you must use client credentials. Public cloud tenants (e.g., tenant.auth0.com) can use the default device flow.

Where are the credentials stored after running the init command?

The access token, domain, and expiration timestamp are stored in your operating system's secure keychain using the functions in src/utils/keychain.ts (lines 60-78). The client secret is used only during the initial token exchange and is not persisted to disk.

Can I switch from device flow to client credentials without reinstalling the server?

Yes. Simply re-run the auth0-mcp init command with the --auth0-domain, --auth0-client-id, and --auth0-client-secret parameters. The new credentials will overwrite the existing device-flow tokens in the keychain, and the server will use the client-credentials flow for subsequent API calls.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →