Skip to main content
Glama
forms.ts15.4 kB
import type { HandlerConfig, HandlerRequest, HandlerResponse, Tool } from '../utils/types.js'; import { log } from '../utils/logger.js'; import { createErrorResponse, createSuccessResponse } from '../utils/http-utility.js'; import type { Auth0Config } from '../utils/config.js'; import { getManagementClient } from '../utils/auth0-client.js'; import type { PostFormsRequest } from 'auth0/dist/cjs/management/index.js'; // Define all available form tools export const FORM_TOOLS: Tool[] = [ { name: 'auth0_list_forms', description: 'List all forms in the Auth0 tenant', inputSchema: { type: 'object', properties: { page: { type: 'number', description: 'Page number (0-based)' }, per_page: { type: 'number', description: 'Number of forms per page default:50' }, include_totals: { type: 'boolean', description: 'Include total count' }, }, }, _meta: { requiredScopes: ['read:forms'], readOnly: true, }, annotations: { title: 'List Auth0 Forms', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, { name: 'auth0_get_form', description: 'Get details about a specific Auth0 form', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'ID of the form to retrieve' }, }, required: ['id'], }, _meta: { requiredScopes: ['read:forms'], readOnly: true, }, annotations: { title: 'Get Auth0 Form Details', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, { name: 'auth0_create_form', description: 'Create a new Auth0 form', inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Name of the form. Required.', }, messages: { type: 'object', description: 'Message settings for the form', }, languages: { type: 'object', description: 'Language settings for the form', }, translations: { type: 'object', description: 'Translations for form content', }, nodes: { type: 'array', description: 'Nodes defining form structure and behavior', items: { type: 'object', }, }, start: { type: 'object', description: 'Settings for form start configuration', }, ending: { type: 'object', description: 'Settings for form completion', }, style: { type: 'object', description: 'Style settings for the form', }, }, required: ['name'], }, _meta: { requiredScopes: ['create:forms'], }, annotations: { title: 'Create Auth0 Form', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false, }, }, { name: 'auth0_update_form', description: 'Update an existing Auth0 form', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'ID of the form to update. Required.', }, name: { type: 'string', description: 'Name of the form', }, messages: { type: 'object', description: 'Message settings for the form', }, languages: { type: 'object', description: 'Language settings for the form', }, translations: { type: 'object', description: 'Translations for form content', }, nodes: { type: 'array', description: 'Nodes defining form structure and behavior', items: { type: 'object', }, }, start: { type: 'object', description: 'Settings for form start configuration', }, ending: { type: 'object', description: 'Settings for form completion', }, style: { type: 'object', description: 'Style settings for the form', }, }, required: ['id'], }, _meta: { requiredScopes: ['update:forms'], }, annotations: { title: 'Update Auth0 Form', readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false, }, }, ]; // Define handlers for each form tool export const FORM_HANDLERS: Record< string, (request: HandlerRequest, config: HandlerConfig) => Promise<HandlerResponse> > = { auth0_list_forms: async ( request: HandlerRequest, config: HandlerConfig ): Promise<HandlerResponse> => { try { // Check for token if (!request.token) { log('Warning: Token is empty or undefined'); return createErrorResponse('Error: Missing authorization token'); } // Check if domain is configured if (!config.domain) { log('Error: Auth0 domain is not configured'); return createErrorResponse('Error: Auth0 domain is not configured'); } // Build query parameters const options: Record<string, any> = {}; if (request.parameters.page !== undefined) { options.page = request.parameters.page; } if (request.parameters.per_page !== undefined) { options.per_page = request.parameters.per_page; } else { // Default to 50 forms per page options.per_page = 50; } if (request.parameters.include_totals !== undefined) { options.include_totals = request.parameters.include_totals; } else { // Default to include totals options.include_totals = true; } try { const managementClientConfig: Auth0Config = { domain: config.domain, token: request.token, }; const managementClient = await getManagementClient(managementClientConfig); log(`Fetching forms with supplied options`); // Use the Auth0 SDK to get all forms const { data: responseData } = await managementClient.forms.getAll(options); // Handle different response formats log(`Successfully retrieved forms`); if (!responseData) { return createSuccessResponse({ message: 'No forms found matching your criteria.', forms: [], }); } return createSuccessResponse(responseData); } catch (sdkError: any) { // Handle SDK errors log('Auth0 SDK error'); let errorMessage = `Failed to list forms: ${sdkError.message || 'Unknown error'}`; // Add context based on common error codes if (sdkError.statusCode === 401) { errorMessage += '\nError: Unauthorized. Your token might be expired or invalid or missing read:branding scope.'; } else if (sdkError.statusCode === 403) { errorMessage += '\nError: Forbidden. Your token might not have the required scopes (read:branding).'; } return createErrorResponse(errorMessage); } } catch (error: any) { // Handle any other errors log('Error processing request'); return createErrorResponse( `Error: ${error instanceof Error ? error.message : String(error)}` ); } }, auth0_get_form: async ( request: HandlerRequest, config: HandlerConfig ): Promise<HandlerResponse> => { try { const id = request.parameters.id; if (!id) { return createErrorResponse('Error: id is required'); } // Check for token if (!request.token) { log('Warning: Token is empty or undefined'); return createErrorResponse('Error: Missing authorization token'); } // Check if domain is configured if (!config.domain) { log('Error: Auth0 domain is not configured'); return createErrorResponse('Error: Auth0 domain is not configured'); } try { const managementClientConfig: Auth0Config = { domain: config.domain, token: request.token, }; const managementClient = await getManagementClient(managementClientConfig); log(`Fetching form with ID: ${id}`); // Use the Auth0 SDK to get a specific form const { data: form } = await managementClient.forms.get({ id }); log(`Successfully retrieved form: ${(form as any).name} (${(form as any).id})`); return createSuccessResponse(form as any); } catch (sdkError: any) { // Handle SDK errors log('Auth0 SDK error'); let errorMessage = `Failed to get form: ${sdkError.message || 'Unknown error'}`; // Add context based on common error codes if (sdkError.statusCode === 404) { errorMessage = `Form with id '${id}' not found.`; } else if (sdkError.statusCode === 401) { errorMessage += '\nError: Unauthorized. Your token might be expired or invalid or missing read:branding scope.'; } return createErrorResponse(errorMessage); } } catch (error: any) { // Handle any other errors log('Error processing request'); return createErrorResponse( `Error: ${error instanceof Error ? error.message : String(error)}` ); } }, auth0_create_form: async ( request: HandlerRequest, config: HandlerConfig ): Promise<HandlerResponse> => { try { const { name, messages, languages, translations, nodes, start, ending, style } = request.parameters; if (!name) { return createErrorResponse('Error: name is required'); } // Check for token if (!request.token) { log('Warning: Token is empty or undefined'); return createErrorResponse('Error: Missing authorization token'); } // Check if domain is configured if (!config.domain) { log('Error: Auth0 domain is not configured'); return createErrorResponse('Error: Auth0 domain is not configured'); } // Prepare request body with required properties according to PostFormsRequest interface const formData: PostFormsRequest = { name: name, }; // Add optional properties if defined if (messages !== undefined) formData.messages = messages; if (languages !== undefined) formData.languages = languages; if (translations !== undefined) formData.translations = translations; if (nodes !== undefined) formData.nodes = nodes; if (start !== undefined) formData.start = start; if (ending !== undefined) formData.ending = ending; if (style !== undefined) formData.style = style; try { const managementClientConfig: Auth0Config = { domain: config.domain, token: request.token, }; const managementClient = await getManagementClient(managementClientConfig); log(`Creating new form with name: ${name}`); // Use the Auth0 SDK to create a form const newForm = await managementClient.forms.create(formData); log( `Successfully created form: ${(newForm as any).name || name} (${(newForm as any).id || 'new form'})` ); return createSuccessResponse(newForm as any); } catch (sdkError: any) { // Handle SDK errors log('Auth0 SDK error'); let errorMessage = `Failed to create form: ${sdkError.message || 'Unknown error'}`; // Add context based on common error codes if (sdkError.statusCode === 401) { errorMessage += '\nError: Unauthorized. Your token might be expired or invalid or missing create:branding scope.'; } else if (sdkError.statusCode === 422) { errorMessage += '\nError: Validation errors in your request. Check that your parameters are valid.'; } return createErrorResponse(errorMessage); } } catch (error: any) { // Handle any other errors log('Error processing request'); return createErrorResponse( `Error: ${error instanceof Error ? error.message : String(error)}` ); } }, auth0_update_form: async ( request: HandlerRequest, config: HandlerConfig ): Promise<HandlerResponse> => { try { const { id, name, messages, languages, translations, nodes, start, ending, style } = request.parameters; if (!id) { return createErrorResponse('Error: id is required'); } // Check for token if (!request.token) { log('Warning: Token is empty or undefined'); return createErrorResponse('Error: Missing authorization token'); } // Check if domain is configured if (!config.domain) { log('Error: Auth0 domain is not configured'); return createErrorResponse('Error: Auth0 domain is not configured'); } // Prepare request body - partial PostFormsRequest const updateData: Partial<PostFormsRequest> = {}; // Add properties if defined if (name !== undefined) updateData.name = name; if (messages !== undefined) updateData.messages = messages; if (languages !== undefined) updateData.languages = languages; if (translations !== undefined) updateData.translations = translations; if (nodes !== undefined) updateData.nodes = nodes; if (start !== undefined) updateData.start = start; if (ending !== undefined) updateData.ending = ending; if (style !== undefined) updateData.style = style; try { const managementClientConfig: Auth0Config = { domain: config.domain, token: request.token, }; const managementClient = await getManagementClient(managementClientConfig); log(`Updating form with ID: ${id}`); // Use the Auth0 SDK to update a form const { data: updatedForm } = await managementClient.forms.update({ id }, updateData); log( `Successfully updated form: ${updatedForm.name || 'Unknown'} (${updatedForm.id || id})` ); return createSuccessResponse(updatedForm); } catch (sdkError: any) { // Handle SDK errors log('Auth0 SDK error'); let errorMessage = `Failed to update form: ${sdkError.message || 'Unknown error'}`; // Add context based on common error codes if (sdkError.statusCode === 404) { errorMessage = `Form with id '${id}' not found.`; } else if (sdkError.statusCode === 401) { errorMessage += '\nError: Unauthorized. Your token might be expired or invalid or missing update:branding scope.'; } else if (sdkError.statusCode === 422) { errorMessage += '\nError: Validation errors in your request. Check that your parameters are valid.'; } return createErrorResponse(errorMessage); } } catch (error: any) { // Handle any other errors log('Error processing request'); return createErrorResponse( `Error: ${error instanceof Error ? error.message : String(error)}` ); } }, };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/auth0/auth0-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server