diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index b093aff..98d428c 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp-skills", - "version": "1.0.0", + "version": "1.1.0", "description": "Expert skills for building n8n workflows with n8n-mcp", "author": { "name": "Romuald Członkowski", diff --git a/CLAUDE.md b/CLAUDE.md index a2db069..7e25afd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,10 +8,10 @@ This is the **n8n-skills** repository - a collection of Claude Code skills desig **Repository**: https://github.com/czlonkowski/n8n-skills -**Purpose**: Create 5 complementary meta-skills that provide expert guidance on using n8n-mcp MCP tools effectively for building n8n workflows. +**Purpose**: 7 complementary skills that provide expert guidance on using n8n-mcp MCP tools effectively for building n8n workflows. **Architecture**: -- **n8n-mcp MCP Server**: Provides data access (525 nodes, validation, templates) +- **n8n-mcp MCP Server**: Provides data access (800+ nodes, validation, templates, workflow management) - **Claude Skills**: Provides expert guidance on HOW to use MCP tools - **Together**: Expert workflow builder with progressive disclosure @@ -19,120 +19,91 @@ This is the **n8n-skills** repository - a collection of Claude Code skills desig ``` n8n-skills/ -├── README.md # Project overview -├── LICENSE # MIT License -├── skills/ # (To be created) Individual skill implementations +├── README.md # Project overview with video +├── LICENSE # MIT License +├── skills/ # Individual skill implementations │ ├── n8n-expression-syntax/ │ ├── n8n-mcp-tools-expert/ │ ├── n8n-workflow-patterns/ │ ├── n8n-validation-expert/ -│ └── n8n-node-configuration/ -├── evaluations/ # (To be created) Test scenarios for each skill -├── docs/ # Documentation -│ └── SKILLS_IMPLEMENTATION_GUIDE.md # Complete implementation guide -└── .gitignore # Git ignore (excludes docs/) +│ ├── n8n-node-configuration/ +│ ├── n8n-code-javascript/ +│ └── n8n-code-python/ +├── evaluations/ # Test scenarios for each skill +├── docs/ # Documentation +├── dist/ # Distribution packages +└── .claude-plugin/ # Claude Code plugin configuration ``` -## Implementation Timeline - -- **Week 1**: n8n Expression Syntax (PoC - 4 files, ~350 lines) -- **Week 2**: n8n MCP Tools Expert + n8n Workflow Patterns -- **Week 3**: n8n Validation Expert + n8n Node Configuration -- **Week 4**: Testing, refinement, documentation -- **Week 5-6**: Distribution, plugin packaging - -## Five Skills to Implement +## The 7 Skills ### 1. n8n Expression Syntax -**Priority**: Foundation (Week 1) - Teaches correct n8n expression syntax ({{}} patterns) - Covers common mistakes and fixes -- Files: SKILL.md, COMMON_MISTAKES.md, EXAMPLES.md +- Critical gotcha: Webhook data under `$json.body` -### 2. n8n MCP Tools Expert -**Priority**: Highest (fixes 20% failure rate) +### 2. n8n MCP Tools Expert (HIGHEST PRIORITY) - Teaches how to use n8n-mcp MCP tools effectively -- Covers node discovery, validation, workflow management -- Files: SKILL.md, SEARCH_GUIDE.md, VALIDATION_GUIDE.md, WORKFLOW_GUIDE.md +- Covers unified tools: `get_node`, `validate_node`, `search_nodes` +- Workflow management with `n8n_update_partial_workflow` +- New: `n8n_deploy_template`, `n8n_workflow_versions`, `activateWorkflow` ### 3. n8n Workflow Patterns -**Priority**: High (addresses 813 webhook searches) - Teaches proven workflow architectural patterns -- 5 patterns from 31,917 real workflows -- Files: SKILL.md + 5 pattern files (webhook, http, database, ai, scheduled) +- 5 patterns: webhook, HTTP API, database, AI, scheduled ### 4. n8n Validation Expert -**Priority**: Medium - Interprets validation errors and guides fixing - Handles false positives and validation loops -- Files: SKILL.md, ERROR_CATALOG.md, FALSE_POSITIVES.md +- Auto-fix with `n8n_autofix_workflow` ### 5. n8n Node Configuration -**Priority**: Medium - Operation-aware node configuration guidance - Property dependencies and common patterns -- Files: SKILL.md, DEPENDENCIES.md, OPERATION_PATTERNS.md -## Data-Driven Design +### 6. n8n Code JavaScript +- Write JavaScript in n8n Code nodes +- Data access patterns, `$helpers`, DateTime -These skills are based on telemetry analysis of: -- 447,557 real MCP tool usage events -- 31,917 workflows created -- 19,113 validation errors -- 15,107 validation feedback loops +### 7. n8n Code Python +- Write Python in n8n Code nodes +- Limitations awareness (no external libraries) -## Skill Structure +## Key MCP Tools -Each skill follows this format: +The n8n-mcp server provides these unified tools: -```markdown ---- -name: Skill Name -description: When to use this skill. Use when [trigger conditions]. ---- +### Node Discovery +- `search_nodes` - Find nodes by keyword +- `get_node` - Unified node info with detail levels (minimal, standard, full) and modes (info, docs, search_properties, versions) -# Skill Name +### Validation +- `validate_node` - Unified validation with modes (minimal, full) and profiles (runtime, ai-friendly, strict) +- `validate_workflow` - Complete workflow validation -## [Content organized in sections] -``` +### Workflow Management +- `n8n_create_workflow` - Create new workflows +- `n8n_update_partial_workflow` - Incremental updates (17 operation types including `activateWorkflow`) +- `n8n_validate_workflow` - Validate by ID +- `n8n_autofix_workflow` - Auto-fix common issues +- `n8n_deploy_template` - Deploy template to n8n instance +- `n8n_workflow_versions` - Version history and rollback +- `n8n_test_workflow` - Test execution +- `n8n_executions` - Manage executions -## Development Approach +### Templates +- `search_templates` - Multiple modes (keyword, by_nodes, by_task, by_metadata) +- `get_template` - Get template details -**Evaluation-Driven Development**: -1. Create 3+ evaluations FIRST for each skill -2. Establish baseline (test without skill) -3. Write minimal SKILL.md (under 500 lines) -4. Test against evaluations -5. Iterate until 100% pass -6. Add reference files as needed +### Guides +- `tools_documentation` - Meta-documentation for all tools +- `ai_agents_guide` - AI agent workflow guidance -## Key Implementation Guidelines - -### File Organization -- Keep SKILL.md files under 500 lines -- Split complex content into reference files -- Use markdown with clear sections -- Link between related files - -### Skill Activation -Skills activate automatically when queries match their description triggers: -- "How do I write n8n expressions?" → n8n Expression Syntax -- "Find me a Slack node" → n8n MCP Tools Expert -- "Build a webhook workflow" → n8n Workflow Patterns - -### Cross-Skill Integration -Skills are designed to work together: -- Use n8n Workflow Patterns to identify structure -- Use n8n MCP Tools Expert to find nodes -- Use n8n Node Configuration for setup -- Use n8n Expression Syntax for data mapping -- Use n8n Validation Expert to validate - -## Important Patterns from Telemetry +## Important Patterns ### Most Common Tool Usage Pattern ``` -search_nodes → get_node_essentials (9,835 occurrences, 18s avg) +search_nodes → get_node (18s avg between steps) ``` ### Most Common Validation Pattern @@ -151,34 +122,25 @@ Avg 56 seconds between edits ### When Adding New Skills 1. Create skill directory under `skills/` -2. Follow the structure in `docs/SKILLS_IMPLEMENTATION_GUIDE.md` -3. Write SKILL.md with frontmatter -4. Add reference files as needed -5. Create 3+ evaluations in `evaluations/` -6. Test thoroughly before committing +2. Write SKILL.md with frontmatter +3. Add reference files as needed +4. Create 3+ evaluations in `evaluations/` +5. Test thoroughly before committing -### When Creating Evaluations -Place in `evaluations/[skill-name]/eval-NNN-description.json` +### Skill Activation +Skills activate automatically when queries match their description triggers: +- "How do I write n8n expressions?" → n8n Expression Syntax +- "Find me a Slack node" → n8n MCP Tools Expert +- "Build a webhook workflow" → n8n Workflow Patterns -Format: -```json -{ - "id": "skill-NNN", - "skills": ["skill-name"], - "query": "User question or scenario", - "expected_behavior": [ - "List of expected behaviors", - "What skill should do", - "What content it should reference" - ] -} -``` - -### Git Workflow -- Work on feature branches -- Commit frequently with clear messages -- Test skills before pushing -- Keep main branch stable +### Cross-Skill Integration +Skills are designed to work together: +- Use n8n Workflow Patterns to identify structure +- Use n8n MCP Tools Expert to find nodes +- Use n8n Node Configuration for setup +- Use n8n Expression Syntax for data mapping +- Use n8n Code JavaScript/Python for custom logic +- Use n8n Validation Expert to validate ## Requirements @@ -188,9 +150,9 @@ Format: ## Distribution -Final distribution will be: +Available as: 1. **GitHub Repository**: Full source code and documentation -2. **Claude Code Plugin**: Packaged skills with plugin.json +2. **Claude Code Plugin**: `npm install @anthropic/claude-code-plugin-n8n-skills` 3. **Individual Skill Uploads**: For Claude.ai users ## Credits @@ -202,4 +164,4 @@ Part of the n8n-mcp project. ## License MIT License - See LICENSE file for details. -- Add to every commit and PR: Concieved by Romuald Członkowski - and then link to www.aiadvisors.pl/en. Don't add it in conversations \ No newline at end of file +- Add to every commit and PR: Conceived by Romuald Członkowski - and then link to www.aiadvisors.pl/en. Don't add it in conversations diff --git a/README.md b/README.md index dae2f45..ae55bca 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,19 @@ **Expert Claude Code skills for building flawless n8n workflows using the n8n-mcp MCP server** +[![GitHub stars](https://img.shields.io/github/stars/czlonkowski/n8n-skills?style=social)](https://github.com/czlonkowski/n8n-skills) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![n8n-mcp](https://img.shields.io/badge/n8n--mcp-compatible-green.svg)](https://github.com/czlonkowski/n8n-mcp) +## Watch the Introduction Video + +[![n8n Skills Introduction](skills.png)](https://youtu.be/e6VvRqmUY2Y?si=6Igply3cadjO6Xx0) + --- ## 🎯 What is this? -This repository contains 5 complementary **Claude Code skills** that teach AI assistants how to build production-ready n8n workflows using the [n8n-mcp](https://github.com/czlonkowski/n8n-mcp) MCP server. +This repository contains **7 complementary Claude Code skills** that teach AI assistants how to build production-ready n8n workflows using the [n8n-mcp](https://github.com/czlonkowski/n8n-mcp) MCP server. ### Why These Skills Exist diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..34678a2 --- /dev/null +++ b/build.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Build script for n8n-skills distribution packages +# Creates zip files for both Claude.ai (individual skills) and Claude Code (bundle) + +set -e + +DIST_DIR="dist" +VERSION="1.1.0" + +echo "🔨 Building n8n-skills distribution packages..." + +# Create dist directory if it doesn't exist +mkdir -p "$DIST_DIR" + +# Remove old zips +echo "🗑️ Removing old zip files..." +rm -f "$DIST_DIR"/*.zip + +# Build individual skill zips (for Claude.ai) +echo "📦 Building individual skill zips for Claude.ai..." + +SKILLS=( + "n8n-expression-syntax" + "n8n-mcp-tools-expert" + "n8n-workflow-patterns" + "n8n-validation-expert" + "n8n-node-configuration" +) + +for skill in "${SKILLS[@]}"; do + echo " - $skill" + zip -rq "$DIST_DIR/${skill}-v${VERSION}.zip" "skills/${skill}/" -x "*.DS_Store" +done + +# Build complete bundle (for Claude Code) +echo "📦 Building complete bundle for Claude Code..." +zip -rq "$DIST_DIR/n8n-mcp-skills-v${VERSION}.zip" \ + .claude-plugin/ \ + README.md \ + LICENSE \ + skills/ \ + -x "*.DS_Store" + +# Show results +echo "" +echo "✅ Build complete! Files in $DIST_DIR/:" +echo "" +ls -lh "$DIST_DIR"/*.zip +echo "" +echo "📊 Package sizes:" +du -h "$DIST_DIR"/*.zip diff --git a/dist/README.md b/dist/README.md index 1cdf4a9..178694c 100644 --- a/dist/README.md +++ b/dist/README.md @@ -6,7 +6,7 @@ This folder contains distribution packages for different Claude platforms. ### Complete Bundle (Recommended) -- **`n8n-mcp-skills-v1.0.0.zip`** (168 KB) - All 7 skills in one package +- **`n8n-mcp-skills-v1.1.0.zip`** (172 KB) - All 7 skills in one package **Includes:** - Skill #1: n8n Expression Syntax @@ -23,18 +23,18 @@ This folder contains distribution packages for different Claude platforms. /plugin install czlonkowski/n8n-skills # Or install from local file -/plugin install /path/to/n8n-mcp-skills-v1.0.0.zip +/plugin install /path/to/n8n-mcp-skills-v1.1.0.zip ``` ### For Claude.ai Users (Individual Skills) Upload each skill separately via Settings → Capabilities → Skills (bottom of page): -- `n8n-expression-syntax-v1.0.0.zip` - n8n expression syntax and common patterns -- `n8n-mcp-tools-expert-v1.0.0.zip` - Expert guide for using n8n-mcp tools (recommended to install first) -- `n8n-workflow-patterns-v1.0.0.zip` - 5 proven workflow architectural patterns -- `n8n-validation-expert-v1.0.0.zip` - Validation error interpretation and fixing -- `n8n-node-configuration-v1.0.0.zip` - Operation-aware node configuration +- `n8n-expression-syntax-v1.1.0.zip` - n8n expression syntax and common patterns +- `n8n-mcp-tools-expert-v1.1.0.zip` - Expert guide for using n8n-mcp tools (recommended to install first) +- `n8n-workflow-patterns-v1.1.0.zip` - 5 proven workflow architectural patterns +- `n8n-validation-expert-v1.1.0.zip` - Validation error interpretation and fixing +- `n8n-node-configuration-v1.1.0.zip` - Operation-aware node configuration **Installation:** 1. Go to Settings → Capabilities → Skills (bottom of page) @@ -49,7 +49,7 @@ Upload each skill separately via Settings → Capabilities → Skills (bottom of | Platform | Package | What You Get | |----------|---------|--------------| | **Claude.ai** | Individual zips | 5 core skills (upload separately) | -| **Claude Code** | Complete bundle (n8n-mcp-skills-v1.0.0.zip) | All 7 skills at once | +| **Claude Code** | Complete bundle (n8n-mcp-skills-v1.1.0.zip) | All 7 skills at once | | **Claude API** | Complete bundle | All 7 skills (extract skills/ folder) | **Note:** Code skills (#6 JavaScript, #7 Python) are only in the complete bundle. @@ -60,12 +60,12 @@ Upload each skill separately via Settings → Capabilities → Skills (bottom of ``` dist/ -├── n8n-mcp-skills-v1.0.0.zip (168 KB) ★ RECOMMENDED -├── n8n-expression-syntax-v1.0.0.zip (11 KB) -├── n8n-mcp-tools-expert-v1.0.0.zip (15 KB) -├── n8n-workflow-patterns-v1.0.0.zip (35 KB) -├── n8n-validation-expert-v1.0.0.zip (18 KB) -├── n8n-node-configuration-v1.0.0.zip (17 KB) +├── n8n-mcp-skills-v1.1.0.zip (168 KB) ★ RECOMMENDED +├── n8n-expression-syntax-v1.1.0.zip (11 KB) +├── n8n-mcp-tools-expert-v1.1.0.zip (15 KB) +├── n8n-workflow-patterns-v1.1.0.zip (35 KB) +├── n8n-validation-expert-v1.1.0.zip (18 KB) +├── n8n-node-configuration-v1.1.0.zip (17 KB) └── README.md (this file) ``` diff --git a/dist/n8n-expression-syntax-v1.0.0.zip b/dist/n8n-expression-syntax-v1.1.0.zip similarity index 81% rename from dist/n8n-expression-syntax-v1.0.0.zip rename to dist/n8n-expression-syntax-v1.1.0.zip index 272aeda..55e450a 100644 Binary files a/dist/n8n-expression-syntax-v1.0.0.zip and b/dist/n8n-expression-syntax-v1.1.0.zip differ diff --git a/dist/n8n-mcp-skills-v1.0.0.zip b/dist/n8n-mcp-skills-v1.1.0.zip similarity index 66% rename from dist/n8n-mcp-skills-v1.0.0.zip rename to dist/n8n-mcp-skills-v1.1.0.zip index acdd63c..a12426b 100644 Binary files a/dist/n8n-mcp-skills-v1.0.0.zip and b/dist/n8n-mcp-skills-v1.1.0.zip differ diff --git a/dist/n8n-mcp-tools-expert-v1.0.0.zip b/dist/n8n-mcp-tools-expert-v1.0.0.zip deleted file mode 100644 index 2c6070e..0000000 Binary files a/dist/n8n-mcp-tools-expert-v1.0.0.zip and /dev/null differ diff --git a/dist/n8n-mcp-tools-expert-v1.1.0.zip b/dist/n8n-mcp-tools-expert-v1.1.0.zip new file mode 100644 index 0000000..08c69f5 Binary files /dev/null and b/dist/n8n-mcp-tools-expert-v1.1.0.zip differ diff --git a/dist/n8n-node-configuration-v1.0.0.zip b/dist/n8n-node-configuration-v1.0.0.zip deleted file mode 100644 index 143a677..0000000 Binary files a/dist/n8n-node-configuration-v1.0.0.zip and /dev/null differ diff --git a/dist/n8n-node-configuration-v1.1.0.zip b/dist/n8n-node-configuration-v1.1.0.zip new file mode 100644 index 0000000..8756508 Binary files /dev/null and b/dist/n8n-node-configuration-v1.1.0.zip differ diff --git a/dist/n8n-validation-expert-v1.0.0.zip b/dist/n8n-validation-expert-v1.0.0.zip deleted file mode 100644 index 9af4003..0000000 Binary files a/dist/n8n-validation-expert-v1.0.0.zip and /dev/null differ diff --git a/dist/n8n-validation-expert-v1.1.0.zip b/dist/n8n-validation-expert-v1.1.0.zip new file mode 100644 index 0000000..8cef4ed Binary files /dev/null and b/dist/n8n-validation-expert-v1.1.0.zip differ diff --git a/dist/n8n-workflow-patterns-v1.0.0.zip b/dist/n8n-workflow-patterns-v1.1.0.zip similarity index 73% rename from dist/n8n-workflow-patterns-v1.0.0.zip rename to dist/n8n-workflow-patterns-v1.1.0.zip index 3ab3f41..7c9ca7d 100644 Binary files a/dist/n8n-workflow-patterns-v1.0.0.zip and b/dist/n8n-workflow-patterns-v1.1.0.zip differ diff --git a/docs/CODE_NODE_BEST_PRACTICES.md b/docs/CODE_NODE_BEST_PRACTICES.md new file mode 100644 index 0000000..7511c69 --- /dev/null +++ b/docs/CODE_NODE_BEST_PRACTICES.md @@ -0,0 +1,1204 @@ +# n8n CODE Node - Best Practices & Pattern Analysis + +**Analysis Period:** Last 60 days | **Data Quality:** 38,094 CODE node instances analyzed + +--- + +## Executive Summary + +- **47.16% of workflows use CODE nodes** (15,202 workflows from 4,461 unique users) +- **Top 3 data access patterns:** `$input.all()` (26% usage), `$input.first()` (25%), `$input.item` (19%) +- **Critical finding:** 39% validation failures are due to empty code or missing return values +- **Best return pattern:** `return [{json: {...}}]` (39% of successful nodes) + +--- + +## 1. Node Configuration Essentials + +### Choosing the Right Mode + +The Code node offers two execution modes that determine how your code processes input data: + +#### **Run Once for All Items** (Default - Recommended for most use cases) +- Code executes **once** regardless of input count +- Access all items via `$input.all()` or `items` array +- **Best for:** Aggregation, filtering, batch processing, transformations +- **Performance:** Faster for multiple items (single execution) +- **Usage:** 78% of successful workflows use this mode + +```javascript +// Example: Process all items together +const allItems = $input.all(); +const total = allItems.reduce((sum, item) => sum + item.json.amount, 0); +return [{json: {total, count: allItems.length}}]; +``` + +#### **Run Once for Each Item** +- Code executes **separately** for each input item +- Access current item via `$input.item` or `$item` +- **Best for:** Item-specific logic, independent operations, item validation +- **Performance:** Slower for large datasets (multiple executions) +- **Usage:** 22% of workflows (specialized cases) + +```javascript +// Example: Process each item independently +const item = $input.item; +return [{ + json: { + ...item.json, + processed: true, + processedAt: new Date().toISOString() + } +}]; +``` + +**Decision Guide:** +- ✅ Use "All Items" when: Comparing items, calculating totals, sorting, deduplication +- ✅ Use "Each Item" when: Item-specific API calls, individual validations, per-item errors + +--- + +### Language Selection + +| Language | Use Case | Performance | Built-ins | Beta Status | +|----------|----------|-------------|-----------|-------------| +| **JavaScript** | General purpose, web APIs, JSON | Fast | Full n8n helpers | Stable | +| **Python (Beta)** | Data science, ML, complex math | Slower | `_` syntax helpers | Beta | +| **Python (Native)** | Standard Python, no helpers | Medium | `_items`, `_item` only | Beta | + +**Recommendation:** Use JavaScript for 95% of use cases. Only use Python when you need specific libraries or data science capabilities. + +--- + +## 2. Top 10 Successful CODE Node Patterns + +### Pattern 1: Multi-source Data Aggregation +```javascript +// Process and structure collected data from multiple sources +const allItems = $input.all(); +let processedArticles = []; + +// Handle different source formats +for (const item of allItems) { + const sourceName = item.json.name || 'Unknown'; + const sourceData = item.json; + + // Parse source-specific structure + if (sourceName === 'Hacker News' && sourceData.hits) { + for (const hit of sourceData.hits) { + processedArticles.push({ + title: hit.title, + url: hit.url, + summary: hit.story_text || 'No summary', + source: 'Hacker News', + score: hit.points || 0 + }); + } + } +} + +return processedArticles.map(article => ({ json: article })); +``` +**Use Case:** Aggregating data from APIs, RSS feeds, webhooks +**Key Techniques:** Loop iteration, conditional parsing, data normalization + +--- + +### Pattern 2: Regex Filtering & Pattern Matching +```javascript +// Extract and filter mentions using regex patterns +const etfPattern = /\b([A-Z]{2,5})\b/g; +const knownETFs = ['VOO', 'VTI', 'VT', 'SCHD', 'QYLD', 'VXUS']; + +const etfMentions = {}; + +for (const item of $input.all()) { + const data = item.json.data; + if (!data?.children) continue; + + for (const post of data.children) { + const combinedText = (post.data.title + ' ' + post.data.selftext).toUpperCase(); + const matches = combinedText.match(etfPattern); + + if (matches) { + for (const match of matches) { + if (knownETFs.includes(match)) { + if (!etfMentions[match]) { + etfMentions[match] = { count: 0, totalScore: 0, posts: [] }; + } + etfMentions[match].count++; + } + } + } + } +} + +return Object.entries(etfMentions) + .map(([etf, data]) => ({ json: { etf, ...data } })) + .sort((a, b) => b.json.count - a.json.count); +``` +**Use Case:** Content analysis, keyword extraction, mention tracking +**Key Techniques:** Regex matching, object aggregation, sorting/ranking + +--- + +### Pattern 3: Markdown Parsing & Structured Data Extraction +```javascript +// Parse markdown and extract structured information +const markdown = $input.first().json.data.markdown; +const adRegex = /##\s*(.*?)\n(.*?)(?=\n##|\n---|$)/gs; + +const ads = []; +let match; + +function parseTimeToMinutes(timeStr) { + if (!timeStr) return 999999; + + const hourMatch = timeStr.match(/(\d+)\s*hour/); + const dayMatch = timeStr.match(/(\d+)\s*day/); + + let totalMinutes = 0; + if (hourMatch) totalMinutes += parseInt(hourMatch[1]) * 60; + if (dayMatch) totalMinutes += parseInt(dayMatch[1]) * 1440; + + return totalMinutes; +} + +while ((match = adRegex.exec(markdown)) !== null) { + const title = match[1]?.trim() || 'No title'; + const content = match[2]?.trim() || ''; + + const districtMatch = content.match(/\*\*District:\*\*\s*(.*?)(?:\n|$)/); + const timeMatch = content.match(/Posted:\s*(.*?)\*/); + + ads.push({ + title: title, + district: districtMatch?.[1].trim() || 'Unknown', + timeInMinutes: parseTimeToMinutes(timeMatch?.[1]), + fullContent: content + }); +} + +return ads.map(ad => ({ json: ad })); +``` +**Use Case:** Parsing formatted text, extracting structured fields +**Key Techniques:** Regex grouping, helper functions, data normalization + +--- + +### Pattern 4: JSON Comparison & Validation +```javascript +// Compare and validate JSON objects from different sources +const orderJsonKeys = (jsonObj) => { + const ordered = {}; + Object.keys(jsonObj).sort().forEach(key => { + ordered[key] = jsonObj[key]; + }); + return ordered; +}; + +const origWorkflow = JSON.parse( + Buffer.from($input.all()[0].json.content, 'base64').toString() +); +const n8nWorkflow = $input.all()[1].json; + +const orderedOriginal = orderJsonKeys(origWorkflow); +const orderedActual = orderJsonKeys(n8nWorkflow); + +const isSame = JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual); + +$input.all()[0].json.status = isSame ? 'same' : 'different'; +$input.all()[0].json.original_data = orderedOriginal; + +return $input.all(); +``` +**Use Case:** Workflow versioning, configuration validation, change detection +**Key Techniques:** JSON ordering, base64 decoding, deep comparison + +--- + +### Pattern 5: CRM Data Transformation +```javascript +// Transform form data into CRM-compatible format +const item = $input.all()[0]; +const { name, email, phone, company, course_interest, message, timestamp } = item.json; + +const nameParts = name.split(' '); +const firstName = nameParts[0] || ''; +const lastName = nameParts.slice(1).join(' ') || 'Unknown'; + +const crmData = { + data: { + type: 'Contact', + attributes: { + first_name: firstName, + last_name: lastName, + email1: email, + phone_work: phone, + account_name: company, + description: `Course: ${course_interest}\nMessage: ${message}\nTimestamp: ${timestamp}` + } + } +}; + +return [{ + json: { + ...item.json, + crmData, + processed: true + } +}]; +``` +**Use Case:** Lead enrichment, data normalization, API preparation +**Key Techniques:** Object destructuring, data mapping, format conversion + +--- + +### Pattern 6: Release Information Processing +```javascript +// Extract and filter stable releases from GitHub API +const allReleases = $input.first().json; +const stableReleases = allReleases + .filter(release => !release.prerelease && !release.draft) + .slice(0, 10) + .map(release => ({ + tag: release.tag_name, + name: release.name, + published: release.published_at, + publishedDate: new Date(release.published_at).toLocaleDateString(), + author: release.author.login, + url: release.html_url, + changelog: release.body || '(No changelog)', + highlights: release.body?.split('## Highlights:')[1]?.split('##')[0]?.trim() + || release.body?.substring(0, 500) + '...' + || 'No highlights available', + assetCount: release.assets.length + })); + +return stableReleases.map(release => ({ json: release })); +``` +**Use Case:** Version management, changelog parsing, release notes generation +**Key Techniques:** Array filtering, conditional field extraction, date formatting + +--- + +### Pattern 7: Array Transformation with Context +```javascript +// Transform and map data with additional context +const stableReleases = $input.first().json + .filter(release => !release.prerelease && !release.draft) + .slice(0, 10) + .map(release => ({ + version: release.tag_name, + assetCount: release.assets.length, + assetsCountText: release.assets.length === 1 ? 'file' : 'files' + })); + +return stableReleases.map(release => ({ json: release })); +``` +**Use Case:** Quick data transformation, simple field mapping +**Key Techniques:** Array methods chaining, pluralization logic + +--- + +### Pattern 8: Slack Block Kit Formatting +```javascript +// Create Slack-formatted message with structured blocks +const date = new Date().toISOString().split('T')[0]; + +return [{ + json: { + text: `Daily Report - ${date}`, + blocks: [ + { + type: "header", + text: { + type: "plain_text", + text: `📊 Daily Security Report - ${date}` + } + }, + { + type: "section", + text: { + type: "mrkdwn", + text: `*Status:* ✅ All Clear\n*Alerts:* 0\n*Updated:* ${new Date().toLocaleString()}` + } + }, + { + type: "context", + elements: [{ + type: "mrkdwn", + text: `Report generated automatically` + }] + } + ] + } +}]; +``` +**Use Case:** Chat notifications, rich message formatting +**Key Techniques:** Template literals, nested objects, Block Kit syntax + +--- + +### Pattern 9: Top N Filtering +```javascript +// Filter and rank by score, return top N results +const ragResponse = $input.item.json; +const chunks = ragResponse.chunks || []; + +const topChunks = chunks + .sort((a, b) => (b.similarity || 0) - (a.similarity || 0)) + .slice(0, 6); + +return [{ + json: { + topChunks: topChunks, + count: topChunks.length + } +}]; +``` +**Use Case:** RAG pipelines, ranking algorithms, result filtering +**Key Techniques:** Sorting, slicing, null coalescing + +--- + +### Pattern 10: String Aggregation & Reporting +```javascript +// Aggregate multiple text inputs into formatted report +const ragResponse = $input.item.json; +const markdown = ragResponse.data.markdown; + +const finalReport = $input.all() + .map(item => item.json.message) + .join('\n\n---\n\n'); + +const header = `🎯 **Report**\n📅 ${new Date().toLocaleString()}\n\n`; + +return [{ + json: { + report: header + finalReport, + timestamp: new Date().toISOString() + } +}]; +``` +**Use Case:** Report generation, log aggregation, content concatenation +**Key Techniques:** Array joining, string concatenation, timestamp handling + +--- + +## 2. Python Code Examples & Best Practices + +### Python vs JavaScript: Key Differences + +| Feature | JavaScript | Python (Beta) | Python (Native) | +|---------|-----------|---------------|-----------------| +| Input access | `$input.all()` | `_input.all()` | `_items` | +| Single item | `$input.first()` | `_input.first()` | `_items[0]` | +| Current item | `$input.item` | `_input.item` | `_item` | +| Return format | `[{json: {...}}]` | `[{json: {...}}]` | `[{"json": {...}}]` | +| Date helper | `$now` | `_now` | Standard datetime | +| JSON query | `$jmespath()` | `_jmespath()` | Not available | + +### Python Pattern 1: Data Transformation (Run Once for All Items) + +```python +# Python (Beta) - Using n8n helpers +items = _input.all() +processed = [] + +for item in items: + data = item["json"] + processed.append({ + "json": { + "id": data.get("id"), + "name": data.get("name", "Unknown"), + "processed": True, + "timestamp": _now.isoformat() + } + }) + +return processed +``` + +```python +# Python (Native) - Standard Python +processed = [] + +for item in _items: + data = item["json"] + processed.append({ + "json": { + "id": data.get("id"), + "name": data.get("name", "Unknown"), + "processed": True, + "timestamp": str(_now) # _now is datetime object + } + }) + +return processed +``` + +### Python Pattern 2: Filtering & Aggregation + +```python +# Filter and sum amounts +items = _input.all() +total = 0 +valid_items = [] + +for item in items: + amount = item["json"].get("amount", 0) + if amount > 0: + total += amount + valid_items.append(item["json"]) + +return [{ + "json": { + "total": total, + "count": len(valid_items), + "items": valid_items + } +}] +``` + +### Python Pattern 3: String Processing with Regex + +```python +import re + +# Extract emails from text +items = _input.all() +email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' + +all_emails = [] +for item in items: + text = item["json"].get("text", "") + emails = re.findall(email_pattern, text) + all_emails.extend(emails) + +# Remove duplicates +unique_emails = list(set(all_emails)) + +return [{ + "json": { + "emails": unique_emails, + "count": len(unique_emails) + } +}] +``` + +### Python Pattern 4: Data Science Operations + +```python +# Calculate statistics (Python Native with standard library) +from statistics import mean, median, stdev + +items = _items +values = [item["json"].get("value", 0) for item in items if "value" in item["json"]] + +if len(values) > 0: + return [{ + "json": { + "mean": mean(values), + "median": median(values), + "std_dev": stdev(values) if len(values) > 1 else 0, + "min": min(values), + "max": max(values), + "count": len(values) + } + }] +else: + return [{"json": {"error": "No values found"}}] +``` + +### Python Pattern 5: Dictionary/Object Manipulation + +```python +# Merge and deduplicate objects by key +items = _input.all() +merged = {} + +for item in items: + data = item["json"] + key = data.get("id") + + if key: + if key not in merged: + merged[key] = data + else: + # Merge properties, preferring newer values + merged[key].update({k: v for k, v in data.items() if v}) + +# Convert back to array format +result = [{"json": value} for value in merged.values()] +return result +``` + +### Python Best Practices + +1. **Always use `.get()` for dictionary access** to avoid KeyError + ```python + # ✅ Safe + value = item["json"].get("field", "default") + + # ❌ Risky + value = item["json"]["field"] # Crashes if field missing + ``` + +2. **Handle None/null values explicitly** + ```python + amount = item["json"].get("amount") or 0 # Default to 0 + text = item["json"].get("text", "").strip() # Default to empty string + ``` + +3. **Use list comprehensions for filtering** + ```python + # ✅ Pythonic + valid = [item for item in items if item["json"].get("active")] + + # ❌ Verbose + valid = [] + for item in items: + if item["json"].get("active"): + valid.append(item) + ``` + +4. **Return consistent structure** + ```python + # Always return list of objects with "json" key + return [{"json": result}] # Single result + return results # Multiple results (already formatted) + return [] # No results + ``` + +5. **Debug with print() statements** + ```python + print(f"Processing {len(items)} items") # Appears in browser console + print(f"Item data: {item['json']}") + ``` + +--- + +## 3. Common Data Access Patterns + +### Usage Distribution +| Pattern | Usage % | Best For | +|---------|---------|----------| +| `$input.all()` | 26% | Processing arrays, batch operations | +| `$input.first()` | 25% | Single item operations, first-last logic | +| `$input.item` | 19% | Item-by-item processing in loops | +| Other patterns | 16% | Complex scenarios | +| `$json` | 11% | Direct field access | +| `$node` | 1% | Referencing other node outputs | +| `$env` | 0.2% | Environment variables | +| `$binary` | 0.1% | Binary data processing | + +### Key Recommendations +1. **Use `$input.all()` when:** Processing multiple records, aggregating data, batch transformations +2. **Use `$input.first()` when:** Working with single objects, API responses, initial data processing +3. **Use `$input.item` when:** In split/loop contexts, iterating collections, item-by-item logic +4. **Avoid `$json` alone:** Always use `$input.first().json` or `$input.item.json` to ensure data availability + +--- + +## 3. Return Value Structures + +### Recommended Return Patterns +```javascript +// Pattern 1: Single object transformation (39% of successful nodes) +return [{ + json: { + field1: value1, + field2: value2 + } +}]; + +// Pattern 2: Array passthrough (24% of successful nodes) +return $input.all(); + +// Pattern 3: Mapped transformation (most common) +const transformed = $input.all() + .filter(item => item.json.valid) + .map(item => ({ + json: { + id: item.json.id, + processed: true, + timestamp: new Date().toISOString() + } + })); +return transformed; + +// Pattern 4: Conditional returns +if (shouldProcess) { + return [{json: processedData}]; +} else { + return []; // Empty array when no data +} + +// Pattern 5: Multiple outputs +const results = []; +for (const item of $input.all()) { + if (item.json.valid) { + results.push({json: item.json}); + } +} +return results; +``` + +### What NOT to Return +```javascript +// ❌ Incorrect: Raw data without json wrapper +return $input.all(); // Missing .map() + +// ❌ Incorrect: String instead of object +return "processed"; + +// ❌ Incorrect: Object without array wrapper +return { + json: {field: value} +}; + +// ❌ Incorrect: Incomplete structure +return [{data: value}]; // Should be: {json: value} + +// ❌ Incorrect: Throwing without structure +throw new Error("Something failed"); // No graceful handling +``` + +--- + +## 4. Top 5 Error Patterns to Avoid + +### Error #1: Empty Code (23% of validation failures) +``` +Message: "Code cannot be empty" +Occurrences: 58 + +Solution: Always include meaningful code or use a different node type +``` + +**What to Do:** +```javascript +// Always provide implementation +const items = $input.all(); +return items.map(item => ({ + json: { + ...item.json, + processed: true + } +})); +``` + +--- + +### Error #2: Missing Return Statement (15% of validation failures) +``` +Message: "Code must return data for the next node" +Occurrences: 29 + +Solution: Always return data, even if empty +``` + +**What to Do:** +```javascript +const items = $input.all(); + +// Always include a return statement +if (items.length === 0) { + return []; // Return empty array if no items +} + +return items.map(item => ({json: item.json})); +``` + +--- + +### Error #3: Expression Syntax Confusion (8% of validation failures) +``` +Message: "Expression syntax {{...}} is not valid in Code nodes" +Occurrences: 5 + +Solution: Use JavaScript template literals, NOT n8n expressions +``` + +**What to Do:** +```javascript +// ❌ Wrong: Using n8n expression syntax +const value = "{{ $json.field }}"; + +// ✅ Correct: Using JavaScript template literals +const value = `${$json.field}`; + +// ✅ Also correct: Direct access +const value = $input.first().json.field; +``` + +--- + +### Error #4: Unmatched Expression Brackets (6% of validation failures) +``` +Message: "Unmatched expression brackets: 0 opening, 1 closing" +Occurrences: 4 + +Solution: Ensure quote/bracket balance in JSONB storage +``` + +**What to Do:** +```javascript +// When storing multi-line strings, escape properly +const code = `const text = 'It\\'s working correctly'; +const result = text.split('\\n'); +return [{json: {result}}];`; + +// Test: Check all quotes are properly escaped +``` + +--- + +### Error #5: Incorrect Return Wrapper (5% of validation failures) +``` +Message: "Return value must be an array of objects" +Occurrences: 3 + +Solution: Always wrap output in array, each element must have json property +``` + +**What to Do:** +```javascript +// ❌ Wrong: Single object +return { + json: {field: value} +}; + +// ✅ Correct: Array of objects +return [{ + json: {field: value} +}]; + +// ✅ Also correct: Array with multiple items +return [ + {json: {id: 1, data: 'first'}}, + {json: {id: 2, data: 'second'}} +]; +``` + +--- + +## 5. Performance & Best Practices + +### Success Rate Metrics +- **47.16% of workflows** use CODE nodes +- **4,461 unique users** creating workflows with CODE nodes +- **Average patterns:** Most successful nodes combine 2-3 common techniques + +### Common Node Sequence Patterns +Most successful workflows follow this pattern: +1. HTTP Request / Webhook (data ingestion) +2. CODE node (transformation) +3. CODE node (normalization/enrichment) +4. Database write / API output + +### Optimization Tips + +**1. Use `$input.all()` over loops when possible:** +```javascript +// ❌ Slower: Multiple loops +let results = []; +for (const item of $input.all()) { + results.push({json: item.json}); +} + +// ✅ Faster: Single map operation +return $input.all().map(item => ({json: item.json})); +``` + +**2. Filter early, process late:** +```javascript +// ✅ Good: Filter first, then transform +const processed = $input.all() + .filter(item => item.json.valid) + .map(item => ({json: normalize(item.json)})); +``` + +**3. Pre-compile regex patterns:** +```javascript +// ✅ Define outside loop +const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + +for (const item of $input.all()) { + if (emailRegex.test(item.json.email)) { + // Process valid email + } +} +``` + +**4. Use guard clauses:** +```javascript +// ✅ Fail fast +if (!$input.first().json.data) { + return []; +} + +const data = $input.first().json.data; +// Continue processing +``` + +--- + +## 6. Library & Built-in Availability + +### n8n Built-in Methods & Variables (JavaScript) + +#### Core Data Access +| Method | Description | Example | +|--------|-------------|---------| +| `$input.all()` | Get all input items | `const items = $input.all();` | +| `$input.first()` | Get first input item | `const first = $input.first();` | +| `$input.last()` | Get last input item | `const last = $input.last();` | +| `$input.item` | Current item (Each Item mode) | `const current = $input.item;` | +| `items` | Array of all items (legacy) | `items[0].json.field` | +| `$json` | Current item JSON (Each Item mode) | `const field = $json.field;` | +| `$binary` | Current item binary data | `$binary.data` | + +#### Node & Workflow Context +| Method | Description | Example | +|--------|-------------|---------| +| `$node` | Reference other node outputs | `$node['HTTP Request'].json.data` | +| `$prevNode` | Access previous node data | `$prevNode.name` | +| `$workflow` | Workflow metadata | `$workflow.name`, `$workflow.id` | +| `$execution` | Execution context | `$execution.id`, `$execution.mode` | +| `$env` | Environment variables | `$env.MY_VAR` | + +#### Date & Time Helpers (Luxon-based) +| Variable | Description | Example Output | +|----------|-------------|----------------| +| `$now` | Current datetime object | Luxon DateTime | +| `$today` | Today at midnight | Luxon DateTime | +| `$now.toISO()` | ISO 8601 format | `"2025-01-20T10:30:00.000Z"` | +| `$now.toFormat('yyyy-MM-dd')` | Custom format | `"2025-01-20"` | +| `$now.plus({days: 7})` | Date arithmetic | 7 days from now | +| `$now.minus({hours: 2})` | Subtract time | 2 hours ago | + +```javascript +// Date examples +const tomorrow = $now.plus({days: 1}).toISO(); +const lastWeek = $now.minus({weeks: 1}).toFormat('yyyy-MM-dd'); +const isWeekend = $now.weekday > 5; // 6 = Saturday, 7 = Sunday +``` + +#### Data Querying with JMESPath +| Method | Description | Example | +|--------|-------------|---------| +| `$jmespath(data, query)` | Query JSON structures | `$jmespath(data, 'users[?age > `21`].name')` | + +```javascript +// JMESPath examples +const data = $input.first().json; + +// Filter array +const adults = $jmespath(data, 'users[?age >= `18`]'); + +// Extract specific fields +const names = $jmespath(data, 'users[*].name'); + +// Complex queries +const topScores = $jmespath(data, 'scores | sort_by(@, &value) | reverse(@) | [0:5]'); +``` + +#### Utility Methods +| Method | Description | Example | +|--------|-------------|---------| +| `$getWorkflowStaticData()` | Persistent workflow data | `const counter = $getWorkflowStaticData().counter \|\| 0;` | +| `$evaluateExpression(expr, itemIndex)` | Evaluate n8n expression | `$evaluateExpression('{{ $json.field }}', 0)` | + +### Python Built-in Methods (Beta) + +| Python | JavaScript | Description | +|--------|------------|-------------| +| `_input.all()` | `$input.all()` | Get all items | +| `_input.first()` | `$input.first()` | Get first item | +| `_input.last()` | `$input.last()` | Get last item | +| `_input.item` | `$input.item` | Current item | +| `_items` | `items` | All items array (Native) | +| `_item` | `$item` | Current item (Native) | +| `_now` | `$now` | Current datetime | +| `_today` | `$today` | Today at midnight | +| `_jmespath(data, query)` | `$jmespath()` | Query JSON | + +```python +# Python (Beta) examples +from datetime import timedelta + +# Date operations +tomorrow = _now + timedelta(days=1) +last_week = _now - timedelta(weeks=1) + +# JMESPath querying +data = _input.first()["json"] +adults = _jmespath(data, 'users[?age >= `18`]') +``` + +### Standard JavaScript/Python Objects (No imports needed) + +**JavaScript:** +- `Math` - Math functions: `Math.max()`, `Math.random()`, etc. +- `Date` - Date operations: `new Date()`, `.toISOString()` +- `JSON` - JSON parsing: `JSON.parse()`, `JSON.stringify()` +- `Buffer` - Base64: `Buffer.from(data, 'base64')` +- `console` - Logging: `console.log()`, `console.error()` +- `Object` - Object methods: `Object.keys()`, `Object.entries()` +- `Array` - Array methods: `.map()`, `.filter()`, `.reduce()` + +**Python:** +- `re` - Regular expressions +- `json` - JSON parsing +- `datetime` - Date/time operations +- `statistics` - Statistical functions +- `base64` - Base64 encoding/decoding +- `print()` - Debug logging + +### Common Code Patterns + +**Base64 Encoding/Decoding:** +```javascript +// Decode +const decoded = Buffer.from(encoded, 'base64').toString(); + +// Encode +const encoded = Buffer.from(text).toString('base64'); +``` + +**Date Formatting:** +```javascript +// ISO format +const iso = new Date().toISOString(); + +// Locale string +const local = new Date().toLocaleString('en-US'); + +// Custom format +const parts = new Date().toISOString().split('T'); +const date = parts[0]; // YYYY-MM-DD +``` + +**JSON Operations:** +```javascript +// Parse with default +const data = JSON.parse(jsonString || '{}'); + +// Stringify with formatting +const pretty = JSON.stringify(data, null, 2); + +// Ordered keys +const ordered = {}; +Object.keys(data).sort().forEach(key => { + ordered[key] = data[key]; +}); +``` + +--- + +## 7. Real-World Template Examples + +The following examples are from popular n8n workflow templates (214K+ views): + +### Example 1: Scene Extraction with Error Handling +```javascript +// From: "Generate AI Viral Videos" workflow (214,907 views) +function findSceneEntries(obj) { + const scenes = []; + + for (const [key, value] of Object.entries(obj)) { + if (key.toLowerCase().startsWith("scene") && typeof value === "string") { + scenes.push(value); + } else if (typeof value === "object" && value !== null) { + scenes.push(...findSceneEntries(value)); // Recursive search + } + } + + return scenes; +} + +let output = []; + +try { + const inputData = items[0].json; + const scenes = findSceneEntries(inputData); + + if (scenes.length === 0) { + throw new Error("No scene keys found at any level."); + } + + output = scenes.map(scene => ({ description: scene })); +} catch (e) { + throw new Error("Could not extract scenes properly. Details: " + e.message); +} + +return output; +``` +**Key Techniques:** Recursive object traversal, try-catch error handling, validation + +### Example 2: Array to Object Property Mapping +```javascript +// From: "Generate AI Viral Videos" workflow (214,907 views) +// Collect video URLs from multiple items into single object +return [ + { + video_urls: items.map(item => item.json.video.url) + } +]; +``` +**Key Techniques:** Array mapping, property extraction, single result aggregation + +### Example 3: Binary Data Manipulation +```javascript +// From: "Automate Social Media Content" workflow (205,470 views) +// Rename binary property for downstream processing +$input.first().binary.data = $input.first().binary.Upload_Image__optional_ +delete $input.first().binary.Upload_Image__optional_ +return $input.first() +``` +**Key Techniques:** Binary property manipulation, object mutation, passthrough pattern + +--- + +## 8. Quick Reference Checklist + +Before deploying CODE nodes, verify: + +- [ ] **Code is not empty** - Must have meaningful logic +- [ ] **Return statement exists** - Must return array of objects +- [ ] **Proper return format** - Each item: `{json: {...}}` +- [ ] **Data access correct** - Using `$input.all()`, `$input.first()`, or `$input.item` +- [ ] **No n8n expressions** - Use JavaScript template literals instead: `` `${value}` `` +- [ ] **Error handling** - Guard clauses for null/undefined inputs +- [ ] **Quote escaping** - Properly escape strings in JSONB +- [ ] **Loop logic correct** - Avoid infinite loops, use proper conditions +- [ ] **Performance** - Prefer map/filter over manual loops for small datasets +- [ ] **Output consistent** - All paths return same structure + +--- + +## 9. Additional Resources + +### Official n8n Documentation +- **Code Node Guide:** https://docs.n8n.io/code/code-node/ +- **Code Examples:** https://docs.n8n.io/code/cookbook/code-node/ +- **Built-in Methods Reference:** https://docs.n8n.io/code-examples/methods-variables-reference/ +- **n8n Expressions:** https://docs.n8n.io/code/expressions/ +- **Luxon Date Library:** https://moment.github.io/luxon/ + +### Common Use Cases Quick Reference +- **Data transformation:** See Section 2, Patterns 1, 3, 5 +- **Filtering & ranking:** See Section 2, Patterns 2, 6, 9 +- **Format conversion:** See Section 2, Patterns 4, 7, 8 +- **Python examples:** See Section 2 (Python patterns) +- **Error handling:** See Section 5 (Performance tips, guard clauses) +- **Real-world examples:** See Section 7 (Template examples) + +### When to Use CODE Node vs Other Nodes +| Scenario | Use This | Not CODE Node | +|----------|----------|---------------| +| Simple field mapping | Set node | ✓ Simpler UI | +| Basic filtering | Filter node | ✓ Visual interface | +| Conditional routing | If/Switch node | ✓ Better clarity | +| Complex transformations | **CODE node** | ✗ Too limited | +| Multi-step logic | **CODE node** | ✗ Needs chaining | +| Custom calculations | **CODE node** | ✗ No built-in | +| API response parsing | **CODE node** | ✗ Complex structure | +| Recursive operations | **CODE node** | ✗ Not possible | + +### Related n8n Nodes +- **If/Switch:** Conditional logic (use CODE for complex conditions with multiple criteria) +- **Set:** Simple field mapping (use CODE for transformations requiring logic) +- **Merge:** Combining data (use CODE for custom merge logic with conflict resolution) +- **Split:** Array handling (use CODE for complex filtering and grouping) +- **Function:** Legacy node (CODE node is the modern replacement) +- **Execute Command:** Shell commands (use CODE for JavaScript/Python processing) + +### n8n Community Resources +- **Community Forum:** https://community.n8n.io/c/questions/code-node +- **Workflow Templates:** https://n8n.io/workflows (filter by "Code" node) +- **GitHub Discussions:** https://github.com/n8n-io/n8n/discussions + +--- + +## 10. Summary & Key Takeaways + +### Essential Rules for CODE Node Success + +1. **Choose the Right Mode** + - Use "Run Once for All Items" (default) for 95% of use cases + - Only use "Each Item" mode for independent per-item operations + +2. **Master Data Access Patterns** + - `$input.all()` for batch processing and aggregation (26% usage) + - `$input.first()` for single-item operations (25% usage) + - `$input.item` only in "Each Item" mode (19% usage) + +3. **Always Return Correct Format** + - Single result: `return [{json: {...}}]` + - Multiple results: `return items.map(item => ({json: item}))` + - No results: `return []` + - Never return raw objects, strings, or missing array wrapper + +4. **Use JavaScript Unless You Need Python** + - JavaScript: 95% of use cases, faster, full n8n helpers + - Python: Data science, ML, specific library requirements only + +5. **Implement Error Handling** + - Use guard clauses for null/undefined checks + - Provide fallback values with `.get()` or `||` operator + - Wrap risky operations in try-catch blocks + - Return meaningful error messages + +6. **Optimize for Performance** + - Prefer `.map()`, `.filter()`, `.reduce()` over manual loops + - Filter early, process late + - Pre-compile regex patterns outside loops + - Use early returns to avoid unnecessary processing + +7. **Debug Effectively** + - JavaScript: `console.log()` outputs to browser console + - Python: `print()` statements for debugging + - Test with minimal data first, then scale up + - Validate with n8n's built-in execution viewer + +### Common Pitfalls to Avoid + +❌ **Empty code or missing return statement** (39% of failures) +❌ **Using n8n expression syntax `{{}}` instead of JavaScript template literals** +❌ **Returning raw objects without `[{json: {...}}]` wrapper** +❌ **Accessing properties without null checks** (causes crashes) +❌ **Using wrong mode** (Each Item when All Items would be better) + +### Success Metrics from Real-World Data + +- **47.16% of all n8n workflows** use CODE nodes (15,202 workflows analyzed) +- **4,461 unique users** creating CODE node workflows +- **78% use "All Items" mode** (more efficient for batch operations) +- **39% success rate improvement** when following return format patterns + +### Next Steps + +1. **Start Simple:** Begin with basic transformations using the patterns in Section 2 +2. **Study Examples:** Review the 10 successful patterns and template examples (Sections 2.1-2.10, 7) +3. **Test Incrementally:** Start with 1-2 items, then scale to production data +4. **Use the Checklist:** Follow Section 8 before deploying to production +5. **Learn n8n Helpers:** Master `$input`, `$now`, and `$jmespath` (Section 6) +6. **Join the Community:** Ask questions on the n8n forum for specific use cases + +With these patterns, best practices, and real-world insights, you'll create robust, maintainable CODE nodes that process data efficiently and reliably across your n8n workflows. + +--- + +**Document Metadata:** +- **Based on:** 38,094 CODE node instances from 15,202 workflows +- **Analysis Period:** Last 60 days +- **Data Sources:** n8n telemetry database, workflow templates, official documentation +- **Last Updated:** January 2025 +- **n8n Version:** Supports Code node v2.x (JavaScript, Python Beta, Python Native Beta) + +--- + +**Conceived by Romuald Członkowski** - [www.aiadvisors.pl/en](https://www.aiadvisors.pl/en) diff --git a/skills.png b/skills.png new file mode 100644 index 0000000..887cc69 Binary files /dev/null and b/skills.png differ diff --git a/skills/n8n-mcp-tools-expert/SEARCH_GUIDE.md b/skills/n8n-mcp-tools-expert/SEARCH_GUIDE.md index c789a94..3afbb10 100644 --- a/skills/n8n-mcp-tools-expert/SEARCH_GUIDE.md +++ b/skills/n8n-mcp-tools-expert/SEARCH_GUIDE.md @@ -6,7 +6,7 @@ Complete guide for finding and understanding n8n nodes. ## search_nodes (START HERE!) -**Success Rate**: 99.9% | **Speed**: <20ms +**Speed**: <20ms **Use when**: You know what you're looking for (keyword, service, use case) @@ -15,7 +15,9 @@ Complete guide for finding and understanding n8n nodes. search_nodes({ query: "slack", // Required: search keywords mode: "OR", // Optional: OR (default), AND, FUZZY - limit: 20 // Optional: max results (default 20, max 100) + limit: 20, // Optional: max results (default 20) + source: "all", // Optional: all, core, community, verified + includeExamples: false // Optional: include template configs }) ``` @@ -38,24 +40,38 @@ search_nodes({ **Tips**: - Common searches: webhook, http, database, email, slack, google, ai -- OR mode (default): matches any word -- AND mode: requires all words -- FUZZY mode: typo-tolerant (finds "slak" → Slack) +- `OR` mode (default): matches any word +- `AND` mode: requires all words +- `FUZZY` mode: typo-tolerant (finds "slak" → Slack) +- Use `source: "core"` for only built-in nodes +- Use `includeExamples: true` for real-world configs --- -## get_node_essentials (RECOMMENDED!) +## get_node (UNIFIED NODE INFORMATION) -**Success Rate**: 91.7% | **Speed**: <10ms | **Size**: ~5KB +The `get_node` tool provides all node information with different detail levels and modes. + +### Detail Levels (mode="info") + +| Detail | Tokens | Use When | +|--------|--------|----------| +| `minimal` | ~200 | Quick metadata check | +| `standard` | ~1-2K | **Most use cases (DEFAULT)** | +| `full` | ~3-8K | Complex debugging only | + +### Standard Detail (RECOMMENDED) + +**Speed**: <10ms | **Size**: ~1-2K tokens **Use when**: You've found the node and need configuration details -**Syntax**: ```javascript -get_node_essentials({ +get_node({ nodeType: "nodes-base.slack", // Required: SHORT prefix format includeExamples: true // Optional: get real template configs }) +// detail="standard" is the default ``` **Returns**: @@ -64,105 +80,161 @@ get_node_essentials({ - Metadata (isAITool, isTrigger, hasCredentials) - Real examples from templates (if includeExamples: true) -**Why use this**: -- 5KB vs 100KB+ (get_node_info) -- 91.7% success vs 80% -- <10ms vs slower -- Focused data (no information overload) +### Minimal Detail ---- +**Speed**: <5ms | **Size**: ~200 tokens -## get_node_info (USE SPARINGLY!) +**Use when**: Just need basic metadata -**Success Rate**: 80% ⚠️ | **Size**: 100KB+ - -**Use when**: -- Debugging complex configuration -- Need complete property schema -- Exploring advanced features - -**Syntax**: ```javascript -get_node_info({ - nodeType: "nodes-base.httpRequest" +get_node({ + nodeType: "nodes-base.slack", + detail: "minimal" }) ``` -**Warning**: 20% failure rate! Use get_node_essentials instead for most cases. +**Returns**: nodeType, displayName, description, category -**Better alternatives**: -1. get_node_essentials - operations list -2. get_node_documentation - readable docs -3. search_node_properties - specific property +### Full Detail (USE SPARINGLY) ---- +**Speed**: <100ms | **Size**: ~3-8K tokens -## list_nodes (BROWSE BY CATEGORY) +**Use when**: Debugging complex configuration, need complete schema -**Success Rate**: 99.6% | **Speed**: <20ms - -**Use when**: Exploring by category or listing all nodes - -**Syntax**: ```javascript -list_nodes({ - category: "trigger", // Optional: filter by category - package: "n8n-nodes-base", // Optional: filter by package - limit: 200 // Optional: default 50 -}) -``` - -**Categories**: -- `trigger` - Webhook, Schedule, Manual, etc. (108 total) -- `transform` - Code, Set, Function, etc. -- `output` - HTTP Request, Email, Slack, etc. -- `input` - Read data sources -- `AI` - AI-capable nodes (270 total) - -**Packages**: -- `n8n-nodes-base` - Core nodes (437 total) -- `@n8n/n8n-nodes-langchain` - AI nodes (100 total) - ---- - -## search_node_properties (FIND SPECIFIC FIELDS) - -**Use when**: Looking for specific property in a node - -**Syntax**: -```javascript -search_node_properties({ +get_node({ nodeType: "nodes-base.httpRequest", - query: "auth" // Find authentication properties + detail: "full" }) ``` -**Returns**: Property paths and descriptions matching query - -**Common searches**: auth, header, body, json, url, method +**Warning**: Large payload! Use `standard` for most cases. --- -## get_node_documentation (READABLE DOCS) +## get_node Modes -**Coverage**: 88% of nodes (470/537) +### mode="docs" (READABLE DOCUMENTATION) **Use when**: Need human-readable documentation with examples -**Syntax**: ```javascript -get_node_documentation({ - nodeType: "nodes-base.slack" +get_node({ + nodeType: "nodes-base.slack", + mode: "docs" }) ``` -**Returns**: Formatted docs with: +**Returns**: Formatted markdown with: - Usage examples - Authentication guide - Common patterns - Best practices -**Note**: Better than raw schema for learning! +**Better than raw schema for learning!** + +### mode="search_properties" (FIND SPECIFIC FIELDS) + +**Use when**: Looking for specific property in a node + +```javascript +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "auth", // Required for this mode + maxPropertyResults: 20 // Optional: default 20 +}) +``` + +**Returns**: Property paths and descriptions matching query + +**Common searches**: auth, header, body, json, url, method, credential + +### mode="versions" (VERSION HISTORY) + +**Use when**: Need to check node version history + +```javascript +get_node({ + nodeType: "nodes-base.executeWorkflow", + mode: "versions" +}) +``` + +**Returns**: Version history with breaking changes flags + +### mode="compare" (COMPARE VERSIONS) + +**Use when**: Need to see differences between versions + +```javascript +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "compare", + fromVersion: "3.0", + toVersion: "4.1" // Optional: defaults to latest +}) +``` + +**Returns**: Property-level changes between versions + +### mode="breaking" (BREAKING CHANGES ONLY) + +**Use when**: Checking for breaking changes before upgrades + +```javascript +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "breaking", + fromVersion: "3.0" +}) +``` + +**Returns**: Only breaking changes (not all changes) + +### mode="migrations" (AUTO-MIGRATABLE) + +**Use when**: Checking what can be auto-migrated + +```javascript +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "migrations", + fromVersion: "3.0" +}) +``` + +**Returns**: Changes that can be automatically migrated + +--- + +## Additional Parameters + +### includeTypeInfo + +Add type structure metadata (validation rules, JS types) + +```javascript +get_node({ + nodeType: "nodes-base.if", + includeTypeInfo: true // Adds ~80-120 tokens per property +}) +``` + +Use for complex nodes like filter, resourceMapper + +### includeExamples + +Include real-world configuration examples from templates + +```javascript +get_node({ + nodeType: "nodes-base.slack", + includeExamples: true // Adds ~200-400 tokens per example +}) +``` + +Only works with `mode: "info"` and `detail: "standard"` --- @@ -174,14 +246,14 @@ search_nodes({query: "slack"}) → Returns: nodes-base.slack Step 2: Get Operations (18s avg thinking time) -get_node_essentials({ +get_node({ nodeType: "nodes-base.slack", includeExamples: true }) → Returns: operations list + example configs Step 3: Validate Config -validate_node_operation({ +validate_node({ nodeType: "nodes-base.slack", config: {resource: "channel", operation: "create"}, profile: "runtime" @@ -192,21 +264,23 @@ Step 4: Use in Workflow (Configuration ready!) ``` -**Most common pattern**: search → essentials (18s average) +**Most common pattern**: search → get_node (18s average) --- ## Quick Comparison -| Tool | When to Use | Success | Speed | Size | -|------|-------------|---------|-------|------| -| search_nodes | Find by keyword | 99.9% | <20ms | Small | -| get_node_essentials | Get config | 91.7% | <10ms | 5KB | -| get_node_info | Full schema | 80% ⚠️ | Slow | 100KB+ | -| list_nodes | Browse category | 99.6% | <20ms | Small | -| get_node_documentation | Learn usage | N/A | Fast | Medium | +| Tool/Mode | When to Use | Speed | Size | +|-----------|-------------|-------|------| +| `search_nodes` | Find by keyword | <20ms | Small | +| `get_node (standard)` | **Get config (DEFAULT)** | <10ms | 1-2K | +| `get_node (minimal)` | Quick metadata | <5ms | 200 | +| `get_node (full)` | Complex debugging | <100ms | 3-8K | +| `get_node (docs)` | Learn usage | Fast | Medium | +| `get_node (search_properties)` | Find specific field | Fast | Small | +| `get_node (versions)` | Check versions | Fast | Small | -**Best Practice**: search → essentials → validate +**Best Practice**: search → get_node(standard) → validate --- @@ -229,13 +303,71 @@ Step 4: Use in Workflow **Conversion**: search_nodes returns BOTH formats: ```javascript { - "nodeType": "nodes-base.slack", // Use with essentials - "workflowNodeType": "n8n-nodes-base.slack" // Use with create_workflow + "nodeType": "nodes-base.slack", // Use with get_node, validate_node + "workflowNodeType": "n8n-nodes-base.slack" // Use with n8n_create_workflow } ``` --- +## Examples + +### Find and Configure HTTP Request + +```javascript +// Step 1: Search +search_nodes({query: "http request"}) + +// Step 2: Get standard info +get_node({nodeType: "nodes-base.httpRequest"}) + +// Step 3: Find auth options +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "authentication" +}) + +// Step 4: Validate config +validate_node({ + nodeType: "nodes-base.httpRequest", + config: {method: "POST", url: "https://api.example.com"}, + profile: "runtime" +}) +``` + +### Explore AI Nodes + +```javascript +// Find all AI-related nodes +search_nodes({query: "ai agent", source: "all"}) + +// Get AI Agent documentation +get_node({nodeType: "nodes-langchain.agent", mode: "docs"}) + +// Get configuration details with examples +get_node({ + nodeType: "nodes-langchain.agent", + includeExamples: true +}) +``` + +### Check Version Compatibility + +```javascript +// See all versions +get_node({nodeType: "nodes-base.executeWorkflow", mode: "versions"}) + +// Check breaking changes from v1 to v2 +get_node({ + nodeType: "nodes-base.executeWorkflow", + mode: "breaking", + fromVersion: "1.0" +}) +``` + +--- + ## Related - [VALIDATION_GUIDE.md](VALIDATION_GUIDE.md) - Validate node configs diff --git a/skills/n8n-mcp-tools-expert/SKILL.md b/skills/n8n-mcp-tools-expert/SKILL.md index 37f7c42..090a877 100644 --- a/skills/n8n-mcp-tools-expert/SKILL.md +++ b/skills/n8n-mcp-tools-expert/SKILL.md @@ -11,13 +11,13 @@ Master guide for using n8n-mcp MCP server tools to build workflows. ## Tool Categories -n8n-mcp provides **40+ tools** organized into categories: +n8n-mcp provides tools organized into categories: 1. **Node Discovery** → [SEARCH_GUIDE.md](SEARCH_GUIDE.md) 2. **Configuration Validation** → [VALIDATION_GUIDE.md](VALIDATION_GUIDE.md) 3. **Workflow Management** → [WORKFLOW_GUIDE.md](WORKFLOW_GUIDE.md) -4. **Template Library** - Search and access 2,653 real workflows -5. **Documentation** - Get tool and node documentation +4. **Template Library** - Search and deploy 2,700+ real workflows +5. **Documentation & Guides** - Tool docs, AI agent guide, Code node guides --- @@ -25,14 +25,15 @@ n8n-mcp provides **40+ tools** organized into categories: ### Most Used Tools (by success rate) -| Tool | Use When | Success Rate | Speed | -|------|----------|--------------|-------| -| `search_nodes` | Finding nodes by keyword | 99.9% | <20ms | -| `get_node_essentials` | Understanding node operations | 91.7% | <10ms | -| `validate_node_operation` | Checking configurations | Varies | <100ms | -| `n8n_create_workflow` | Creating workflows | 96.8% | 100-500ms | -| `n8n_update_partial_workflow` | Editing workflows (MOST USED!) | 99.0% | 50-200ms | -| `validate_workflow` | Checking complete workflow | 95.5% | 100-500ms | +| Tool | Use When | Speed | +|------|----------|-------| +| `search_nodes` | Finding nodes by keyword | <20ms | +| `get_node` | Understanding node operations (detail="standard") | <10ms | +| `validate_node` | Checking configurations (mode="full") | <100ms | +| `n8n_create_workflow` | Creating workflows | 100-500ms | +| `n8n_update_partial_workflow` | Editing workflows (MOST USED!) | 50-200ms | +| `validate_workflow` | Checking complete workflow | 100-500ms | +| `n8n_deploy_template` | Deploy template to n8n instance | 200-500ms | --- @@ -43,8 +44,8 @@ n8n-mcp provides **40+ tools** organized into categories: **Workflow**: ``` 1. search_nodes({query: "keyword"}) -2. get_node_essentials({nodeType: "nodes-base.name"}) -3. [Optional] get_node_documentation({nodeType: "nodes-base.name"}) +2. get_node({nodeType: "nodes-base.name"}) +3. [Optional] get_node({nodeType: "nodes-base.name", mode: "docs"}) ``` **Example**: @@ -53,19 +54,23 @@ n8n-mcp provides **40+ tools** organized into categories: search_nodes({query: "slack"}) // Returns: nodes-base.slack -// Step 2: Get details (18s avg between steps) -get_node_essentials({nodeType: "nodes-base.slack"}) -// Returns: operations, properties, examples +// Step 2: Get details +get_node({nodeType: "nodes-base.slack"}) +// Returns: operations, properties, examples (standard detail) + +// Step 3: Get readable documentation +get_node({nodeType: "nodes-base.slack", mode: "docs"}) +// Returns: markdown documentation ``` -**Common pattern**: search → essentials (18s average) +**Common pattern**: search → get_node (18s average) ### Validating Configuration **Workflow**: ``` -1. validate_node_minimal({nodeType, config: {}}) - Check required fields -2. validate_node_operation({nodeType, config, profile: "runtime"}) - Full validation +1. validate_node({nodeType, config: {}, mode: "minimal"}) - Check required fields +2. validate_node({nodeType, config, profile: "runtime"}) - Full validation 3. [Repeat] Fix errors, validate again ``` @@ -79,6 +84,7 @@ get_node_essentials({nodeType: "nodes-base.slack"}) 2. n8n_validate_workflow({id}) 3. n8n_update_partial_workflow({id, operations: [...]}) 4. n8n_validate_workflow({id}) again +5. n8n_update_partial_workflow({id, operations: [{type: "activateWorkflow"}]}) ``` **Common pattern**: iterative updates (56s average between edits) @@ -100,11 +106,9 @@ get_node_essentials({nodeType: "nodes-base.slack"}) **Tools that use this**: - search_nodes (returns this format) -- get_node_essentials -- get_node_info -- validate_node_minimal -- validate_node_operation -- get_property_dependencies +- get_node +- validate_node +- validate_workflow ### Format 2: Workflow Tools ```javascript @@ -118,7 +122,6 @@ get_node_essentials({nodeType: "nodes-base.slack"}) **Tools that use this**: - n8n_create_workflow - n8n_update_partial_workflow -- list_node_templates ### Conversion @@ -134,40 +137,43 @@ get_node_essentials({nodeType: "nodes-base.slack"}) ## Common Mistakes -### ❌ Mistake 1: Wrong nodeType Format +### Mistake 1: Wrong nodeType Format **Problem**: "Node not found" error ```javascript -❌ get_node_essentials({nodeType: "slack"}) // Missing prefix -❌ get_node_essentials({nodeType: "n8n-nodes-base.slack"}) // Wrong prefix +// WRONG +get_node({nodeType: "slack"}) // Missing prefix +get_node({nodeType: "n8n-nodes-base.slack"}) // Wrong prefix -✅ get_node_essentials({nodeType: "nodes-base.slack"}) // Correct! +// CORRECT +get_node({nodeType: "nodes-base.slack"}) ``` -### ❌ Mistake 2: Using get_node_info Instead of get_node_essentials +### Mistake 2: Using detail="full" by Default -**Problem**: 20% failure rate, slow response, huge payload +**Problem**: Huge payload, slower response, token waste ```javascript -❌ get_node_info({nodeType: "nodes-base.slack"}) -// Returns: 100KB+ data, 20% chance of failure +// WRONG - Returns 3-8K tokens, use sparingly +get_node({nodeType: "nodes-base.slack", detail: "full"}) -✅ get_node_essentials({nodeType: "nodes-base.slack"}) -// Returns: 5KB focused data, 91.7% success, <10ms +// CORRECT - Returns 1-2K tokens, covers 95% of use cases +get_node({nodeType: "nodes-base.slack"}) // detail="standard" is default +get_node({nodeType: "nodes-base.slack", detail: "standard"}) ``` -**When to use get_node_info**: +**When to use detail="full"**: - Debugging complex configuration issues -- Need complete property schema +- Need complete property schema with all nested options - Exploring advanced features **Better alternatives**: -1. get_node_essentials - for operations list -2. get_node_documentation - for readable docs -3. search_node_properties - for specific property +1. `get_node({detail: "standard"})` - for operations list (default) +2. `get_node({mode: "docs"})` - for readable documentation +3. `get_node({mode: "search_properties", propertyQuery: "auth"})` - for specific property -### ❌ Mistake 3: Not Using Validation Profiles +### Mistake 3: Not Using Validation Profiles **Problem**: Too many false positives OR missing real errors @@ -178,12 +184,14 @@ get_node_essentials({nodeType: "nodes-base.slack"}) - `strict` - Maximum validation (for production) ```javascript -❌ validate_node_operation({nodeType, config}) // Uses default +// WRONG - Uses default profile +validate_node({nodeType, config}) -✅ validate_node_operation({nodeType, config, profile: "runtime"}) // Explicit +// CORRECT - Explicit profile +validate_node({nodeType, config, profile: "runtime"}) ``` -### ❌ Mistake 4: Ignoring Auto-Sanitization +### Mistake 4: Ignoring Auto-Sanitization **What happens**: ALL nodes sanitized on ANY workflow update @@ -203,7 +211,7 @@ n8n_update_partial_workflow({id, operations: [...]}) // → Automatically fixes operator structures ``` -### ❌ Mistake 5: Not Using Smart Parameters +### Mistake 5: Not Using Smart Parameters **Problem**: Complex sourceIndex calculations for multi-output nodes @@ -244,6 +252,25 @@ n8n_update_partial_workflow({id, operations: [...]}) } ``` +### Mistake 6: Not Using intent Parameter + +**Problem**: Less helpful tool responses + +```javascript +// WRONG - No context for response +n8n_update_partial_workflow({ + id: "abc", + operations: [{type: "addNode", node: {...}}] +}) + +// CORRECT - Better AI responses +n8n_update_partial_workflow({ + id: "abc", + intent: "Add error handling for API failures", + operations: [{type: "addNode", node: {...}}] +}) +``` + --- ## Tool Usage Patterns @@ -262,7 +289,7 @@ const results = await search_nodes({ // → Returns: nodes-base.slack, nodes-base.slackTrigger // Step 2: Get details (~18s later, user reviewing results) -const details = await get_node_essentials({ +const details = await get_node({ nodeType: "nodes-base.slack", includeExamples: true // Get real template configs }); @@ -275,7 +302,7 @@ const details = await get_node_essentials({ ```javascript // Step 1: Validate -const result = await validate_node_operation({ +const result = await validate_node({ nodeType: "nodes-base.slack", config: { resource: "channel", @@ -293,7 +320,7 @@ if (!result.valid) { config.name = "general"; // Step 4: Validate again -await validate_node_operation({...}); // Repeat until clean +await validate_node({...}); // Repeat until clean ``` ### Pattern 3: Workflow Editing @@ -305,6 +332,7 @@ await validate_node_operation({...}); // Repeat until clean // Edit 1 await n8n_update_partial_workflow({ id: "workflow-id", + intent: "Add webhook trigger", operations: [{type: "addNode", node: {...}}] }); @@ -313,6 +341,7 @@ await n8n_update_partial_workflow({ // Edit 2 await n8n_update_partial_workflow({ id: "workflow-id", + intent: "Connect webhook to processor", operations: [{type: "addConnection", source: "...", target: "..."}] }); @@ -320,6 +349,13 @@ await n8n_update_partial_workflow({ // Edit 3 (validation) await n8n_validate_workflow({id: "workflow-id"}); + +// Ready? Activate! +await n8n_update_partial_workflow({ + id: "workflow-id", + intent: "Activate workflow for production", + operations: [{type: "activateWorkflow"}] +}); ``` --- @@ -328,15 +364,14 @@ await n8n_validate_workflow({id: "workflow-id"}); ### Node Discovery Tools See [SEARCH_GUIDE.md](SEARCH_GUIDE.md) for: -- search_nodes (99.9% success) -- get_node_essentials vs get_node_info -- list_nodes by category -- search_node_properties for specific fields +- search_nodes +- get_node with detail levels (minimal, standard, full) +- get_node modes (info, docs, search_properties, versions) ### Validation Tools See [VALIDATION_GUIDE.md](VALIDATION_GUIDE.md) for: - Validation profiles explained -- validate_node_minimal vs validate_node_operation +- validate_node with modes (minimal, full) - validate_workflow complete structure - Auto-sanitization system - Handling validation errors @@ -344,10 +379,12 @@ See [VALIDATION_GUIDE.md](VALIDATION_GUIDE.md) for: ### Workflow Management See [WORKFLOW_GUIDE.md](WORKFLOW_GUIDE.md) for: - n8n_create_workflow -- n8n_update_partial_workflow (15 operation types!) +- n8n_update_partial_workflow (17 operation types!) - Smart parameters (branch, case) - AI connection types (8 types) -- cleanStaleConnections recovery +- Workflow activation (activateWorkflow/deactivateWorkflow) +- n8n_deploy_template +- n8n_workflow_versions --- @@ -356,28 +393,58 @@ See [WORKFLOW_GUIDE.md](WORKFLOW_GUIDE.md) for: ### Search Templates ```javascript -// Search by keyword +// Search by keyword (default mode) search_templates({ query: "webhook slack", limit: 20 }); -// → Returns: 1,085 templates with metadata -// Get template details -get_template({ - templateId: 2947, // Weather to Slack - mode: "structure" // or "full" for complete JSON +// Search by node types +search_templates({ + searchMode: "by_nodes", + nodeTypes: ["n8n-nodes-base.httpRequest", "n8n-nodes-base.slack"] +}); + +// Search by task type +search_templates({ + searchMode: "by_task", + task: "webhook_processing" +}); + +// Search by metadata (complexity, setup time) +search_templates({ + searchMode: "by_metadata", + complexity: "simple", + maxSetupMinutes: 15 }); ``` -### Template Metadata +### Get Template Details -Templates include: -- Complexity (simple, medium, complex) -- Setup time estimate -- Required services -- Categories and use cases -- View counts (popularity) +```javascript +get_template({ + templateId: 2947, + mode: "structure" // nodes+connections only +}); + +get_template({ + templateId: 2947, + mode: "full" // complete workflow JSON +}); +``` + +### Deploy Template Directly + +```javascript +// Deploy template to your n8n instance +n8n_deploy_template({ + templateId: 2947, + name: "My Weather to Slack", // Custom name (optional) + autoFix: true, // Auto-fix common issues (default) + autoUpgradeVersions: true // Upgrade node versions (default) +}); +// Returns: workflow ID, required credentials, fixes applied +``` --- @@ -386,7 +453,7 @@ Templates include: ### Get Tool Documentation ```javascript -// List all tools +// Overview of all tools tools_documentation() // Specific tool details @@ -394,21 +461,29 @@ tools_documentation({ topic: "search_nodes", depth: "full" }) + +// Code node guides +tools_documentation({topic: "javascript_code_node_guide", depth: "full"}) +tools_documentation({topic: "python_code_node_guide", depth: "full"}) +``` + +### AI Agent Guide + +```javascript +// Comprehensive AI workflow guide +ai_agents_guide() +// Returns: Architecture, connections, tools, validation, best practices ``` ### Health Check ```javascript -// Verify MCP server connectivity +// Quick health check n8n_health_check() -// → Returns: status, features, API availability, version -``` -### Database Statistics - -```javascript -get_database_statistics() -// → Returns: 537 nodes, 270 AI tools, 2,653 templates +// Detailed diagnostics +n8n_health_check({mode: "diagnostic"}) +// → Returns: status, env vars, tool status, API connectivity ``` --- @@ -416,79 +491,140 @@ get_database_statistics() ## Tool Availability **Always Available** (no n8n API needed): -- search_nodes, list_nodes, get_node_essentials ✅ -- validate_node_minimal, validate_node_operation ✅ -- validate_workflow, get_property_dependencies ✅ -- search_templates, get_template, list_tasks ✅ -- tools_documentation, get_database_statistics ✅ +- search_nodes, get_node +- validate_node, validate_workflow +- search_templates, get_template +- tools_documentation, ai_agents_guide **Requires n8n API** (N8N_API_URL + N8N_API_KEY): -- n8n_create_workflow ⚠️ -- n8n_update_partial_workflow ⚠️ -- n8n_validate_workflow (by ID) ⚠️ -- n8n_list_workflows, n8n_get_workflow ⚠️ -- n8n_trigger_webhook_workflow ⚠️ +- n8n_create_workflow +- n8n_update_partial_workflow +- n8n_validate_workflow (by ID) +- n8n_list_workflows, n8n_get_workflow +- n8n_test_workflow +- n8n_executions +- n8n_deploy_template +- n8n_workflow_versions +- n8n_autofix_workflow If API tools unavailable, use templates and validation-only workflows. --- +## Unified Tool Reference + +### get_node (Unified Node Information) + +**Detail Levels** (mode="info", default): +- `minimal` (~200 tokens) - Basic metadata only +- `standard` (~1-2K tokens) - Essential properties + operations (RECOMMENDED) +- `full` (~3-8K tokens) - Complete schema (use sparingly) + +**Operation Modes**: +- `info` (default) - Node schema with detail level +- `docs` - Readable markdown documentation +- `search_properties` - Find specific properties (use with propertyQuery) +- `versions` - List all versions with breaking changes +- `compare` - Compare two versions +- `breaking` - Show only breaking changes +- `migrations` - Show auto-migratable changes + +```javascript +// Standard (recommended) +get_node({nodeType: "nodes-base.httpRequest"}) + +// Get documentation +get_node({nodeType: "nodes-base.webhook", mode: "docs"}) + +// Search for properties +get_node({nodeType: "nodes-base.httpRequest", mode: "search_properties", propertyQuery: "auth"}) + +// Check versions +get_node({nodeType: "nodes-base.executeWorkflow", mode: "versions"}) +``` + +### validate_node (Unified Validation) + +**Modes**: +- `full` (default) - Comprehensive validation with errors/warnings/suggestions +- `minimal` - Quick required fields check only + +**Profiles** (for mode="full"): +- `minimal` - Very lenient +- `runtime` - Standard (default, recommended) +- `ai-friendly` - Balanced for AI workflows +- `strict` - Most thorough (production) + +```javascript +// Full validation with runtime profile +validate_node({nodeType: "nodes-base.slack", config: {...}, profile: "runtime"}) + +// Quick required fields check +validate_node({nodeType: "nodes-base.webhook", config: {}, mode: "minimal"}) +``` + +--- + ## Performance Characteristics -| Tool | Response Time | Payload Size | Reliability | -|------|---------------|--------------|-------------| -| search_nodes | <20ms | Small | 99.9% | -| list_nodes | <20ms | Small | 99.6% | -| get_node_essentials | <10ms | ~5KB | 91.7% | -| get_node_info | Varies | 100KB+ | 80% ⚠️ | -| validate_node_minimal | <100ms | Small | 97.4% | -| validate_node_operation | <100ms | Medium | Varies | -| validate_workflow | 100-500ms | Medium | 95.5% | -| n8n_create_workflow | 100-500ms | Medium | 96.8% | -| n8n_update_partial_workflow | 50-200ms | Small | 99.0% | +| Tool | Response Time | Payload Size | +|------|---------------|--------------| +| search_nodes | <20ms | Small | +| get_node (standard) | <10ms | ~1-2KB | +| get_node (full) | <100ms | 3-8KB | +| validate_node (minimal) | <50ms | Small | +| validate_node (full) | <100ms | Medium | +| validate_workflow | 100-500ms | Medium | +| n8n_create_workflow | 100-500ms | Medium | +| n8n_update_partial_workflow | 50-200ms | Small | +| n8n_deploy_template | 200-500ms | Medium | --- ## Best Practices -### ✅ Do - -- Use get_node_essentials over get_node_info (91.7% vs 80%) -- Specify validation profile explicitly -- Use smart parameters (branch, case) for clarity -- Follow search → essentials → validate workflow +### Do +- Use `get_node({detail: "standard"})` for most use cases +- Specify validation profile explicitly (`profile: "runtime"`) +- Use smart parameters (`branch`, `case`) for clarity +- Include `intent` parameter in workflow updates +- Follow search → get_node → validate workflow - Iterate workflows (avg 56s between edits) - Validate after every significant change -- Use includeExamples: true for real configs +- Use `includeExamples: true` for real configs +- Use `n8n_deploy_template` for quick starts -### ❌ Don't - -- Use get_node_info unless necessary (20% failure rate!) -- Forget nodeType prefix (nodes-base.*) -- Skip validation profiles (use "runtime") +### Don't +- Use `detail: "full"` unless necessary (wastes tokens) +- Forget nodeType prefix (`nodes-base.*`) +- Skip validation profiles - Try to build workflows in one shot (iterate!) - Ignore auto-sanitization behavior -- Use full prefix (n8n-nodes-base.*) with search tools +- Use full prefix (`n8n-nodes-base.*`) with search/validate tools +- Forget to activate workflows after building --- ## Summary **Most Important**: -1. Use **get_node_essentials**, not get_node_info (5KB vs 100KB, 91.7% vs 80%) -2. nodeType formats differ: `nodes-base.*` (search) vs `n8n-nodes-base.*` (workflows) -3. Specify **validation profiles** (runtime recommended) -4. Use **smart parameters** (branch="true", case=0) -5. **Auto-sanitization** runs on ALL nodes during updates -6. Workflows are built **iteratively** (56s avg between edits) +1. Use **get_node** with `detail: "standard"` (default) - covers 95% of use cases +2. nodeType formats differ: `nodes-base.*` (search/validate) vs `n8n-nodes-base.*` (workflows) +3. Specify **validation profiles** (`runtime` recommended) +4. Use **smart parameters** (`branch="true"`, `case=0`) +5. Include **intent parameter** in workflow updates +6. **Auto-sanitization** runs on ALL nodes during updates +7. Workflows can be **activated via API** (`activateWorkflow` operation) +8. Workflows are built **iteratively** (56s avg between edits) **Common Workflow**: 1. search_nodes → find node -2. get_node_essentials → understand config -3. validate_node_operation → check config +2. get_node → understand config +3. validate_node → check config 4. n8n_create_workflow → build 5. n8n_validate_workflow → verify 6. n8n_update_partial_workflow → iterate +7. activateWorkflow → go live! For details, see: - [SEARCH_GUIDE.md](SEARCH_GUIDE.md) - Node discovery @@ -502,3 +638,5 @@ For details, see: - n8n Workflow Patterns - Architectural patterns from templates - n8n Validation Expert - Interpret validation errors - n8n Node Configuration - Operation-specific requirements +- n8n Code JavaScript - Write JavaScript in Code nodes +- n8n Code Python - Write Python in Code nodes diff --git a/skills/n8n-mcp-tools-expert/VALIDATION_GUIDE.md b/skills/n8n-mcp-tools-expert/VALIDATION_GUIDE.md index 925d34d..127cfe0 100644 --- a/skills/n8n-mcp-tools-expert/VALIDATION_GUIDE.md +++ b/skills/n8n-mcp-tools-expert/VALIDATION_GUIDE.md @@ -12,17 +12,21 @@ Validation is typically iterative with validate → fix cycles --- -## validate_node_minimal (QUICK CHECK) +## validate_node (UNIFIED VALIDATION) -**Success Rate**: 97.4% | **Speed**: <100ms +The `validate_node` tool provides all validation capabilities with different modes. + +### Quick Check (mode="minimal") + +**Speed**: <50ms **Use when**: Checking what fields are required -**Syntax**: ```javascript -validate_node_minimal({ +validate_node({ nodeType: "nodes-base.slack", - config: {} // Empty to see all required fields + config: {}, // Empty to see all required fields + mode: "minimal" }) ``` @@ -36,17 +40,14 @@ validate_node_minimal({ **When to use**: Planning configuration, seeing basic requirements ---- +### Full Validation (mode="full", DEFAULT) -## validate_node_operation (FULL VALIDATION) - -**Success Rate**: Varies | **Speed**: <100ms +**Speed**: <100ms **Use when**: Validating actual configuration before deployment -**Syntax**: ```javascript -validate_node_operation({ +validate_node({ nodeType: "nodes-base.slack", config: { resource: "channel", @@ -55,9 +56,12 @@ validate_node_operation({ }, profile: "runtime" // Recommended! }) +// mode="full" is the default ``` -### Validation Profiles +--- + +## Validation Profiles Choose based on your stage: @@ -81,10 +85,15 @@ Choose based on your stage: - May have false positives - Use: Production deployment -### Returns +--- + +## Validation Response ```javascript { + "nodeType": "nodes-base.slack", + "workflowNodeType": "n8n-nodes-base.slack", + "displayName": "Slack", "valid": false, "errors": [ { @@ -106,7 +115,8 @@ Choose based on your stage: "summary": { "hasErrors": true, "errorCount": 1, - "warningCount": 1 + "warningCount": 1, + "suggestionCount": 0 } } ``` @@ -123,7 +133,7 @@ Choose based on your stage: ## validate_workflow (STRUCTURE VALIDATION) -**Success Rate**: 95.5% | **Speed**: 100-500ms +**Speed**: 100-500ms **Use when**: Checking complete workflow before execution @@ -152,6 +162,21 @@ validate_workflow({ **Returns**: Comprehensive validation report with errors, warnings, suggestions +### Validate by Workflow ID + +```javascript +// Validate workflow already in n8n +n8n_validate_workflow({ + id: "workflow-id", + options: { + validateNodes: true, + validateConnections: true, + validateExpressions: true, + profile: "runtime" + } +}) +``` + --- ## Validation Loop Pattern @@ -161,11 +186,11 @@ validate_workflow({ ``` 1. Configure node ↓ -2. validate_node_operation (23s thinking about errors) +2. validate_node (23s thinking about errors) ↓ 3. Fix errors ↓ -4. validate_node_operation again (58s fixing) +4. validate_node again (58s fixing) ↓ 5. Repeat until valid ``` @@ -178,7 +203,7 @@ let config = { operation: "create" }; -const result1 = validate_node_operation({ +const result1 = validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" @@ -188,7 +213,7 @@ const result1 = validate_node_operation({ // Iteration 2 (~58s later) config.name = "general"; -const result2 = validate_node_operation({ +const result2 = validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" @@ -220,7 +245,7 @@ const result2 = validate_node_operation({ { "type": "boolean", "operation": "equals", - "singleValue": true // ❌ Binary operators shouldn't have this + "singleValue": true // Binary operators shouldn't have this } // After auto-sanitization (automatic!) @@ -233,7 +258,36 @@ const result2 = validate_node_operation({ **Recovery tools**: - `cleanStaleConnections` operation - removes broken connections -- `n8n_autofix_workflow` - preview/apply fixes +- `n8n_autofix_workflow({id})` - preview/apply fixes + +--- + +## n8n_autofix_workflow (AUTO-FIX TOOL) + +**Use when**: Validation errors need automatic fixes + +```javascript +// Preview fixes (default - doesn't apply) +n8n_autofix_workflow({ + id: "workflow-id", + applyFixes: false, // Preview mode + confidenceThreshold: "medium" // high, medium, low +}) + +// Apply fixes +n8n_autofix_workflow({ + id: "workflow-id", + applyFixes: true +}) +``` + +**Fix Types**: +- `expression-format` - Fix expression syntax +- `typeversion-correction` - Correct typeVersion +- `error-output-config` - Fix error output settings +- `webhook-missing-path` - Add missing webhook paths +- `typeversion-upgrade` - Upgrade to latest version +- `version-migration` - Apply version migrations --- @@ -270,7 +324,7 @@ const result2 = validate_node_operation({ → Add the field with appropriate value **"Invalid value"** -→ Check allowed values in essentials/documentation +→ Check allowed values in get_node output **"Type mismatch"** → Convert to correct type (string/number/boolean) @@ -294,17 +348,18 @@ Use **ai-friendly** profile to reduce false positives. ## Best Practices -### ✅ Do +### Do - Use **runtime** profile for pre-deployment - Validate after every configuration change - Fix errors immediately (avg 58s) - Iterate validation loop - Trust auto-sanitization for operator issues -- Use minimal profile for quick checks -- Complete workflow activation manually in n8n UI (API/MCP cannot activate workflows) +- Use `mode: "minimal"` for quick checks +- Use `n8n_autofix_workflow` for bulk fixes +- Activate workflows via API when ready (`activateWorkflow` operation) -### ❌ Don't +### Don't - Skip validation before deployment - Ignore error messages @@ -317,10 +372,11 @@ Use **ai-friendly** profile to reduce false positives. ## Example: Complete Validation Workflow ```javascript -// Step 1: Get node requirements -validate_node_minimal({ +// Step 1: Get node requirements (quick check) +validate_node({ nodeType: "nodes-base.slack", - config: {} + config: {}, + mode: "minimal" }); // → Know what's required @@ -332,8 +388,8 @@ const config = { text: "Hello!" }; -// Step 3: Validate configuration -const result = validate_node_operation({ +// Step 3: Validate configuration (full validation) +const result = validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" @@ -341,9 +397,9 @@ const result = validate_node_operation({ // Step 4: Check result if (result.valid) { - console.log("✅ Configuration valid!"); + console.log("Configuration valid!"); } else { - console.log("❌ Errors:", result.errors); + console.log("Errors:", result.errors); // Fix and validate again } @@ -354,6 +410,12 @@ validate_workflow({ connections: {...} } }); + +// Step 6: Apply auto-fixes if needed +n8n_autofix_workflow({ + id: "workflow-id", + applyFixes: true +}); ``` --- @@ -366,11 +428,14 @@ validate_workflow({ 3. Auto-sanitization fixes operator structures automatically 4. Binary operators ≠ singleValue, Unary operators = singleValue: true 5. Iterate until validation passes +6. Use `n8n_autofix_workflow` for automatic fixes **Tool Selection**: -- **validate_node_minimal**: Quick check -- **validate_node_operation**: Full config validation (**use this!**) +- **validate_node({mode: "minimal"})**: Quick required fields check +- **validate_node({profile: "runtime"})**: Full config validation (**use this!**) - **validate_workflow**: Complete workflow check +- **n8n_validate_workflow({id})**: Validate existing workflow +- **n8n_autofix_workflow({id})**: Auto-fix common issues **Related**: - [SEARCH_GUIDE.md](SEARCH_GUIDE.md) - Find nodes diff --git a/skills/n8n-mcp-tools-expert/WORKFLOW_GUIDE.md b/skills/n8n-mcp-tools-expert/WORKFLOW_GUIDE.md index 72e26b3..9608600 100644 --- a/skills/n8n-mcp-tools-expert/WORKFLOW_GUIDE.md +++ b/skills/n8n-mcp-tools-expert/WORKFLOW_GUIDE.md @@ -6,7 +6,7 @@ Complete guide for creating, updating, and managing n8n workflows. ## Tool Availability -**⚠️ Requires n8n API**: All tools in this guide need `N8N_API_URL` and `N8N_API_KEY` configured. +**Requires n8n API**: All tools in this guide need `N8N_API_URL` and `N8N_API_KEY` configured. If unavailable, use template examples and validation-only workflows. @@ -14,7 +14,7 @@ If unavailable, use template examples and validation-only workflows. ## n8n_create_workflow -**Success Rate**: 96.8% | **Speed**: 100-500ms +**Speed**: 100-500ms **Use when**: Creating new workflows from scratch @@ -39,7 +39,7 @@ n8n_create_workflow({ id: "webhook-1", name: "Webhook", type: "n8n-nodes-base.webhook", // Full prefix! - typeVersion: 1, + typeVersion: 2, position: [250, 300], parameters: { path: "slack-notify", @@ -50,7 +50,7 @@ n8n_create_workflow({ id: "slack-1", name: "Slack", type: "n8n-nodes-base.slack", - typeVersion: 1, + typeVersion: 2, position: [450, 300], parameters: { resource: "message", @@ -69,7 +69,7 @@ n8n_create_workflow({ ``` **Notes**: -- Workflows created **inactive** (must activate separately) +- Workflows created **inactive** (activate with `activateWorkflow` operation) - Auto-sanitization runs on creation - Validate before creating for best results @@ -77,26 +77,26 @@ n8n_create_workflow({ ## n8n_update_partial_workflow (MOST USED!) -**Success Rate**: 99.0% | **Speed**: 50-200ms | **Uses**: 38,287 (most used tool!) +**Speed**: 50-200ms | **Uses**: 38,287 (most used tool!) **Use when**: Making incremental changes to workflows **Common pattern**: 56s average between edits (iterative building!) -### 15 Operation Types +### 17 Operation Types **Node Operations** (6 types): 1. `addNode` - Add new node 2. `removeNode` - Remove node by ID or name -3. `updateNode` - Update node properties +3. `updateNode` - Update node properties (use dot notation) 4. `moveNode` - Change position 5. `enableNode` - Enable disabled node 6. `disableNode` - Disable active node **Connection Operations** (5 types): -7. `addConnection` - Connect nodes -8. `removeConnection` - Remove connection -9. `rewireConnection` - Change target +7. `addConnection` - Connect nodes (supports smart params) +8. `removeConnection` - Remove connection (supports ignoreErrors) +9. `rewireConnection` - Change connection target 10. `cleanStaleConnections` - Auto-remove broken connections 11. `replaceConnections` - Replace entire connections object @@ -106,7 +106,23 @@ n8n_create_workflow({ 14. `addTag` - Add tag 15. `removeTag` - Remove tag -### Smart Parameters (NEW!) +**Activation Operations** (2 types): +16. `activateWorkflow` - Activate workflow for automatic execution +17. `deactivateWorkflow` - Deactivate workflow + +### Intent Parameter (IMPORTANT!) + +Always include `intent` for better responses: + +```javascript +n8n_update_partial_workflow({ + id: "workflow-id", + intent: "Add error handling for API failures", // Describe what you're doing + operations: [...] +}) +``` + +### Smart Parameters **IF nodes** - Use semantic branch names: ```javascript @@ -182,11 +198,53 @@ n8n_create_workflow({ // - ai_textSplitter ``` +### Property Removal with undefined + +Remove properties by setting them to `undefined`: + +```javascript +// Remove a property +{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { onError: undefined } +} + +// Migrate from deprecated property +{ + type: "updateNode", + nodeName: "HTTP Request", + updates: { + continueOnFail: undefined, // Remove old + onError: "continueErrorOutput" // Add new + } +} +``` + +### Activation Operations + +```javascript +// Activate workflow +n8n_update_partial_workflow({ + id: "workflow-id", + intent: "Activate workflow for production", + operations: [{type: "activateWorkflow"}] +}) + +// Deactivate workflow +n8n_update_partial_workflow({ + id: "workflow-id", + intent: "Deactivate workflow for maintenance", + operations: [{type: "deactivateWorkflow"}] +}) +``` + ### Example Usage ```javascript n8n_update_partial_workflow({ id: "workflow-id", + intent: "Add transform node after IF condition", operations: [ // Add node { @@ -213,8 +271,16 @@ n8n_update_partial_workflow({ **cleanStaleConnections** - Remove broken connections: ```javascript +{type: "cleanStaleConnections"} +``` + +**rewireConnection** - Change target atomically: +```javascript { - type: "cleanStaleConnections" + type: "rewireConnection", + source: "Webhook", + from: "Old Handler", + to: "New Handler" } ``` @@ -227,15 +293,145 @@ n8n_update_partial_workflow({ }) ``` +**Validate before applying**: +```javascript +n8n_update_partial_workflow({ + id: "workflow-id", + operations: [...], + validateOnly: true // Preview without applying +}) +``` + +--- + +## n8n_deploy_template (QUICK START!) + +**Speed**: 200-500ms + +**Use when**: Deploying a template directly to n8n instance + +```javascript +n8n_deploy_template({ + templateId: 2947, // Required: from n8n.io + name: "My Weather to Slack", // Optional: custom name + autoFix: true, // Default: auto-fix common issues + autoUpgradeVersions: true, // Default: upgrade node versions + stripCredentials: true // Default: remove credential refs +}) +``` + +**Returns**: +- Workflow ID +- Required credentials +- Fixes applied + +**Example**: +```javascript +// Deploy a webhook to Slack template +const result = n8n_deploy_template({ + templateId: 2947, + name: "Production Slack Notifier" +}); + +// Result includes: +// - id: "new-workflow-id" +// - requiredCredentials: ["slack"] +// - fixesApplied: ["typeVersion upgraded", "expression format fixed"] +``` + +--- + +## n8n_workflow_versions (VERSION CONTROL) + +**Use when**: Managing workflow history, rollback, cleanup + +### List Versions +```javascript +n8n_workflow_versions({ + mode: "list", + workflowId: "workflow-id", + limit: 10 +}) +``` + +### Get Specific Version +```javascript +n8n_workflow_versions({ + mode: "get", + versionId: 123 +}) +``` + +### Rollback to Previous Version +```javascript +n8n_workflow_versions({ + mode: "rollback", + workflowId: "workflow-id", + versionId: 123, // Optional: specific version + validateBefore: true // Default: validate before rollback +}) +``` + +### Delete Versions +```javascript +// Delete specific version +n8n_workflow_versions({ + mode: "delete", + workflowId: "workflow-id", + versionId: 123 +}) + +// Delete all versions for workflow +n8n_workflow_versions({ + mode: "delete", + workflowId: "workflow-id", + deleteAll: true +}) +``` + +### Prune Old Versions +```javascript +n8n_workflow_versions({ + mode: "prune", + workflowId: "workflow-id", + maxVersions: 10 // Keep 10 most recent +}) +``` + +--- + +## n8n_test_workflow (TRIGGER EXECUTION) + +**Use when**: Testing workflow execution + +**Auto-detects** trigger type (webhook, form, chat) + +```javascript +// Test webhook workflow +n8n_test_workflow({ + workflowId: "workflow-id", + triggerType: "webhook", // Optional: auto-detected + httpMethod: "POST", + data: {message: "Hello!"}, + waitForResponse: true, + timeout: 120000 +}) + +// Test chat workflow +n8n_test_workflow({ + workflowId: "workflow-id", + triggerType: "chat", + message: "Hello, AI agent!", + sessionId: "session-123" // For conversation continuity +}) +``` + --- ## n8n_validate_workflow (by ID) -**Success Rate**: 99.7% | **Speed**: Network-dependent - **Use when**: Validating workflow stored in n8n -**Syntax**: ```javascript n8n_validate_workflow({ id: "workflow-id", @@ -248,7 +444,69 @@ n8n_validate_workflow({ }) ``` -**Returns**: Same as validate_workflow (from validation guide) +--- + +## n8n_get_workflow + +**Use when**: Retrieving workflow details + +**Modes**: +- `full` (default) - Complete workflow JSON +- `details` - Full + execution stats +- `structure` - Nodes + connections only +- `minimal` - ID, name, active, tags + +```javascript +// Full workflow +n8n_get_workflow({id: "workflow-id"}) + +// Just structure +n8n_get_workflow({id: "workflow-id", mode: "structure"}) + +// Minimal metadata +n8n_get_workflow({id: "workflow-id", mode: "minimal"}) +``` + +--- + +## n8n_executions (EXECUTION MANAGEMENT) + +**Use when**: Managing workflow executions + +### Get Execution Details +```javascript +n8n_executions({ + action: "get", + id: "execution-id", + mode: "summary" // preview, summary, filtered, full, error +}) + +// Error mode for debugging +n8n_executions({ + action: "get", + id: "execution-id", + mode: "error", + includeStackTrace: true +}) +``` + +### List Executions +```javascript +n8n_executions({ + action: "list", + workflowId: "workflow-id", + status: "error", // success, error, waiting + limit: 100 +}) +``` + +### Delete Execution +```javascript +n8n_executions({ + action: "delete", + id: "execution-id" +}) +``` --- @@ -265,61 +523,45 @@ n8n_validate_workflow({ → Check for errors 3. EDIT (iterative! 56s avg between edits) - n8n_update_partial_workflow({id, operations: [...]}) + n8n_update_partial_workflow({id, intent: "...", operations: [...]}) → Make changes 4. VALIDATE AGAIN n8n_validate_workflow({id}) → Verify changes -5. ACTIVATE (when ready) - ⚠️ **IMPORTANT LIMITATION**: Workflow activation is NOT supported via API or MCP. - Users must activate workflows manually in the n8n UI. - - The following operation will NOT activate the workflow: - n8n_update_partial_workflow({id, operations: [{ - type: "updateSettings", - settings: {active: true} - }]}) - - **Manual activation required**: Navigate to workflow in n8n UI and toggle activation. +5. ACTIVATE + n8n_update_partial_workflow({ + id, + intent: "Activate workflow", + operations: [{type: "activateWorkflow"}] + }) + → Workflow now runs on triggers! 6. MONITOR - n8n_list_executions({workflowId: id}) - n8n_get_execution({id: execution_id}) + n8n_executions({action: "list", workflowId: id}) + n8n_executions({action: "get", id: execution_id}) ``` -**Deployment Note**: After creating and validating workflows via MCP, inform users they must: -1. Open the workflow in n8n UI (provide workflow ID) -2. Review the workflow configuration -3. Manually activate the workflow using the activation toggle - --- ## Common Patterns from Telemetry ### Pattern 1: Edit → Validate (7,841 occurrences) - ```javascript -// Edit n8n_update_partial_workflow({...}) // ↓ 23s (thinking about what to validate) -// Validate n8n_validate_workflow({id}) ``` ### Pattern 2: Validate → Fix (7,266 occurrences) - ```javascript -// Validate n8n_validate_workflow({id}) // ↓ 58s (fixing errors) -// Fix n8n_update_partial_workflow({...}) ``` ### Pattern 3: Iterative Building (31,464 occurrences) - ```javascript update → update → update → ... (56s avg between edits) ``` @@ -328,51 +570,24 @@ update → update → update → ... (56s avg between edits) --- -## Retrieval Tools - -### n8n_get_workflow -```javascript -n8n_get_workflow({id: "workflow-id"}) -// Returns: Complete workflow JSON -``` - -### n8n_get_workflow_structure -```javascript -n8n_get_workflow_structure({id: "workflow-id"}) -// Returns: Nodes + connections only (no parameters) -``` - -### n8n_get_workflow_minimal -```javascript -n8n_get_workflow_minimal({id: "workflow-id"}) -// Returns: ID, name, active, tags only (fast!) -``` - -### n8n_list_workflows -```javascript -n8n_list_workflows({ - active: true, // Optional: filter by status - limit: 100, // Optional: max results - tags: ["production"] // Optional: filter by tags -}) -``` - ---- - ## Best Practices -### ✅ Do +### Do - Build workflows **iteratively** (avg 56s between edits) +- Include **intent** parameter for better responses - Use **smart parameters** (branch, case) for clarity - Validate **after** significant changes - Use **atomic mode** (default) for critical updates - Specify **sourceOutput** for AI connections - Clean stale connections after node renames/deletions +- Use `n8n_deploy_template` for quick starts +- Activate workflows via API when ready -### ❌ Don't +### Don't - Try to build workflows in one shot +- Skip the intent parameter - Use sourceIndex when branch/case available - Skip validation before activation - Forget to test workflows after creation @@ -383,12 +598,20 @@ n8n_list_workflows({ ## Summary **Most Important**: -1. **n8n_update_partial_workflow** is most-used tool (38,287 uses, 99.0% success) -2. Workflows built **iteratively** (56s avg between edits) -3. Use **smart parameters** (branch="true", case=0) for clarity -4. **AI connections** supported (8 types with sourceOutput) -5. **Auto-sanitization** runs on all operations -6. Validate frequently (7,841 edit → validate patterns) +1. **n8n_update_partial_workflow** is most-used tool (38,287 uses) +2. Include **intent** parameter for better responses +3. Workflows built **iteratively** (56s avg between edits) +4. Use **smart parameters** (branch="true", case=0) for clarity +5. **AI connections** supported (8 types with sourceOutput) +6. **Workflow activation** supported via API (`activateWorkflow` operation) +7. **Auto-sanitization** runs on all operations +8. Use **n8n_deploy_template** for quick starts + +**New Tools**: +- `n8n_deploy_template` - Deploy templates directly +- `n8n_workflow_versions` - Version control & rollback +- `n8n_test_workflow` - Trigger execution +- `n8n_executions` - Manage executions **Related**: - [SEARCH_GUIDE.md](SEARCH_GUIDE.md) - Find nodes to add diff --git a/skills/n8n-node-configuration/DEPENDENCIES.md b/skills/n8n-node-configuration/DEPENDENCIES.md index ad48183..5266e00 100644 --- a/skills/n8n-node-configuration/DEPENDENCIES.md +++ b/skills/n8n-node-configuration/DEPENDENCIES.md @@ -233,43 +233,27 @@ Deep dive into n8n property dependencies and displayOptions mechanism. --- -## Using get_property_dependencies +## Finding Property Dependencies -### Basic Usage +### Using get_node with search_properties Mode ```javascript -const deps = get_property_dependencies({ - nodeType: "nodes-base.httpRequest" +// Find properties related to "body" +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "body" }); ``` -### Example Response +### Using get_node with Full Detail ```javascript -{ - "nodeType": "n8n-nodes-base.httpRequest", - "dependencies": { - "body": { - "shows_when": { - "sendBody": [true], - "method": ["POST", "PUT", "PATCH", "DELETE"] - }, - "required_when_shown": true - }, - "queryParameters": { - "shows_when": { - "sendQuery": [true] - }, - "required_when_shown": false - }, - "headerParameters": { - "shows_when": { - "sendHeaders": [true] - }, - "required_when_shown": false - } - } -} +// Get complete schema with displayOptions +get_node({ + nodeType: "nodes-base.httpRequest", + detail: "full" +}); ``` ### When to Use @@ -281,7 +265,7 @@ const deps = get_property_dependencies({ - Building dynamic configuration tools **❌ Don't use when**: -- Simple configuration (use get_node_essentials) +- Simple configuration (use `get_node` with standard detail) - Just starting configuration - Field requirements are obvious @@ -564,9 +548,11 @@ method=POST **Solution**: ```javascript -// Check dependencies -const deps = get_property_dependencies({ - nodeType: "nodes-base.httpRequest" +// Check field dependencies using search_properties +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "body" }); // Find that body shows when sendBody=true @@ -606,8 +592,8 @@ const deps = get_property_dependencies({ **Solution**: ```javascript -// Check essentials for new operation -get_node_essentials({ +// Check requirements for new operation +get_node({ nodeType: "nodes-base.slack" }); @@ -644,9 +630,11 @@ get_node_essentials({ **Solution**: Respect dependencies from the start ```javascript -// Correct approach -get_property_dependencies({ - nodeType: "nodes-base.httpRequest" +// Correct approach - check property dependencies +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "body" }); // See that body only shows for POST/PUT/PATCH/DELETE @@ -730,7 +718,7 @@ get_property_dependencies({ 1. **Check dependencies when stuck** ```javascript - get_property_dependencies({nodeType: "..."}); + get_node({nodeType: "...", mode: "search_properties", propertyQuery: "..."}); ``` 2. **Configure parent properties first** @@ -742,7 +730,7 @@ get_property_dependencies({ 3. **Validate after changing operation** ```javascript // Operation changed → requirements changed - validate_node_operation({...}); + validate_node({nodeType: "...", config: {...}, profile: "runtime"}); ``` 4. **Read validation errors for dependency hints** @@ -791,8 +779,9 @@ get_property_dependencies({ - Field doesn't save → Hidden by dependencies **Tools**: -- `get_property_dependencies` - See dependency rules -- `get_node_essentials` - See operation requirements +- `get_node({mode: "search_properties"})` - Find property dependencies +- `get_node({detail: "full"})` - See complete schema with displayOptions +- `get_node` - See operation requirements (standard detail) - Validation errors - Hints about dependencies **Related Files**: diff --git a/skills/n8n-node-configuration/SKILL.md b/skills/n8n-node-configuration/SKILL.md index 9bbfdfe..8bc4753 100644 --- a/skills/n8n-node-configuration/SKILL.md +++ b/skills/n8n-node-configuration/SKILL.md @@ -1,6 +1,6 @@ --- name: n8n-node-configuration -description: Operation-aware node configuration guidance. Use when configuring nodes, understanding property dependencies, determining required fields, choosing between get_node_essentials and get_node_info, or learning common configuration patterns by node type. +description: Operation-aware node configuration guidance. Use when configuring nodes, understanding property dependencies, determining required fields, choosing between get_node detail levels, or learning common configuration patterns by node type. --- # n8n Node Configuration @@ -14,11 +14,11 @@ Expert guidance for operation-aware node configuration with property dependencie **Progressive disclosure**: Start minimal, add complexity as needed Configuration best practices: -- get_node_essentials is the most used discovery pattern +- `get_node` with `detail: "standard"` is the most used discovery pattern - 56 seconds average between configuration edits -- 91.7% success rate with essentials-based configuration +- Covers 95% of use cases with 1-2K tokens response -**Key insight**: Most configurations need only essentials, not full schema! +**Key insight**: Most configurations need only standard detail, not full schema! --- @@ -79,23 +79,20 @@ Configuration best practices: ### 3. Progressive Discovery -**Use the right tool for the right job**: +**Use the right detail level**: -1. **get_node_essentials** (91.7% success rate) - - Quick overview - - Required fields - - Common options - - **Use first** - covers 90% of needs +1. **get_node({detail: "standard"})** - DEFAULT + - Quick overview (~1-2K tokens) + - Required fields + common options + - **Use first** - covers 95% of needs -2. **get_property_dependencies** (for complex nodes) - - Shows what fields depend on others - - Reveals conditional requirements - - Use when essentials isn't enough +2. **get_node({mode: "search_properties", propertyQuery: "..."})** (for finding specific fields) + - Find properties by name + - Use when looking for auth, body, headers, etc. -3. **get_node_info** (full schema) - - Complete documentation - - All possible fields - - Use when essentials + dependencies insufficient +3. **get_node({detail: "full"})** (complete schema) + - All properties (~3-8K tokens) + - Use only when standard detail is insufficient --- @@ -106,13 +103,13 @@ Configuration best practices: ``` 1. Identify node type and operation ↓ -2. Use get_node_essentials +2. Use get_node (standard detail is default) ↓ 3. Configure required fields ↓ 4. Validate configuration ↓ -5. If dependencies unclear → get_property_dependencies +5. If field unclear → get_node({mode: "search_properties"}) ↓ 6. Add optional fields as needed ↓ @@ -128,9 +125,9 @@ Configuration best practices: // Goal: POST JSON to API ``` -**Step 2**: Get essentials +**Step 2**: Get node info ```javascript -const info = get_node_essentials({ +const info = get_node({ nodeType: "nodes-base.httpRequest" }); @@ -148,7 +145,7 @@ const info = get_node_essentials({ **Step 4**: Validate ```javascript -validate_node_operation({ +validate_node({ nodeType: "nodes-base.httpRequest", config, profile: "runtime" @@ -168,7 +165,7 @@ validate_node_operation({ **Step 6**: Validate again ```javascript -validate_node_operation({...}); +validate_node({...}); // → Error: "body required when sendBody=true" ``` @@ -191,47 +188,61 @@ validate_node_operation({...}); **Step 8**: Final validation ```javascript -validate_node_operation({...}); +validate_node({...}); // → Valid! ✅ ``` --- -## get_node_essentials vs get_node_info +## get_node Detail Levels -### Use get_node_essentials When: +### Standard Detail (DEFAULT - Use This!) -**✅ Starting configuration** (91.7% success rate) +**✅ Starting configuration** ```javascript -get_node_essentials({ +get_node({ nodeType: "nodes-base.slack" }); +// detail="standard" is the default ``` -**Returns**: +**Returns** (~1-2K tokens): - Required fields - Common options -- Basic examples - Operation list +- Metadata -**Fast**: ~18 seconds average (from search → essentials) +**Use**: 95% of configuration needs -### Use get_node_info When: +### Full Detail (Use Sparingly) -**✅ Essentials insufficient** +**✅ When standard isn't enough** ```javascript -get_node_info({ - nodeType: "nodes-base.slack" +get_node({ + nodeType: "nodes-base.slack", + detail: "full" }); ``` -**Returns**: -- Full schema +**Returns** (~3-8K tokens): +- Complete schema - All properties -- Complete documentation -- Advanced options +- All nested options -**Slower**: More data to process +**Warning**: Large response, use only when standard insufficient + +### Search Properties Mode + +**✅ Looking for specific field** +```javascript +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "auth" +}); +``` + +**Use**: Find authentication, headers, body fields, etc. ### Decision Tree @@ -239,27 +250,27 @@ get_node_info({ ┌─────────────────────────────────┐ │ Starting new node config? │ ├─────────────────────────────────┤ -│ YES → get_node_essentials │ +│ YES → get_node (standard) │ └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ -│ Essentials has what you need? │ +│ Standard has what you need? │ ├─────────────────────────────────┤ -│ YES → Configure with essentials │ +│ YES → Configure with it │ │ NO → Continue │ └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ -│ Need dependency info? │ +│ Looking for specific field? │ ├─────────────────────────────────┤ -│ YES → get_property_dependencies │ +│ YES → search_properties mode │ │ NO → Continue │ └─────────────────────────────────┘ ↓ ┌─────────────────────────────────┐ │ Still need more details? │ ├─────────────────────────────────┤ -│ YES → get_node_info │ +│ YES → get_node({detail: "full"})│ └─────────────────────────────────┘ ``` @@ -334,30 +345,27 @@ get_node_info({ } ``` -### Using get_property_dependencies +### Finding Property Dependencies -**Example**: +**Use get_node with search_properties mode**: ```javascript -const deps = get_property_dependencies({ - nodeType: "nodes-base.httpRequest" +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "body" }); -// Returns dependency tree -{ - "dependencies": { - "body": { - "shows_when": { - "sendBody": [true], - "method": ["POST", "PUT", "PATCH", "DELETE"] - } - }, - "queryParameters": { - "shows_when": { - "sendQuery": [true] - } - } - } -} +// Returns property paths matching "body" with descriptions +``` + +**Or use full detail for complete schema**: +```javascript +get_node({ + nodeType: "nodes-base.httpRequest", + detail: "full" +}); + +// Returns complete schema with displayOptions rules ``` **Use this when**: Validation fails and you don't understand why field is missing/required @@ -382,7 +390,7 @@ const deps = get_property_dependencies({ **How to configure**: 1. Choose resource 2. Choose operation -3. Use get_node_essentials to see operation-specific requirements +3. Use get_node to see operation-specific requirements 4. Configure required fields ### Pattern 2: HTTP-Based Nodes @@ -573,14 +581,16 @@ body is required when: **How to discover**: ```javascript // Option 1: Read validation error -validate_node_operation({...}); +validate_node({...}); // Error: "body required when sendBody=true" -// Option 2: Check dependencies -get_property_dependencies({ - nodeType: "nodes-base.httpRequest" +// Option 2: Search for the property +get_node({ + nodeType: "nodes-base.httpRequest", + mode: "search_properties", + propertyQuery: "body" }); -// Shows: body → shows_when: sendBody=[true], method=[POST,PUT,PATCH,DELETE] +// Shows: body property with displayOptions rules // Option 3: Try minimal config and iterate // Start without body, validation will tell you if needed @@ -600,10 +610,11 @@ singleValue should be true when: **Manual check**: ```javascript -get_property_dependencies({ - nodeType: "nodes-base.if" +get_node({ + nodeType: "nodes-base.if", + detail: "full" }); -// Shows operator-specific dependencies +// Shows complete schema with operator-specific rules ``` --- @@ -651,7 +662,7 @@ n8n_update_partial_workflow({...}); // YOLO ```javascript // Validate before deploying const config = {...}; -const result = validate_node_operation({...}); +const result = validate_node({...}); if (result.valid) { n8n_update_partial_workflow({...}); } @@ -681,7 +692,7 @@ if (result.valid) { **Good**: ```javascript // Check requirements when changing operation -get_node_essentials({ +get_node({ nodeType: "nodes-base.slack" }); // See what update operation needs (messageId, not channel) @@ -693,24 +704,24 @@ get_node_essentials({ ### ✅ Do -1. **Start with get_node_essentials** - - 91.7% success rate - - Faster than get_node_info - - Sufficient for most needs +1. **Start with get_node (standard detail)** + - ~1-2K tokens response + - Covers 95% of configuration needs + - Default detail level 2. **Validate iteratively** - Configure → Validate → Fix → Repeat - Average 2-3 iterations is normal - Read validation errors carefully -3. **Use property dependencies when stuck** - - If field seems missing, check dependencies +3. **Use search_properties mode when stuck** + - If field seems missing, search for it - Understand what controls field visibility - - get_property_dependencies reveals rules + - `get_node({mode: "search_properties", propertyQuery: "..."})` 4. **Respect operation context** - Different operations = different requirements - - Always check essentials when changing operation + - Always check get_node when changing operation - Don't assume configs are transferable 5. **Trust auto-sanitization** @@ -720,15 +731,15 @@ get_node_essentials({ ### ❌ Don't -1. **Jump to get_node_info immediately** - - Try essentials first +1. **Jump to detail="full" immediately** + - Try standard detail first - Only escalate if needed - - Full schema is overwhelming + - Full schema is 3-8K tokens 2. **Configure blindly** - Always validate before deploying - Understand why fields are required - - Check dependencies for conditional fields + - Use search_properties for conditional fields 3. **Copy configs without understanding** - Different operations need different fields @@ -754,10 +765,10 @@ For comprehensive guides on specific topics: ## Summary **Configuration Strategy**: -1. Start with get_node_essentials (91.7% success) +1. Start with `get_node` (standard detail is default) 2. Configure required fields for operation 3. Validate configuration -4. Check dependencies if stuck +4. Search properties if stuck 5. Iterate until valid (avg 2-3 cycles) 6. Deploy with confidence diff --git a/skills/n8n-validation-expert/ERROR_CATALOG.md b/skills/n8n-validation-expert/ERROR_CATALOG.md index e329fe6..a0820d7 100644 --- a/skills/n8n-validation-expert/ERROR_CATALOG.md +++ b/skills/n8n-validation-expert/ERROR_CATALOG.md @@ -65,8 +65,8 @@ Common validation errors by priority: **How to identify required fields**: ```javascript -// Use get_node_essentials to see what's required -const info = get_node_essentials({ +// Use get_node to see what's required +const info = get_node({ nodeType: "nodes-base.slack" }); // Check properties marked as "required": true @@ -868,15 +868,15 @@ let config = { text: "Hello" }; -validate_node_operation({nodeType: "nodes-base.slack", config}); +validate_node({nodeType: "nodes-base.slack", config, profile: "runtime"}); // ✅ Valid // Step 2: Add features one by one config.attachments = [...]; -validate_node_operation({nodeType: "nodes-base.slack", config}); +validate_node({nodeType: "nodes-base.slack", config, profile: "runtime"}); config.blocks = [...]; -validate_node_operation({nodeType: "nodes-base.slack", config}); +validate_node({nodeType: "nodes-base.slack", config, profile: "runtime"}); ``` ### Pattern 2: Error Triage @@ -903,14 +903,14 @@ result.suggestions.forEach(sug => { }); ``` -### Pattern 3: Use get_node_essentials +### Pattern 3: Use get_node **Problem**: Don't know what's required **Solution**: ```javascript // Before configuring, check requirements -const info = get_node_essentials({ +const info = get_node({ nodeType: "nodes-base.slack" }); @@ -927,7 +927,7 @@ info.properties.forEach(prop => { ## Summary **Most Common Errors**: -1. `missing_required` (45%) - Always check get_node_essentials +1. `missing_required` (45%) - Always check get_node 2. `invalid_value` (28%) - Check allowed values 3. `type_mismatch` (12%) - Use correct data types 4. `invalid_expression` (8%) - Use Expression Syntax skill diff --git a/skills/n8n-validation-expert/FALSE_POSITIVES.md b/skills/n8n-validation-expert/FALSE_POSITIVES.md index bd98fb8..467aabd 100644 --- a/skills/n8n-validation-expert/FALSE_POSITIVES.md +++ b/skills/n8n-validation-expert/FALSE_POSITIVES.md @@ -530,7 +530,7 @@ Many warnings are context-dependent: **Development**: ```javascript -validate_node_operation({ +validate_node({ nodeType: "nodes-base.slack", config, profile: "ai-friendly" // Fewer warnings during development @@ -539,7 +539,7 @@ validate_node_operation({ **Pre-Production**: ```javascript -validate_node_operation({ +validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" // Balanced validation @@ -548,7 +548,7 @@ validate_node_operation({ **Production Deployment**: ```javascript -validate_node_operation({ +validate_node({ nodeType: "nodes-base.slack", config, profile: "strict" // All warnings, review each one diff --git a/skills/n8n-validation-expert/SKILL.md b/skills/n8n-validation-expert/SKILL.md index aac9052..fd6ce22 100644 --- a/skills/n8n-validation-expert/SKILL.md +++ b/skills/n8n-validation-expert/SKILL.md @@ -79,13 +79,13 @@ Validation is typically iterative: ``` 1. Configure node ↓ -2. validate_node_operation (23 seconds thinking about errors) +2. validate_node (23 seconds thinking about errors) ↓ 3. Read error messages carefully ↓ 4. Fix errors ↓ -5. validate_node_operation again (58 seconds fixing) +5. validate_node again (58 seconds fixing) ↓ 6. Repeat until valid (usually 2-3 iterations) ``` @@ -98,7 +98,7 @@ let config = { operation: "create" }; -const result1 = validate_node_operation({ +const result1 = validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" @@ -110,7 +110,7 @@ const result1 = validate_node_operation({ // Iteration 2 config.name = "general"; -const result2 = validate_node_operation({ +const result2 = validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" @@ -122,7 +122,7 @@ const result2 = validate_node_operation({ // Iteration 3 config.text = "Hello!"; -const result3 = validate_node_operation({ +const result3 = validate_node({ nodeType: "nodes-base.slack", config, profile: "runtime" @@ -193,7 +193,7 @@ Choose the right profile for your stage: **What it means**: A required field is not provided **How to fix**: -1. Use `get_node_essentials` to see required fields +1. Use `get_node` to see required fields 2. Add the missing field to your configuration 3. Provide an appropriate value @@ -215,7 +215,7 @@ config.channel = "#general"; **How to fix**: 1. Check error message for allowed values -2. Use `get_node_essentials` to see options +2. Use `get_node` to see options 3. Update to a valid value **Example**: @@ -430,7 +430,7 @@ Validation warnings that are technically "wrong" but acceptable in your use case **Use `ai-friendly` profile**: ```javascript -validate_node_operation({ +validate_node({ nodeType: "nodes-base.slack", config: {...}, profile: "ai-friendly" // Fewer false positives @@ -585,7 +585,7 @@ validate_workflow({ **When**: Configuration is severely broken **Steps**: -1. Note required fields from `get_node_essentials` +1. Note required fields from `get_node` 2. Create minimal valid configuration 3. Add features incrementally 4. Validate after each addition @@ -642,7 +642,7 @@ n8n_autofix_workflow({ - Use `runtime` profile for pre-deployment - Check `valid` field before assuming success - Trust auto-sanitization for operator issues -- Use `get_node_essentials` when unclear about requirements +- Use `get_node` when unclear about requirements - Document false positives you accept ### ❌ Don't diff --git a/skills/n8n-workflow-patterns/README.md b/skills/n8n-workflow-patterns/README.md index 38ac229..2bd46ae 100644 --- a/skills/n8n-workflow-patterns/README.md +++ b/skills/n8n-workflow-patterns/README.md @@ -35,8 +35,9 @@ Teaches architectural patterns for building n8n workflows. Provides structure, b **n8n-mcp tools**: - search_nodes (find nodes for patterns) -- get_node_essentials (understand node operations) +- get_node (understand node operations) - search_templates (find example workflows) +- ai_agents_guide (AI pattern guidance) **Related skills**: - n8n MCP Tools Expert (find and configure nodes) @@ -230,7 +231,7 @@ Use `search_templates` to find examples for your use case! **Node Discovery** (n8n MCP Tools Expert): 4. Find nodes for pattern (search_nodes) -5. Understand node operations (get_node_essentials) +5. Understand node operations (get_node) **Implementation** (n8n Expression Syntax + Node Configuration): 6. Write expressions ({{$json.body.field}}) diff --git a/skills/n8n-workflow-patterns/SKILL.md b/skills/n8n-workflow-patterns/SKILL.md index 4eadd2b..437bc5d 100644 --- a/skills/n8n-workflow-patterns/SKILL.md +++ b/skills/n8n-workflow-patterns/SKILL.md @@ -126,14 +126,14 @@ When building ANY workflow, follow this checklist: - [ ] Configure error handling ### Validation Phase -- [ ] Validate each node configuration (validate_node_operation) +- [ ] Validate each node configuration (validate_node) - [ ] Validate complete workflow (validate_workflow) - [ ] Test with sample data - [ ] Handle edge cases (empty data, errors) ### Deployment Phase - [ ] Review workflow settings (execution order, timeout, error handling) -- [ ] Activate workflow ⚠️ **Manual activation required in n8n UI** (API/MCP cannot activate) +- [ ] Activate workflow using `activateWorkflow` operation - [ ] Monitor first executions - [ ] Document workflow purpose and data flow @@ -225,8 +225,10 @@ These skills work together with Workflow Patterns: **n8n MCP Tools Expert** - Use to: - Find nodes for your pattern (search_nodes) -- Understand node operations (get_node_essentials) +- Understand node operations (get_node) - Create workflows (n8n_create_workflow) +- Deploy templates (n8n_deploy_template) +- Use ai_agents_guide for AI pattern guidance **n8n Expression Syntax** - Use to: - Write expressions in transformation nodes