UNPKG

@auth0/auth0-mcp-server

Version:

Auth0 Model Context Protocol (MCP) Server (Beta) — A secure and extendable implementation of an MCP server that provides AI assistants with controlled access to the Auth0 Management API through natural language. This project is in beta and not intended fo

133 lines • 5.46 kB
import { clients } from '../clients/index.js'; import { log, logError } from '../utils/logger.js'; import { requestAuthorization } from '../auth/device-auth-flow.js'; import { requestClientCredentialsAuthorization } from '../auth/client-credentials-flow.js'; import { promptForScopeSelection } from '../utils/terminal.js'; import { getAllScopes } from '../utils/scopes.js'; import { Glob } from '../utils/glob.js'; import chalk from 'chalk'; import trackEvent from '../utils/analytics.js'; /** * Resolves scope patterns to actual scope values * * @param {string[] | undefined} scopePatterns - Scope patterns from command line * @returns {Promise<string[]>} - The selected scopes */ async function resolveScopes(scopePatterns) { // If no scopes provided, prompt user for selection if (!scopePatterns?.length) { return promptForScopeSelection(); } const allAvailableScopes = getAllScopes(); const matchedScopes = new Set(); const invalidScopes = new Set(); // Match patterns against available scopes for (const pattern of scopePatterns) { let foundMatch = false; const glob = new Glob(pattern); for (const scope of allAvailableScopes) { if (glob.matches(scope)) { matchedScopes.add(scope); foundMatch = true; } } // Track non-wildcard patterns that didn't match anything if (!glob.hasWildcards() && !foundMatch) { invalidScopes.add(pattern); } } // Handle invalid scopes if (invalidScopes.size > 0) { const errorMessage = `Error: The following scopes are not valid: ${Array.from(invalidScopes).join(', ')}`; logError(errorMessage); logError(chalk.yellow(`Valid scopes are: ${allAvailableScopes.join(', ')}`)); process.exit(1); } // Handle matched scopes const matchedScopesArray = Array.from(matchedScopes); if (matchedScopesArray.length === 0) { log(chalk.yellow('No scopes matched the provided patterns, proceeding to scope selection.')); return promptForScopeSelection(); } return promptForScopeSelection(matchedScopesArray); } /** * Configures the specified client with options * * @param {ClientType} clientType - Type of the client to configure * @param {InitOptions} options - Configuration options */ async function configureClient(clientType, options) { const manager = clients[clientType]; if (!manager) { logError(`Invalid client type specified: ${clientType}`); logError(`Available clients are: ${Object.keys(clients).join(', ')}`); process.exit(1); } log(`Configuring ${manager.displayName} as client...`); const clientOptions = { tools: options.tools, readOnly: options.readOnly, }; await manager.configure(clientOptions); } /** * Initializes the Auth0 MCP server with the specified client, tools and scopes. * * This function orchestrates the complete initialization process by: * 1. Resolving and validating requested scopes * 2. Obtaining authorization through the device flow * 3. Configuring the selected client (Claude, Claude Code, Windsurf, Cursor, VS Code or Gemini CLI) * * @param {InitOptions} options - Configuration options including: * - client: The target client type to configure ('claude', 'claude-code', 'windsurf', 'cursor', 'vscode' or 'gemini') * - scopes: Optional scope patterns for authorization (will prompt if omitted) * - tools: Tool patterns to enable (e.g., ['auth0_list_*']) * - (no-)interaction: Should the CLI prompt the user to press return to open the browser * * @returns {Promise<void>} A promise that resolves when initialization is complete * * @throws {Error} If authorization fails or client configuration encounters an error * * @example * // Initialize with Claude client and all tools * await init({ client: 'claude', tools: ['*'] }); * * @example * // Initialize with Windsurf client and specific tools * await init({ * client: 'windsurf', * tools: ['auth0_list_*', 'auth0_get_*'], * scopes: ['read:*'] * }); */ const init = async (options) => { log('Initializing Auth0 MCP server...'); log(`Configuring server with selected tools: ${options.tools.join(', ')}`); if (options.readOnly) { log('Running in read-only mode - only read operations will be available'); } trackEvent.trackInit(options.client); // Check if client credentials parameters are provided for Private Cloud authentication const { auth0Domain, auth0ClientId, auth0ClientSecret } = options; if (auth0Domain && auth0ClientId && auth0ClientSecret) { // Client credentials flow for Private Cloud log('Using client credentials flow for authentication'); await requestClientCredentialsAuthorization({ auth0Domain: auth0Domain, auth0ClientId: auth0ClientId, auth0ClientSecret: auth0ClientSecret, }); } else { // Device authorization flow for public cloud log('Using device authorization flow for authentication'); // Handle scope resolution const selectedScopes = await resolveScopes(options.scopes); await requestAuthorization(selectedScopes, options.interaction); } // Configure the requested client await configureClient(options.client, options); }; export default init; //# sourceMappingURL=init.js.map