Skip to main content
Glama

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
NameRequiredDescriptionDefault
templateIdYesTemplate ID from n8n.io (required)
nameNoCustom workflow name (default: template name)
autoUpgradeVersionsNoAutomatically upgrade node typeVersions to latest supported (default: true)
autoFixNoAuto-apply fixes after deployment for expression format issues, missing = prefix, etc. (default: true)
stripCredentialsNoRemove 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'
        };
      }
    }
  • 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']
      }
    }
  • 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']
      }
    };

Latest Blog Posts

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

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