create_node
Add new nodes to existing n8n workflows to extend automation capabilities and integrate additional services or data processing steps.
Instructions
Create a new node in an existing n8n workflow
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| credentials | No | Optional credentials configuration | |
| name | No | Optional name for the node | |
| params | No | Optional node parameters | |
| position | No | Optional [x, y] position | |
| type | Yes | The node type (e.g., n8n-nodes-base.webhook) | |
| workflowId | Yes | The workflow ID |
Implementation Reference
- src/n8n-client.ts:408-424 (handler)Core implementation of the create_node tool logic: generates unique node ID, determines position, creates new node object, and atomically appends it to the workflow.nodes array using performWorkflowUpdate.async createNode(request: CreateNodeRequest): Promise<CreateNodeResponse> { const nodeId = this.generateNodeId(); await this.performWorkflowUpdate(request.workflowId, (workflow) => { const position = request.position || this.getDefaultPosition(workflow.nodes); const newNode: N8nNode = { id: nodeId, name: request.name || request.type.split('.').pop() || 'New Node', type: request.type, typeVersion: 1, position, parameters: request.params || {}, credentials: request.credentials || {}, }; workflow.nodes.push(newNode); }); return { nodeId }; }
- src/index.ts:541-551 (handler)MCP server handler method for the 'create_node' tool, which delegates execution to N8nClient.createNode and formats the success response.private async handleCreateNode(args: CreateNodeRequest) { const result = await this.n8nClient.createNode(args); return { content: [ { type: 'text', text: JSON.stringify(jsonSuccess(result), null, 2), }, ], }; }
- src/index.ts:211-211 (registration)Registration of the 'create_node' tool in the MCP server, including name, description, and detailed input schema.{ name: 'create_node', description: 'Create a new node in an existing n8n workflow', inputSchema: { type: 'object', properties: { workflowId: { oneOf: [{ type: 'string' }, { type: 'number' }], description: 'The workflow ID' }, type: { type: 'string', description: 'The node type (e.g., n8n-nodes-base.webhook)' }, name: { type: 'string', description: 'Optional name for the node' }, params: { type: 'object', description: 'Optional node parameters' }, position: { type: 'array', items: { type: 'number' }, minItems: 2, maxItems: 2, description: 'Optional [x, y] position' }, credentials: { type: 'object', description: 'Optional credentials configuration' } }, required: ['workflowId', 'type'] } },
- src/types.ts:188-199 (schema)TypeScript interfaces defining the input (CreateNodeRequest) and output (CreateNodeResponse) types for the create_node tool.export interface CreateNodeRequest { workflowId: string | number; type: string; name?: string; params?: Record<string, any>; position?: [number, number]; credentials?: Record<string, string>; } export interface CreateNodeResponse { nodeId: string; }
- src/n8n-client.ts:384-406 (helper)Helper method performWorkflowUpdate used by create_node (and other mutation tools) to atomically fetch current workflow with ETag, apply mutation operation, and update with optimistic concurrency control and retry on precondition failures.private async performWorkflowUpdate( workflowId: string | number, operation: (workflow: N8nWorkflow) => void, maxRetries: number = 3, ): Promise<void> { let retries = 0; while (retries < maxRetries) { try { const { workflow, etag } = await this.getWorkflowWithETag(workflowId); operation(workflow); await this.updateWorkflow(workflowId, workflow, etag || undefined); return; } catch (error: any) { const message = error?.message || ''; if (message.includes('Precondition failed') && retries < maxRetries - 1) { retries++; await new Promise((resolve) => setTimeout(resolve, Math.pow(2, retries) * 100)); continue; } throw error; } } }