mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-01-30 22:42:04 +00:00
The 5-operation limit was overly conservative and unnecessary. Analysis showed: - Workflow is cloned before modifications (no original mutation) - All operations validated before any are applied (true atomicity) - First error causes immediate return (no partial state possible) - Two-pass processing handles dependencies correctly Changes: - Remove hard-coded 5-operation limit check from workflow-diff-engine.ts - Update tool descriptions and documentation to reflect unlimited operations - Add tests verifying 50 and 100+ operations work successfully - Add example showing 26 operations in single request The system already ensures complete transactional integrity regardless of operation count. Bottleneck is workflow size, not operation count. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
697 lines
15 KiB
Markdown
697 lines
15 KiB
Markdown
# Workflow Diff Examples
|
|
|
|
This guide demonstrates how to use the `n8n_update_partial_workflow` tool for efficient workflow editing.
|
|
|
|
## Overview
|
|
|
|
The `n8n_update_partial_workflow` tool allows you to make targeted changes to workflows without sending the entire workflow JSON. This results in:
|
|
- 80-90% reduction in token usage
|
|
- More precise edits
|
|
- Clearer intent
|
|
- Reduced risk of accidentally modifying unrelated parts
|
|
|
|
## Basic Usage
|
|
|
|
```json
|
|
{
|
|
"id": "workflow-id-here",
|
|
"operations": [
|
|
{
|
|
"type": "operation-type",
|
|
"...operation-specific-fields..."
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Operation Types
|
|
|
|
### 1. Node Operations
|
|
|
|
#### Add Node
|
|
```json
|
|
{
|
|
"type": "addNode",
|
|
"description": "Add HTTP Request node to fetch data",
|
|
"node": {
|
|
"name": "Fetch User Data",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"position": [600, 300],
|
|
"parameters": {
|
|
"url": "https://api.example.com/users",
|
|
"method": "GET",
|
|
"authentication": "none"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Remove Node
|
|
```json
|
|
{
|
|
"type": "removeNode",
|
|
"nodeName": "Old Node Name",
|
|
"description": "Remove deprecated node"
|
|
}
|
|
```
|
|
|
|
#### Update Node
|
|
```json
|
|
{
|
|
"type": "updateNode",
|
|
"nodeName": "HTTP Request",
|
|
"changes": {
|
|
"parameters.url": "https://new-api.example.com/v2/users",
|
|
"parameters.headers.parameters": [
|
|
{
|
|
"name": "Authorization",
|
|
"value": "Bearer {{$credentials.apiKey}}"
|
|
}
|
|
]
|
|
},
|
|
"description": "Update API endpoint to v2"
|
|
}
|
|
```
|
|
|
|
#### Move Node
|
|
```json
|
|
{
|
|
"type": "moveNode",
|
|
"nodeName": "Set Variable",
|
|
"position": [800, 400],
|
|
"description": "Reposition for better layout"
|
|
}
|
|
```
|
|
|
|
#### Enable/Disable Node
|
|
```json
|
|
{
|
|
"type": "disableNode",
|
|
"nodeName": "Debug Node",
|
|
"description": "Disable debug output for production"
|
|
}
|
|
```
|
|
|
|
### 2. Connection Operations
|
|
|
|
#### Add Connection
|
|
```json
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Webhook",
|
|
"target": "Process Data",
|
|
"sourceOutput": "main",
|
|
"targetInput": "main",
|
|
"description": "Connect webhook to processor"
|
|
}
|
|
```
|
|
|
|
#### Remove Connection
|
|
```json
|
|
{
|
|
"type": "removeConnection",
|
|
"source": "Old Source",
|
|
"target": "Old Target",
|
|
"description": "Remove unused connection"
|
|
}
|
|
```
|
|
|
|
#### Update Connection (Change routing)
|
|
```json
|
|
{
|
|
"type": "updateConnection",
|
|
"source": "IF",
|
|
"target": "Send Email",
|
|
"changes": {
|
|
"sourceOutput": "false", // Change from 'true' to 'false' output
|
|
"targetInput": "main"
|
|
},
|
|
"description": "Route failed conditions to email"
|
|
}
|
|
```
|
|
|
|
### 3. Workflow Metadata Operations
|
|
|
|
#### Update Workflow Name
|
|
```json
|
|
{
|
|
"type": "updateName",
|
|
"name": "Production User Sync v2",
|
|
"description": "Update workflow name for versioning"
|
|
}
|
|
```
|
|
|
|
#### Update Settings
|
|
```json
|
|
{
|
|
"type": "updateSettings",
|
|
"settings": {
|
|
"executionTimeout": 300,
|
|
"saveDataErrorExecution": "all",
|
|
"timezone": "America/New_York"
|
|
},
|
|
"description": "Configure production settings"
|
|
}
|
|
```
|
|
|
|
#### Manage Tags
|
|
```json
|
|
{
|
|
"type": "addTag",
|
|
"tag": "production",
|
|
"description": "Mark as production workflow"
|
|
}
|
|
```
|
|
|
|
## Complete Examples
|
|
|
|
### Example 1: Add Slack Notification to Workflow
|
|
```json
|
|
{
|
|
"id": "workflow-123",
|
|
"operations": [
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Send Slack Alert",
|
|
"type": "n8n-nodes-base.slack",
|
|
"position": [1000, 300],
|
|
"parameters": {
|
|
"resource": "message",
|
|
"operation": "post",
|
|
"channel": "#alerts",
|
|
"text": "Workflow completed successfully!"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Process Data",
|
|
"target": "Send Slack Alert"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Example 2: Update Multiple Webhook Paths
|
|
```json
|
|
{
|
|
"id": "workflow-456",
|
|
"operations": [
|
|
{
|
|
"type": "updateNode",
|
|
"nodeName": "Webhook 1",
|
|
"changes": {
|
|
"parameters.path": "v2/webhook1"
|
|
}
|
|
},
|
|
{
|
|
"type": "updateNode",
|
|
"nodeName": "Webhook 2",
|
|
"changes": {
|
|
"parameters.path": "v2/webhook2"
|
|
}
|
|
},
|
|
{
|
|
"type": "updateName",
|
|
"name": "API v2 Webhooks"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Example 3: Refactor Workflow Structure
|
|
```json
|
|
{
|
|
"id": "workflow-789",
|
|
"operations": [
|
|
{
|
|
"type": "removeNode",
|
|
"nodeName": "Legacy Processor"
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Modern Processor",
|
|
"type": "n8n-nodes-base.code",
|
|
"position": [600, 300],
|
|
"parameters": {
|
|
"mode": "runOnceForEachItem",
|
|
"jsCode": "// Process items\nreturn item;"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "HTTP Request",
|
|
"target": "Modern Processor"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Modern Processor",
|
|
"target": "Save to Database"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Example 4: Add Error Handling
|
|
```json
|
|
{
|
|
"id": "workflow-999",
|
|
"operations": [
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Error Handler",
|
|
"type": "n8n-nodes-base.errorTrigger",
|
|
"position": [200, 500]
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Send Error Email",
|
|
"type": "n8n-nodes-base.emailSend",
|
|
"position": [400, 500],
|
|
"parameters": {
|
|
"toEmail": "admin@example.com",
|
|
"subject": "Workflow Error: {{$node['Error Handler'].json.error.message}}",
|
|
"text": "Error details: {{$json}}"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Error Handler",
|
|
"target": "Send Error Email"
|
|
},
|
|
{
|
|
"type": "updateSettings",
|
|
"settings": {
|
|
"errorWorkflow": "workflow-999"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Example 5: Large Batch Workflow Refactoring
|
|
Demonstrates handling many operations in a single request - no longer limited to 5 operations!
|
|
|
|
```json
|
|
{
|
|
"id": "workflow-batch",
|
|
"operations": [
|
|
// Add 10 processing nodes
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Filter Active Users",
|
|
"type": "n8n-nodes-base.filter",
|
|
"position": [400, 200],
|
|
"parameters": { "conditions": { "boolean": [{ "value1": "={{$json.active}}", "value2": true }] } }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Transform User Data",
|
|
"type": "n8n-nodes-base.set",
|
|
"position": [600, 200],
|
|
"parameters": { "values": { "string": [{ "name": "formatted_name", "value": "={{$json.firstName}} {{$json.lastName}}" }] } }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Validate Email",
|
|
"type": "n8n-nodes-base.if",
|
|
"position": [800, 200],
|
|
"parameters": { "conditions": { "string": [{ "value1": "={{$json.email}}", "operation": "contains", "value2": "@" }] } }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Enrich with API",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"position": [1000, 150],
|
|
"parameters": { "url": "https://api.example.com/enrich", "method": "POST" }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Log Invalid Emails",
|
|
"type": "n8n-nodes-base.code",
|
|
"position": [1000, 350],
|
|
"parameters": { "jsCode": "console.log('Invalid email:', $json.email);\nreturn $json;" }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Merge Results",
|
|
"type": "n8n-nodes-base.merge",
|
|
"position": [1200, 250]
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Deduplicate",
|
|
"type": "n8n-nodes-base.removeDuplicates",
|
|
"position": [1400, 250],
|
|
"parameters": { "propertyName": "id" }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Sort by Date",
|
|
"type": "n8n-nodes-base.sort",
|
|
"position": [1600, 250],
|
|
"parameters": { "sortFieldsUi": { "sortField": [{ "fieldName": "created_at", "order": "descending" }] } }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Batch for DB",
|
|
"type": "n8n-nodes-base.splitInBatches",
|
|
"position": [1800, 250],
|
|
"parameters": { "batchSize": 100 }
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Save to Database",
|
|
"type": "n8n-nodes-base.postgres",
|
|
"position": [2000, 250],
|
|
"parameters": { "operation": "insert", "table": "processed_users" }
|
|
}
|
|
},
|
|
// Connect all the nodes
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Get Users",
|
|
"target": "Filter Active Users"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Filter Active Users",
|
|
"target": "Transform User Data"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Transform User Data",
|
|
"target": "Validate Email"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Validate Email",
|
|
"sourceOutput": "true",
|
|
"target": "Enrich with API"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Validate Email",
|
|
"sourceOutput": "false",
|
|
"target": "Log Invalid Emails"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Enrich with API",
|
|
"target": "Merge Results"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Log Invalid Emails",
|
|
"target": "Merge Results",
|
|
"targetInput": "input2"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Merge Results",
|
|
"target": "Deduplicate"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Deduplicate",
|
|
"target": "Sort by Date"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Sort by Date",
|
|
"target": "Batch for DB"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Batch for DB",
|
|
"target": "Save to Database"
|
|
},
|
|
// Update workflow metadata
|
|
{
|
|
"type": "updateName",
|
|
"name": "User Processing Pipeline v2"
|
|
},
|
|
{
|
|
"type": "updateSettings",
|
|
"settings": {
|
|
"executionOrder": "v1",
|
|
"timezone": "UTC",
|
|
"saveDataSuccessExecution": "all"
|
|
}
|
|
},
|
|
{
|
|
"type": "addTag",
|
|
"tag": "production"
|
|
},
|
|
{
|
|
"type": "addTag",
|
|
"tag": "user-processing"
|
|
},
|
|
{
|
|
"type": "addTag",
|
|
"tag": "v2"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
This example shows 26 operations in a single request, creating a complete data processing pipeline with proper error handling, validation, and batch processing.
|
|
|
|
## Best Practices
|
|
|
|
1. **Use Descriptive Names**: Always provide clear node names and descriptions for operations
|
|
2. **Batch Related Changes**: Group related operations in a single request
|
|
3. **Validate First**: Use `validateOnly: true` to test your operations before applying
|
|
4. **Reference by Name**: Prefer node names over IDs for better readability
|
|
5. **Small, Focused Changes**: Make targeted edits rather than large structural changes
|
|
|
|
## Common Patterns
|
|
|
|
### Add Processing Step
|
|
```json
|
|
{
|
|
"operations": [
|
|
{
|
|
"type": "removeConnection",
|
|
"source": "Source Node",
|
|
"target": "Target Node"
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Process Step",
|
|
"type": "n8n-nodes-base.set",
|
|
"position": [600, 300],
|
|
"parameters": { /* ... */ }
|
|
}
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Source Node",
|
|
"target": "Process Step"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Process Step",
|
|
"target": "Target Node"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Replace Node
|
|
```json
|
|
{
|
|
"operations": [
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "New Implementation",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"position": [600, 300],
|
|
"parameters": { /* ... */ }
|
|
}
|
|
},
|
|
{
|
|
"type": "removeConnection",
|
|
"source": "Previous Node",
|
|
"target": "Old Implementation"
|
|
},
|
|
{
|
|
"type": "removeConnection",
|
|
"source": "Old Implementation",
|
|
"target": "Next Node"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Previous Node",
|
|
"target": "New Implementation"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "New Implementation",
|
|
"target": "Next Node"
|
|
},
|
|
{
|
|
"type": "removeNode",
|
|
"nodeName": "Old Implementation"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The tool validates all operations before applying any changes. Common errors include:
|
|
|
|
- **Duplicate node names**: Each node must have a unique name
|
|
- **Invalid node types**: Use full package prefixes (e.g., `n8n-nodes-base.webhook`)
|
|
- **Missing connections**: Referenced nodes must exist
|
|
- **Circular dependencies**: Connections cannot create loops
|
|
|
|
Always check the response for validation errors and adjust your operations accordingly.
|
|
|
|
## Transactional Updates (v2.7.0+)
|
|
|
|
The diff engine now supports transactional updates using a **two-pass processing** approach:
|
|
|
|
### How It Works
|
|
|
|
1. **Operation Limit**: Maximum 5 operations per request to ensure reliability
|
|
2. **Two-Pass Processing**:
|
|
- **Pass 1**: All node operations (add, remove, update, move, enable, disable)
|
|
- **Pass 2**: All other operations (connections, settings, metadata)
|
|
|
|
This allows you to add nodes and connect them in the same request:
|
|
|
|
```json
|
|
{
|
|
"id": "workflow-id",
|
|
"operations": [
|
|
// These will be processed in Pass 2 (but work because nodes are added first)
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Webhook",
|
|
"target": "Process Data"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Process Data",
|
|
"target": "Send Email"
|
|
},
|
|
// These will be processed in Pass 1
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Process Data",
|
|
"type": "n8n-nodes-base.set",
|
|
"position": [400, 300],
|
|
"parameters": {}
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Send Email",
|
|
"type": "n8n-nodes-base.emailSend",
|
|
"position": [600, 300],
|
|
"parameters": {
|
|
"to": "user@example.com"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Benefits
|
|
|
|
- **Order Independence**: You don't need to worry about operation order
|
|
- **Atomic Updates**: All operations succeed or all fail
|
|
- **Intuitive Usage**: Add complex workflow structures in one call
|
|
- **Clear Limits**: 5 operations max keeps things simple and reliable
|
|
|
|
### Example: Complete Workflow Addition
|
|
|
|
```json
|
|
{
|
|
"id": "workflow-id",
|
|
"operations": [
|
|
// Add three nodes
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Schedule",
|
|
"type": "n8n-nodes-base.schedule",
|
|
"position": [200, 300],
|
|
"parameters": {
|
|
"rule": {
|
|
"interval": [{ "field": "hours", "intervalValue": 1 }]
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Get Data",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"position": [400, 300],
|
|
"parameters": {
|
|
"url": "https://api.example.com/data"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "addNode",
|
|
"node": {
|
|
"name": "Save to Database",
|
|
"type": "n8n-nodes-base.postgres",
|
|
"position": [600, 300],
|
|
"parameters": {
|
|
"operation": "insert"
|
|
}
|
|
}
|
|
},
|
|
// Connect them all
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Schedule",
|
|
"target": "Get Data"
|
|
},
|
|
{
|
|
"type": "addConnection",
|
|
"source": "Get Data",
|
|
"target": "Save to Database"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
All 5 operations will be processed correctly regardless of order! |