update_workflow
Modify and save entire workflows by providing the complete updated structure, including nodes, connections, and settings, after retrieving and editing an existing workflow.
Instructions
Updates an existing workflow with new configuration. Typically used after retrieving a workflow with get_workflow, modifying its structure, and then saving the changes. The entire workflow structure must be provided, not just the parts being changed.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the workflow to update - can be obtained from list_workflows | |
| workflow | Yes | Complete updated workflow structure - must include all nodes and connections, not just changes |
Implementation Reference
- Primary handler for update_workflow tool. Validates input (ID and workflow), parses workflow with Zod schema, validates nodes exist in n8n, calls API client to update, handles validation/node errors with guidance, returns formatted success/error response.export async function handle_update_workflow( api_client: N8nApiClient, args: any, ) { if (!args.id || !args.workflow) { throw new McpError( ErrorCode.InvalidParams, 'Workflow ID and updated workflow data are required', ); } try { // Validate workflow with Zod const parsed_workflow = WorkflowSchema.parse(args.workflow); // Validate that all nodes exist in n8n const invalid_nodes = await node_validator.validate_workflow_nodes( parsed_workflow.nodes, ); if (invalid_nodes.length > 0) { // Format error message with suggestions const error_messages = invalid_nodes.map((node) => { const suggestion = node.suggestion ? `Did you mean '${node.suggestion}'?` : 'No similar nodes found.'; return `- '${node.node_type}': Not a valid n8n node. ${suggestion}`; }); // Include relevant sections from the workflow composition guide const node_categories = WORKFLOW_COMPOSITION_GUIDE.node_categories; return { content: [ { type: 'text', text: `Workflow contains invalid node types:\n${error_messages.join( '\n', )}\n\nPlease correct these node types before updating the workflow.\n\n` + `Here are the available node categories for reference:\n${node_categories}`, }, ], isError: true, }; } const workflow = await api_client.update_workflow( args.id, parsed_workflow, ); const activation_status = workflow.active ? 'active' : 'inactive'; return { content: [ { type: 'text', text: `Successfully updated workflow "${workflow.name}" (ID: ${args.id}, Status: ${activation_status})`, }, ], }; } catch (error: any) { if (error.name === 'ZodError') { return handle_validation_error(error); } return { content: [ { type: 'text', text: `Error updating workflow: ${ error.message || String(error) }`, }, ], isError: true, }; } }
- src/tool-handlers/index.ts:157-201 (registration)Tool registration in MCP ListToolsRequestHandler, defining name, description, and input schema for update_workflow.name: 'update_workflow', description: 'Updates an existing workflow with new configuration. Typically used after retrieving a workflow with get_workflow, modifying its structure, and then saving the changes. The entire workflow structure must be provided, not just the parts being changed.', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'ID of the workflow to update - can be obtained from list_workflows', }, workflow: { type: 'object', description: 'Complete updated workflow structure - must include all nodes and connections, not just changes', properties: { name: { type: 'string', description: 'Name of the workflow', }, nodes: { type: 'array', description: 'Array of workflow nodes (triggers, actions, etc.)', items: { type: 'object', }, }, connections: { type: 'object', description: 'Connections between nodes defining the workflow execution path', }, settings: { type: 'object', description: 'Workflow settings like error handling, execution timeout, etc.', }, }, required: ['name', 'nodes', 'connections'], }, }, required: ['id', 'workflow'], }, },
- src/tool-handlers/index.ts:326-327 (registration)Dispatch logic in MCP CallToolRequestHandler switch statement that routes to the handler.case 'update_workflow': return await handle_update_workflow(api_client, args);
- src/schemas.ts:36-46 (schema)Zod schema for validating the workflow object structure used in the handler's input validation.export const WorkflowSchema = z.object({ id: z.string().optional(), name: z.string(), active: z.boolean().optional(), nodes: z.array(NodeSchema), connections: z.record(z.record(z.array(z.array(ConnectionSchema)))), settings: WorkflowSettingsSchema, staticData: z .union([z.string().nullable(), z.record(z.any()).nullable()]) .optional(), });
- src/n8n-api-client.ts:146-148 (helper)API client method called by the handler to perform the actual HTTP PUT request to update the workflow in n8n.async update_workflow(id: string, workflow: any): Promise<any> { return this.request<any>('PUT', `/workflows/${id}`, workflow); }