n8n_create_workflow
Create an n8n workflow by defining nodes and connections. The workflow is created in an inactive state and returns with a unique ID for automation setup.
Instructions
Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Workflow name (required) | |
| nodes | Yes | Array of workflow nodes. Each node must have: id, name, type, typeVersion, position, and parameters | |
| connections | Yes | Workflow connections object. Keys are source node names (the name field, not id), values define output connections | |
| settings | No | Optional workflow settings (execution order, timezone, error handling) |
Implementation Reference
- src/mcp/handlers-n8n-manager.ts:469-552 (handler)Main handler function that executes n8n_create_workflow tool: validates input with Zod, checks node types, validates structure, calls N8nApiClient.createWorkflow, handles errors, tracks telemetry.export async function handleCreateWorkflow(args: unknown, context?: InstanceContext): Promise<McpToolResponse> { try { const client = ensureApiConfigured(context); const input = createWorkflowSchema.parse(args); // Proactively detect SHORT form node types (common mistake) const shortFormErrors: string[] = []; input.nodes?.forEach((node: any, index: number) => { if (node.type?.startsWith('nodes-base.') || node.type?.startsWith('nodes-langchain.')) { const fullForm = node.type.startsWith('nodes-base.') ? node.type.replace('nodes-base.', 'n8n-nodes-base.') : node.type.replace('nodes-langchain.', '@n8n/n8n-nodes-langchain.'); shortFormErrors.push( `Node ${index} ("${node.name}") uses SHORT form "${node.type}". ` + `The n8n API requires FULL form. Change to "${fullForm}"` ); } }); if (shortFormErrors.length > 0) { telemetry.trackWorkflowCreation(input, false); return { success: false, error: 'Node type format error: n8n API requires FULL form node types', details: { errors: shortFormErrors, hint: 'Use n8n-nodes-base.* instead of nodes-base.* for standard nodes' } }; } // Validate workflow structure (n8n API expects FULL form: n8n-nodes-base.*) const errors = validateWorkflowStructure(input); if (errors.length > 0) { // Track validation failure telemetry.trackWorkflowCreation(input, false); return { success: false, error: 'Workflow validation failed', details: { errors } }; } // Create workflow (n8n API expects node types in FULL form) const workflow = await client.createWorkflow(input); // Track successful workflow creation telemetry.trackWorkflowCreation(workflow, true); return { success: true, data: { id: workflow.id, name: workflow.name, active: workflow.active, nodeCount: workflow.nodes?.length || 0 }, message: `Workflow "${workflow.name}" created successfully with ID: ${workflow.id}. Use n8n_get_workflow with mode 'structure' to verify current state.` }; } 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:11-69 (schema)ToolDefinition for n8n_create_workflow including name, description, and detailed inputSchema defining parameters, nodes array structure, connections object, and optional settings.{ name: 'n8n_create_workflow', description: `Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.`, inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Workflow name (required)' }, nodes: { type: 'array', description: 'Array of workflow nodes. Each node must have: id, name, type, typeVersion, position, and parameters', items: { type: 'object', required: ['id', 'name', 'type', 'typeVersion', 'position', 'parameters'], properties: { id: { type: 'string' }, name: { type: 'string' }, type: { type: 'string' }, typeVersion: { type: 'number' }, position: { type: 'array', items: { type: 'number' }, minItems: 2, maxItems: 2 }, parameters: { type: 'object' }, credentials: { type: 'object' }, disabled: { type: 'boolean' }, notes: { type: 'string' }, continueOnFail: { type: 'boolean' }, retryOnFail: { type: 'boolean' }, maxTries: { type: 'number' }, waitBetweenTries: { type: 'number' } } } }, connections: { type: 'object', description: 'Workflow connections object. Keys are source node IDs, values define output connections' }, settings: { type: 'object', description: 'Optional workflow settings (execution order, timezone, error handling)', properties: { executionOrder: { type: 'string', enum: ['v0', 'v1'] }, timezone: { type: 'string' }, saveDataErrorExecution: { type: 'string', enum: ['all', 'none'] }, saveDataSuccessExecution: { type: 'string', enum: ['all', 'none'] }, saveManualExecutions: { type: 'boolean' }, saveExecutionProgress: { type: 'boolean' }, executionTimeout: { type: 'number' }, errorWorkflow: { type: 'string' } } } }, required: ['name', 'nodes', 'connections'] }
- Zod schema used for input validation inside the handleCreateWorkflow function.const createWorkflowSchema = z.object({ name: z.string(), nodes: z.array(z.any()), connections: z.record(z.any()), settings: z.object({ executionOrder: z.enum(['v0', 'v1']).optional(), timezone: z.string().optional(), saveDataErrorExecution: z.enum(['all', 'none']).optional(), saveDataSuccessExecution: z.enum(['all', 'none']).optional(), saveManualExecutions: z.boolean().optional(), saveExecutionProgress: z.boolean().optional(), executionTimeout: z.number().optional(), errorWorkflow: z.string().optional(), }).optional(), });
- src/mcp/tools-n8n-manager.ts:9-525 (registration)n8nManagementTools array exports the ToolDefinition for n8n_create_workflow and other management tools, used for MCP tool registration.export const n8nManagementTools: ToolDefinition[] = [ // Workflow Management Tools { name: 'n8n_create_workflow', description: `Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.`, inputSchema: { type: 'object', properties: { name: { type: 'string', description: 'Workflow name (required)' }, nodes: { type: 'array', description: 'Array of workflow nodes. Each node must have: id, name, type, typeVersion, position, and parameters', items: { type: 'object', required: ['id', 'name', 'type', 'typeVersion', 'position', 'parameters'], properties: { id: { type: 'string' }, name: { type: 'string' }, type: { type: 'string' }, typeVersion: { type: 'number' }, position: { type: 'array', items: { type: 'number' }, minItems: 2, maxItems: 2 }, parameters: { type: 'object' }, credentials: { type: 'object' }, disabled: { type: 'boolean' }, notes: { type: 'string' }, continueOnFail: { type: 'boolean' }, retryOnFail: { type: 'boolean' }, maxTries: { type: 'number' }, waitBetweenTries: { type: 'number' } } } }, connections: { type: 'object', description: 'Workflow connections object. Keys are source node IDs, values define output connections' }, settings: { type: 'object', description: 'Optional workflow settings (execution order, timezone, error handling)', properties: { executionOrder: { type: 'string', enum: ['v0', 'v1'] }, timezone: { type: 'string' }, saveDataErrorExecution: { type: 'string', enum: ['all', 'none'] }, saveDataSuccessExecution: { type: 'string', enum: ['all', 'none'] }, saveManualExecutions: { type: 'boolean' }, saveExecutionProgress: { type: 'boolean' }, executionTimeout: { type: 'number' }, errorWorkflow: { type: 'string' } } } }, required: ['name', 'nodes', 'connections'] } }, { name: 'n8n_get_workflow', description: `Get workflow by ID with different detail levels. Use mode='full' for complete workflow, 'details' for metadata+stats, 'structure' for nodes/connections only, 'minimal' for id/name/active/tags.`, inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Workflow ID' }, mode: { type: 'string', enum: ['full', 'details', 'structure', 'minimal'], default: 'full', description: 'Detail level: full=complete workflow, details=full+execution stats, structure=nodes/connections topology, minimal=metadata only' } }, required: ['id'] } }, { name: 'n8n_update_full_workflow', description: `Full workflow update. Requires complete nodes[] and connections{}. For incremental use n8n_update_partial_workflow.`, inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Workflow ID to update' }, name: { type: 'string', description: 'New workflow name' }, nodes: { type: 'array', description: 'Complete array of workflow nodes (required if modifying workflow structure)', items: { type: 'object', additionalProperties: true } }, connections: { type: 'object', description: 'Complete connections object (required if modifying workflow structure)' }, settings: { type: 'object', description: 'Workflow settings to update' } }, required: ['id'] } }, { name: 'n8n_update_partial_workflow', description: `Update workflow incrementally with diff operations. Types: addNode, removeNode, updateNode, moveNode, enable/disableNode, addConnection, removeConnection, updateSettings, updateName, add/removeTag. See tools_documentation("n8n_update_partial_workflow", "full") for details.`, inputSchema: { type: 'object', additionalProperties: true, // Allow any extra properties Claude Desktop might add properties: { id: { type: 'string', description: 'Workflow ID to update' }, operations: { type: 'array', description: 'Array of diff operations to apply. Each operation must have a "type" field and relevant properties for that operation type.', items: { type: 'object', additionalProperties: true } }, validateOnly: { type: 'boolean', description: 'If true, only validate operations without applying them' }, continueOnError: { type: 'boolean', description: 'If true, apply valid operations even if some fail (best-effort mode). Returns applied and failed operation indices. Default: false (atomic)' } }, required: ['id', 'operations'] } }, { name: 'n8n_delete_workflow', description: `Permanently delete a workflow. This action cannot be undone.`, inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Workflow ID to delete' } }, required: ['id'] } }, { name: 'n8n_list_workflows', description: `List workflows (minimal metadata only). Returns id/name/active/dates/tags. Check hasMore/nextCursor for pagination.`, inputSchema: { type: 'object', properties: { limit: { type: 'number', description: 'Number of workflows to return (1-100, default: 100)' }, cursor: { type: 'string', description: 'Pagination cursor from previous response' }, active: { type: 'boolean', description: 'Filter by active status' }, tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags (exact match)' }, projectId: { type: 'string', description: 'Filter by project ID (enterprise feature)' }, excludePinnedData: { type: 'boolean', description: 'Exclude pinned data from response (default: true)' } } } }, { name: 'n8n_validate_workflow', description: `Validate workflow by ID. Checks nodes, connections, expressions. Returns errors/warnings/suggestions.`, inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Workflow ID to validate' }, options: { type: 'object', description: 'Validation options', properties: { validateNodes: { type: 'boolean', description: 'Validate node configurations (default: true)' }, validateConnections: { type: 'boolean', description: 'Validate workflow connections (default: true)' }, validateExpressions: { type: 'boolean', description: 'Validate n8n expressions (default: true)' }, profile: { type: 'string', enum: ['minimal', 'runtime', 'ai-friendly', 'strict'], description: 'Validation profile to use (default: runtime)' } } } }, required: ['id'] } }, { name: 'n8n_autofix_workflow', description: `Automatically fix common workflow validation errors. Preview fixes or apply them. Fixes expression format, typeVersion, error output config, webhook paths.`, inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Workflow ID to fix' }, applyFixes: { type: 'boolean', description: 'Apply fixes to workflow (default: false - preview mode)' }, fixTypes: { type: 'array', description: 'Types of fixes to apply (default: all)', items: { type: 'string', enum: ['expression-format', 'typeversion-correction', 'error-output-config', 'node-type-correction', 'webhook-missing-path', 'typeversion-upgrade', 'version-migration'] } }, confidenceThreshold: { type: 'string', enum: ['high', 'medium', 'low'], description: 'Minimum confidence level for fixes (default: medium)' }, maxFixes: { type: 'number', description: 'Maximum number of fixes to apply (default: 50)' } }, required: ['id'] } }, // Execution Management Tools { name: 'n8n_test_workflow', description: `Test/trigger workflow execution. Auto-detects trigger type (webhook/form/chat). Supports: webhook (HTTP), form (fields), chat (message). Note: Only workflows with these trigger types can be executed externally.`, inputSchema: { type: 'object', properties: { workflowId: { type: 'string', description: 'Workflow ID to execute (required)' }, triggerType: { type: 'string', enum: ['webhook', 'form', 'chat'], description: 'Trigger type. Auto-detected if not specified. Workflow must have a matching trigger node.' }, // Webhook options httpMethod: { type: 'string', enum: ['GET', 'POST', 'PUT', 'DELETE'], description: 'For webhook: HTTP method (default: from workflow config or POST)' }, webhookPath: { type: 'string', description: 'For webhook: override the webhook path' }, // Chat options message: { type: 'string', description: 'For chat: message to send (required for chat triggers)' }, sessionId: { type: 'string', description: 'For chat: session ID for conversation continuity' }, // Common options data: { type: 'object', description: 'Input data/payload for webhook, form fields, or execution data' }, headers: { type: 'object', description: 'Custom HTTP headers' }, timeout: { type: 'number', description: 'Timeout in ms (default: 120000)' }, waitForResponse: { type: 'boolean', description: 'Wait for workflow completion (default: true)' } }, required: ['workflowId'] } }, { name: 'n8n_executions', description: `Manage workflow executions: get details, list, or delete. Use action='get' with id for execution details, action='list' for listing executions, action='delete' to remove execution record.`, inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['get', 'list', 'delete'], description: 'Operation: get=get execution details, list=list executions, delete=delete execution' }, // For action='get' and action='delete' id: { type: 'string', description: 'Execution ID (required for action=get or action=delete)' }, // For action='get' - detail level mode: { type: 'string', enum: ['preview', 'summary', 'filtered', 'full', 'error'], description: 'For action=get: preview=structure only, summary=2 items (default), filtered=custom, full=all data, error=optimized error debugging' }, nodeNames: { type: 'array', items: { type: 'string' }, description: 'For action=get with mode=filtered: filter to specific nodes by name' }, itemsLimit: { type: 'number', description: 'For action=get with mode=filtered: items per node (0=structure, 2=default, -1=unlimited)' }, includeInputData: { type: 'boolean', description: 'For action=get: include input data in addition to output (default: false)' }, // Error mode specific parameters errorItemsLimit: { type: 'number', description: 'For action=get with mode=error: sample items from upstream node (default: 2, max: 100)' }, includeStackTrace: { type: 'boolean', description: 'For action=get with mode=error: include full stack trace (default: false, shows truncated)' }, includeExecutionPath: { type: 'boolean', description: 'For action=get with mode=error: include execution path leading to error (default: true)' }, fetchWorkflow: { type: 'boolean', description: 'For action=get with mode=error: fetch workflow for accurate upstream detection (default: true)' }, // For action='list' limit: { type: 'number', description: 'For action=list: number of executions to return (1-100, default: 100)' }, cursor: { type: 'string', description: 'For action=list: pagination cursor from previous response' }, workflowId: { type: 'string', description: 'For action=list: filter by workflow ID' }, projectId: { type: 'string', description: 'For action=list: filter by project ID (enterprise feature)' }, status: { type: 'string', enum: ['success', 'error', 'waiting'], description: 'For action=list: filter by execution status' }, includeData: { type: 'boolean', description: 'For action=list: include execution data (default: false)' } }, required: ['action'] } }, // System Tools { name: 'n8n_health_check', description: `Check n8n instance health and API connectivity. Use mode='diagnostic' for detailed troubleshooting with env vars and tool status.`, inputSchema: { type: 'object', properties: { mode: { type: 'string', enum: ['status', 'diagnostic'], description: 'Mode: "status" (default) for quick health check, "diagnostic" for detailed debug info including env vars and tool status', default: 'status' }, verbose: { type: 'boolean', description: 'Include extra details in diagnostic mode (default: false)' } } } }, { name: 'n8n_workflow_versions', description: `Manage workflow version history, rollback, and cleanup. Six modes: - list: Show version history for a workflow - get: Get details of specific version - rollback: Restore workflow to previous version (creates backup first) - delete: Delete specific version or all versions for a workflow - prune: Manually trigger pruning to keep N most recent versions - truncate: Delete ALL versions for ALL workflows (requires confirmation)`, inputSchema: { type: 'object', properties: { mode: { type: 'string', enum: ['list', 'get', 'rollback', 'delete', 'prune', 'truncate'], description: 'Operation mode' }, workflowId: { type: 'string', description: 'Workflow ID (required for list, rollback, delete, prune)' }, versionId: { type: 'number', description: 'Version ID (required for get mode and single version delete, optional for rollback)' }, limit: { type: 'number', default: 10, description: 'Max versions to return in list mode' }, validateBefore: { type: 'boolean', default: true, description: 'Validate workflow structure before rollback' }, deleteAll: { type: 'boolean', default: false, description: 'Delete all versions for workflow (delete mode only)' }, maxVersions: { type: 'number', default: 10, description: 'Keep N most recent versions (prune mode only)' }, confirmTruncate: { type: 'boolean', default: false, description: 'REQUIRED: Must be true to truncate all versions (truncate mode only)' } }, required: ['mode'] } }, // Template Deployment Tool { 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 tool documentation including examples, best practices, pitfalls, and related tools for n8n_create_workflow.import { ToolDocumentation } from '../types'; export const n8nCreateWorkflowDoc: ToolDocumentation = { name: 'n8n_create_workflow', category: 'workflow_management', essentials: { description: 'Create workflow. Requires: name, nodes[], connections{}. Created inactive. Returns workflow with ID.', keyParameters: ['name', 'nodes', 'connections'], example: 'n8n_create_workflow({name: "My Flow", nodes: [...], connections: {...}})', performance: 'Network-dependent', tips: [ 'Workflow created inactive', 'Returns ID for future updates', 'Validate first with validate_workflow', 'Auto-sanitization fixes operator structures and missing metadata during creation' ] }, full: { description: 'Creates a new workflow in n8n with specified nodes and connections. Workflow is created in inactive state. Each node requires: id, name, type, typeVersion, position, and parameters.', parameters: { name: { type: 'string', required: true, description: 'Workflow name' }, nodes: { type: 'array', required: true, description: 'Array of nodes with id, name, type, typeVersion, position, parameters' }, connections: { type: 'object', required: true, description: 'Node connections. Keys are source node IDs' }, settings: { type: 'object', description: 'Optional workflow settings (timezone, error handling, etc.)' } }, returns: 'Minimal summary (id, name, active, nodeCount) for token efficiency. Use n8n_get_workflow with mode "structure" to verify current state if needed.', examples: [ `// Basic webhook to Slack workflow n8n_create_workflow({ name: "Webhook to Slack", nodes: [ { id: "webhook_1", name: "Webhook", type: "n8n-nodes-base.webhook", typeVersion: 1, position: [250, 300], parameters: { httpMethod: "POST", path: "slack-notify" } }, { id: "slack_1", name: "Slack", type: "n8n-nodes-base.slack", typeVersion: 1, position: [450, 300], parameters: { resource: "message", operation: "post", channel: "#general", text: "={{$json.message}}" } } ], connections: { "webhook_1": { "main": [[{node: "slack_1", type: "main", index: 0}]] } } })`, `// Workflow with settings and error handling n8n_create_workflow({ name: "Data Processing", nodes: [...], connections: {...}, settings: { timezone: "America/New_York", errorWorkflow: "error_handler_workflow_id", saveDataSuccessExecution: "all", saveDataErrorExecution: "all" } })` ], useCases: [ 'Deploy validated workflows', 'Automate workflow creation', 'Clone workflow structures', 'Template deployment' ], performance: 'Network-dependent - Typically 100-500ms depending on workflow size', bestPractices: [ 'Validate with validate_workflow first', 'Use unique node IDs', 'Position nodes for readability', 'Test with n8n_test_workflow' ], pitfalls: [ '**REQUIRES N8N_API_URL and N8N_API_KEY environment variables** - tool unavailable without n8n API access', 'Workflows created in INACTIVE state - must activate separately', 'Node IDs must be unique within workflow', 'Credentials must be configured separately in n8n', 'Node type names must include package prefix (e.g., "n8n-nodes-base.slack")', '**Auto-sanitization runs on creation**: All nodes sanitized before workflow created (operator structures fixed, missing metadata added)', '**Auto-sanitization cannot prevent all failures**: Broken connections or invalid node configurations may still cause creation to fail' ], relatedTools: ['validate_workflow', 'n8n_update_partial_workflow', 'n8n_test_workflow'] } };