n8n_deploy_template
Deploy workflow templates from n8n.io to your n8n instance, automatically fixing common issues and returning workflow details.
Instructions
Deploy a workflow template from n8n.io directly to your n8n instance. Deploys first, then auto-fixes common issues (expression format, typeVersions). Returns workflow ID, required credentials, and fixes applied.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| templateId | Yes | Template ID from n8n.io (required) | |
| name | No | Custom workflow name (default: template name) | |
| autoUpgradeVersions | No | Automatically upgrade node typeVersions to latest supported (default: true) | |
| autoFix | No | Auto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true) | |
| stripCredentials | No | Remove credential references from nodes - user configures in n8n UI (default: true) |
Implementation Reference
- Core implementation of n8n_deploy_template tool. Fetches template by ID from local database, processes it (strips credentials if requested, upgrades node versions, auto-fixes issues), deploys to n8n instance via API creating inactive workflow, returns workflow ID, required credentials list, fixes applied, and n8n UI URL.export async function handleDeployTemplate( args: unknown, templateService: TemplateService, repository: NodeRepository, context?: InstanceContext ): Promise<McpToolResponse> { try { const client = ensureApiConfigured(context); const input = deployTemplateSchema.parse(args); // Fetch template const template = await templateService.getTemplate(input.templateId, 'full'); if (!template) { return { success: false, error: `Template ${input.templateId} not found`, details: { hint: 'Use search_templates to find available templates', templateUrl: `https://n8n.io/workflows/${input.templateId}` } }; } // Extract workflow from template (deep copy to avoid mutation) const workflow = JSON.parse(JSON.stringify(template.workflow)); if (!workflow || !workflow.nodes) { return { success: false, error: 'Template has invalid workflow structure', details: { templateId: input.templateId } }; } // Set workflow name const workflowName = input.name || template.name; // Collect required credentials before stripping const requiredCredentials: RequiredCredential[] = []; for (const node of workflow.nodes) { if (node.credentials && typeof node.credentials === 'object') { for (const [credType] of Object.entries(node.credentials)) { requiredCredentials.push({ nodeType: node.type, nodeName: node.name, credentialType: credType }); } } } // Strip credentials if requested if (input.stripCredentials) { workflow.nodes = workflow.nodes.map((node: any) => { const { credentials, ...rest } = node; return rest; }); } // Auto-upgrade typeVersions if requested if (input.autoUpgradeVersions) { const autoFixer = new WorkflowAutoFixer(repository); // Run validation to get issues to fix const validator = new WorkflowValidator(repository, EnhancedConfigValidator); const validationResult = await validator.validateWorkflow(workflow, { validateNodes: true, validateConnections: false, validateExpressions: false, profile: 'runtime' }); // Generate fixes focused on typeVersion upgrades const fixResult = await autoFixer.generateFixes( workflow, validationResult, [], { fixTypes: ['typeversion-upgrade', 'typeversion-correction'] } ); // Apply fixes to workflow if (fixResult.operations.length > 0) { for (const op of fixResult.operations) { if (op.type === 'updateNode' && op.updates) { const node = workflow.nodes.find((n: any) => n.id === op.nodeId || n.name === op.nodeName ); if (node) { for (const [path, value] of Object.entries(op.updates)) { if (path === 'typeVersion') { node.typeVersion = value; } } } } } } } // Identify trigger type const triggerNode = workflow.nodes.find((n: any) => n.type?.includes('Trigger') || n.type?.includes('webhook') || n.type === 'n8n-nodes-base.webhook' ); const triggerType = triggerNode?.type?.split('.').pop() || 'manual'; // Create workflow via API (always creates inactive) // Deploy first, then fix - this ensures the workflow exists before we modify it const createdWorkflow = await client.createWorkflow({ name: workflowName, nodes: workflow.nodes, connections: workflow.connections, settings: workflow.settings || { executionOrder: 'v1' } }); // Get base URL for workflow link const apiConfig = context ? getN8nApiConfigFromContext(context) : getN8nApiConfig(); const baseUrl = apiConfig?.baseUrl?.replace('/api/v1', '') || ''; // Auto-fix common issues after deployment (expression format, etc.) let fixesApplied: AppliedFix[] = []; let fixSummary = ''; let autoFixStatus: 'success' | 'failed' | 'skipped' = 'skipped'; if (input.autoFix) { try { // Run autofix on the deployed workflow const autofixResult = await handleAutofixWorkflow( { id: createdWorkflow.id, applyFixes: true, fixTypes: ['expression-format', 'typeversion-upgrade'], confidenceThreshold: 'medium' }, repository, context ); if (autofixResult.success && autofixResult.data) { const fixData = autofixResult.data as AutofixResultData; autoFixStatus = 'success'; if (fixData.fixesApplied && fixData.fixesApplied > 0) { fixesApplied = fixData.fixes || []; fixSummary = ` Auto-fixed ${fixData.fixesApplied} issue(s).`; } } } catch (fixError) { // Log but don't fail - autofix is best-effort autoFixStatus = 'failed'; logger.warn('Auto-fix failed after template deployment', { workflowId: createdWorkflow.id, error: fixError instanceof Error ? fixError.message : 'Unknown error' }); fixSummary = ' Auto-fix failed (workflow deployed successfully).'; } } return { success: true, data: { workflowId: createdWorkflow.id, name: createdWorkflow.name, active: false, nodeCount: workflow.nodes.length, triggerType, requiredCredentials: requiredCredentials.length > 0 ? requiredCredentials : undefined, url: baseUrl ? `${baseUrl}/workflow/${createdWorkflow.id}` : undefined, templateId: input.templateId, templateUrl: template.url || `https://n8n.io/workflows/${input.templateId}`, autoFixStatus, fixesApplied: fixesApplied.length > 0 ? fixesApplied : undefined }, message: `Workflow "${createdWorkflow.name}" deployed successfully from template ${input.templateId}.${fixSummary} ${ requiredCredentials.length > 0 ? `Configure ${requiredCredentials.length} credential(s) in n8n to activate.` : '' }` }; } catch (error) { if (error instanceof z.ZodError) { return { success: false, error: 'Invalid input', details: { errors: error.errors } }; } if (error instanceof N8nApiError) { return { success: false, error: getUserFriendlyErrorMessage(error), code: error.code, details: error.details as Record<string, unknown> | undefined }; } return { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred' }; } }
- src/mcp/tools-n8n-manager.ts:492-524 (schema)ToolDefinition object defining the tool name, description, and inputSchema for validation. Part of n8nManagementTools array export.{ name: 'n8n_deploy_template', description: `Deploy a workflow template from n8n.io directly to your n8n instance. Deploys first, then auto-fixes common issues (expression format, typeVersions). Returns workflow ID, required credentials, and fixes applied.`, inputSchema: { type: 'object', properties: { templateId: { type: 'number', description: 'Template ID from n8n.io (required)' }, name: { type: 'string', description: 'Custom workflow name (default: template name)' }, autoUpgradeVersions: { type: 'boolean', default: true, description: 'Automatically upgrade node typeVersions to latest supported (default: true)' }, autoFix: { type: 'boolean', default: true, description: 'Auto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true)' }, stripCredentials: { type: 'boolean', default: true, description: 'Remove credential references from nodes - user configures in n8n UI (default: true)' } }, required: ['templateId'] } }
- src/mcp/tools-n8n-manager.ts:492-525 (registration)The tool is defined and exported as part of the n8nManagementTools array, which is imported and registered in the MCP engine.{ name: 'n8n_deploy_template', description: `Deploy a workflow template from n8n.io directly to your n8n instance. Deploys first, then auto-fixes common issues (expression format, typeVersions). Returns workflow ID, required credentials, and fixes applied.`, inputSchema: { type: 'object', properties: { templateId: { type: 'number', description: 'Template ID from n8n.io (required)' }, name: { type: 'string', description: 'Custom workflow name (default: template name)' }, autoUpgradeVersions: { type: 'boolean', default: true, description: 'Automatically upgrade node typeVersions to latest supported (default: true)' }, autoFix: { type: 'boolean', default: true, description: 'Auto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true)' }, stripCredentials: { type: 'boolean', default: true, description: 'Remove credential references from nodes - user configures in n8n UI (default: true)' } }, required: ['templateId'] } } ];
- Detailed documentation structure for the tool, used by the tools_documentation tool to provide help and examples.import { ToolDocumentation } from '../types'; export const n8nDeployTemplateDoc: ToolDocumentation = { name: 'n8n_deploy_template', category: 'workflow_management', essentials: { description: 'Deploy a workflow template from n8n.io directly to your n8n instance. Deploys first, then auto-fixes common issues (expression format, typeVersions).', keyParameters: ['templateId', 'name', 'autoUpgradeVersions', 'autoFix', 'stripCredentials'], example: 'n8n_deploy_template({templateId: 2776, name: "My Deployed Template"})', performance: 'Network-dependent', tips: [ 'Auto-fixes expression format issues after deployment', 'Workflow created inactive - configure credentials in n8n UI first', 'Returns list of required credentials and fixes applied', 'Use search_templates to find template IDs' ] }, full: { description: 'Deploys a workflow template from n8n.io directly to your n8n instance. This tool deploys first, then automatically fixes common issues like missing expression prefixes (=) and outdated typeVersions. Templates are stored locally and fetched from the database. The workflow is always created in an inactive state, allowing you to configure credentials before activation.', parameters: { templateId: { type: 'number', required: true, description: 'Template ID from n8n.io (find via search_templates)' }, name: { type: 'string', description: 'Custom workflow name (default: template name)' }, autoUpgradeVersions: { type: 'boolean', description: 'Upgrade node typeVersions to latest supported (default: true)' }, autoFix: { type: 'boolean', description: 'Auto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true)' }, stripCredentials: { type: 'boolean', description: 'Remove credential references - user configures in n8n UI (default: true)' } }, returns: 'Object with workflowId, name, nodeCount, triggerType, requiredCredentials array, url, templateId, templateUrl, autoFixStatus (success/failed/skipped), and fixesApplied array', examples: [ `// Deploy template with default settings (auto-fix enabled) n8n_deploy_template({templateId: 2776})`, `// Deploy with custom name n8n_deploy_template({ templateId: 2776, name: "My Google Drive to Airtable Sync" })`, `// Deploy without auto-fix (not recommended) n8n_deploy_template({ templateId: 2776, autoFix: false })`, `// Keep original node versions (useful for compatibility) n8n_deploy_template({ templateId: 2776, autoUpgradeVersions: false })` ], useCases: [ 'Quickly deploy pre-built workflow templates', 'Set up common automation patterns', 'Bootstrap new projects with proven workflows', 'Deploy templates found via search_templates' ], performance: 'Network-dependent - Typically 300-800ms (template fetch + workflow creation + autofix)', bestPractices: [ 'Use search_templates to find templates by use case', 'Review required credentials in the response', 'Check autoFixStatus in response - "success", "failed", or "skipped"', 'Check fixesApplied in response to see what was automatically corrected', 'Configure credentials in n8n UI before activating', 'Test workflow before connecting to production systems' ], pitfalls: [ '**REQUIRES N8N_API_URL and N8N_API_KEY environment variables** - tool unavailable without n8n API access', 'Workflows created in INACTIVE state - must configure credentials and activate in n8n', 'Templates may reference services you do not have (Slack, Google, etc.)', 'Template database must be populated - run npm run fetch:templates if templates not found', 'Some issues may not be auto-fixable (e.g., missing required fields that need user input)' ], relatedTools: ['search_templates', 'get_template', 'n8n_create_workflow', 'n8n_autofix_workflow'] } };