Skip to main content
Glama

n8n-MCP

by 88-888
node-utils.tsβ€’5.71 kB
/** * Normalizes node type from n8n export format to database format * * Examples: * - 'n8n-nodes-base.httpRequest' β†’ 'nodes-base.httpRequest' * - '@n8n/n8n-nodes-langchain.agent' β†’ 'nodes-langchain.agent' * - 'n8n-nodes-langchain.chatTrigger' β†’ 'nodes-langchain.chatTrigger' * - 'nodes-base.slack' β†’ 'nodes-base.slack' (unchanged) * * @param nodeType The node type to normalize * @returns The normalized node type */ export function normalizeNodeType(nodeType: string): string { // Handle n8n-nodes-base -> nodes-base if (nodeType.startsWith('n8n-nodes-base.')) { return nodeType.replace('n8n-nodes-base.', 'nodes-base.'); } // Handle @n8n/n8n-nodes-langchain -> nodes-langchain if (nodeType.startsWith('@n8n/n8n-nodes-langchain.')) { return nodeType.replace('@n8n/n8n-nodes-langchain.', 'nodes-langchain.'); } // Handle n8n-nodes-langchain -> nodes-langchain (without @n8n/ prefix) if (nodeType.startsWith('n8n-nodes-langchain.')) { return nodeType.replace('n8n-nodes-langchain.', 'nodes-langchain.'); } // Return unchanged if already normalized or unknown format return nodeType; } /** * Gets alternative node type formats to try for lookups * * @param nodeType The original node type * @returns Array of alternative formats to try */ export function getNodeTypeAlternatives(nodeType: string): string[] { // Defensive: validate input to prevent TypeError when nodeType is undefined/null/empty if (!nodeType || typeof nodeType !== 'string' || nodeType.trim() === '') { return []; } const alternatives: string[] = []; // Add lowercase version alternatives.push(nodeType.toLowerCase()); // If it has a prefix, try case variations on the node name part if (nodeType.includes('.')) { const [prefix, nodeName] = nodeType.split('.'); // Try different case variations for the node name if (nodeName && nodeName.toLowerCase() !== nodeName) { alternatives.push(`${prefix}.${nodeName.toLowerCase()}`); } // For camelCase names like "chatTrigger", also try with capital first letter variations // e.g., "chattrigger" -> "chatTrigger" if (nodeName && nodeName.toLowerCase() === nodeName && nodeName.length > 1) { // Try to detect common patterns and create camelCase version const camelCaseVariants = generateCamelCaseVariants(nodeName); camelCaseVariants.forEach(variant => { alternatives.push(`${prefix}.${variant}`); }); } } // If it's just a bare node name, try with common prefixes if (!nodeType.includes('.')) { alternatives.push(`nodes-base.${nodeType}`); alternatives.push(`nodes-langchain.${nodeType}`); // Also try camelCase variants for bare names const camelCaseVariants = generateCamelCaseVariants(nodeType); camelCaseVariants.forEach(variant => { alternatives.push(`nodes-base.${variant}`); alternatives.push(`nodes-langchain.${variant}`); }); } // Normalize all alternatives and combine with originals const normalizedAlternatives = alternatives.map(alt => normalizeNodeType(alt)); // Combine original alternatives with normalized ones and remove duplicates return [...new Set([...alternatives, ...normalizedAlternatives])]; } /** * Generate camelCase variants for a lowercase string * @param str The lowercase string * @returns Array of possible camelCase variants */ function generateCamelCaseVariants(str: string): string[] { const variants: string[] = []; // Common patterns for n8n nodes const patterns = [ // Pattern: wordTrigger (e.g., chatTrigger, webhookTrigger) /^(.+)(trigger|node|request|response)$/i, // Pattern: httpRequest, mysqlDatabase /^(http|mysql|postgres|mongo|redis|mqtt|smtp|imap|ftp|ssh|api)(.+)$/i, // Pattern: googleSheets, microsoftTeams /^(google|microsoft|amazon|slack|discord|telegram)(.+)$/i, ]; for (const pattern of patterns) { const match = str.toLowerCase().match(pattern); if (match) { const [, first, second] = match; // Capitalize the second part variants.push(first.toLowerCase() + second.charAt(0).toUpperCase() + second.slice(1).toLowerCase()); } } // Generic camelCase: capitalize after common word boundaries if (variants.length === 0) { // Try splitting on common boundaries and capitalizing const words = str.split(/[-_\s]+/); if (words.length > 1) { const camelCase = words[0].toLowerCase() + words.slice(1).map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() ).join(''); variants.push(camelCase); } } return variants; } /** * Constructs the workflow node type from package name and normalized node type * This creates the format that n8n expects in workflow definitions * * Examples: * - ('n8n-nodes-base', 'nodes-base.webhook') β†’ 'n8n-nodes-base.webhook' * - ('@n8n/n8n-nodes-langchain', 'nodes-langchain.agent') β†’ '@n8n/n8n-nodes-langchain.agent' * * @param packageName The package name from the database * @param nodeType The normalized node type from the database * @returns The workflow node type for use in n8n workflows */ export function getWorkflowNodeType(packageName: string, nodeType: string): string { // Extract just the node name from the normalized type const nodeName = nodeType.split('.').pop() || nodeType; // Construct the full workflow type based on package if (packageName === 'n8n-nodes-base') { return `n8n-nodes-base.${nodeName}`; } else if (packageName === '@n8n/n8n-nodes-langchain') { return `@n8n/n8n-nodes-langchain.${nodeName}`; } // Fallback for unknown packages - return as is return nodeType; }

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/88-888/n8n-mcp'

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