AgentSkillsCN

n8n-workflow-builder

精通n8n工作流自动化技能,涵盖表达式语法、MCP工具的使用、工作流模式、验证机制、节点配置,以及Code节点的开发。当您需要构建n8n工作流、使用{{}}或$json/$node/$now/$env变量编写n8n表达式、搜索n8n节点、验证n8n配置、运用n8n-mcp MCP工具、创建Webhook/HTTP/数据库/AI代理/定时工作流,或调试n8n验证错误与误报、配置n8n节点的属性与依赖关系、在n8n Code节点中编写JavaScript或Python代码、在Code节点中使用$input/$helpers,或排查n8n表达式错误时,此技能都将成为您的得力助手。

SKILL.md
--- frontmatter
name: n8n-workflow-builder
description: Expert n8n workflow automation skill covering expression syntax, MCP tool usage, workflow patterns, validation, node configuration, and Code node development. Use when building n8n workflows, writing n8n expressions with {{}} or $json/$node/$now/$env variables, searching for n8n nodes, validating n8n configurations, using n8n-mcp MCP tools, creating webhook/HTTP/database/AI agent/scheduled workflows, debugging n8n validation errors or false positives, configuring n8n node properties and dependencies, writing JavaScript or Python in n8n Code nodes, using $input/$helpers in Code nodes, or troubleshooting n8n expression errors.

n8n Workflow Builder

Unified expert guidance for building production-ready n8n workflows. Consolidates expression syntax, MCP tool usage, 5 workflow patterns, validation, node configuration, and Code node development.


1. Expression Syntax

Core Syntax

All n8n expressions use double curly braces: {{ expression }}.

VariablePurposeExample
$jsonCurrent item data{{ $json.email }}
$json.bodyWebhook payload (NOT $json directly){{ $json.body.name }}
$node["Name"].jsonData from specific node{{ $node["HTTP Request"].json.id }}
$nowCurrent datetime (Luxon){{ $now.toISO() }}
$todayStart of today{{ $today.toISO() }}
$envEnvironment variables{{ $env.API_KEY }}
$execution.idCurrent execution ID{{ $execution.id }}
$workflow.idWorkflow ID{{ $workflow.id }}
$('Node')Function form of $node{{ $('Webhook').item.json.body }}
$input.all()All input itemsUsed in Code nodes only
$runIndexCurrent run index{{ $runIndex }}

Critical Expression Rules

  1. Webhook data is ALWAYS nested under $json.body — this is the #1 expression mistake:

    code
    ❌ {{ $json.email }}           → undefined for webhook data
    ✅ {{ $json.body.email }}      → correct webhook access
    
  2. Dot notation for simple paths, bracket for special characters:

    code
    ✅ {{ $json.user.name }}
    ✅ {{ $json["first-name"] }}   → hyphens require brackets
    ✅ {{ $json["my field"] }}     → spaces require brackets
    
  3. Ternary for conditional values:

    code
    {{ $json.status === "active" ? "Yes" : "No" }}
    
  4. Optional chaining to prevent errors:

    code
    {{ $json.user?.address?.city ?? "Unknown" }}
    
  5. Date manipulation with Luxon (built-in):

    code
    {{ $now.minus({days: 7}).toISO() }}
    {{ DateTime.fromISO($json.date).toFormat("yyyy-MM-dd") }}
    

Top 5 Expression Mistakes

#MistakeFix
1Accessing webhook data as $json.fieldUse $json.body.field
2Using $json in Code nodesUse $input.first().json or $input.all()
3Missing {{ }} wrapperWrap ALL expressions: {{ $json.name }}
4String concatenation without templateUse {{ "Hello " + $json.name }}
5Date comparison as stringsParse with DateTime.fromISO() first

2. MCP Tool Selection Guide

7 Core MCP Tools — Quick Reference

ToolWhen to UseKey Parameters
tools_documentationSTART HERE — load best practicesNone
search_nodesFind nodes by keywordquery, includeExamples: true, source
get_nodeGet node detailsnodeType, detail, mode, includeExamples
validate_nodeValidate node confignodeType, config, mode, profile
validate_workflowValidate complete workflowworkflow JSON
search_templatesFind workflow templatessearchMode, query, filters
get_templateGet full template JSONtemplateId, mode

nodeType Format — CRITICAL

code
Core nodes:      n8n-nodes-base.slack
                 n8n-nodes-base.httpRequest
                 n8n-nodes-base.webhook

LangChain/AI:    @n8n/n8n-nodes-langchain.agent
                 @n8n/n8n-nodes-langchain.lmChatOpenAi
                 @n8n/n8n-nodes-langchain.memoryBufferWindow

Community:       n8n-nodes-community.customNode

⚠️ Search tools use short format (nodes-base.slack), workflow tools use full format (n8n-nodes-base.slack). The MCP server auto-sanitizes, but always use full format in workflow JSON.

search_nodes Best Practices

code
search_nodes({query: "slack", includeExamples: true})
search_nodes({query: "AI agent", source: "verified"})
search_nodes({query: "database postgres"})
  • Always set includeExamples: true for configuration examples
  • Use source: "verified" to filter to trusted community nodes
  • Keep queries to 1-3 keywords for best results

get_node Modes and Detail Levels

ModeDetailUse Case
infominimalQuick check — name, type, description
infostandardDefault — essential properties + operations
infofullEverything — all properties, all versions
docsMarkdown documentation
search_propertiesFind specific property by name
versionsVersion history and changes

validate_node Profiles

ProfileSpeedUse Case
minimal<100msQuick required-field check before building
runtime~500msFull validation matching n8n runtime behavior
ai-friendly~500msAI workflow specific (LangChain connections)
strict~1sMaximum validation — all rules enforced

Validation sequence: minimal first → fix errors → runtime or ai-friendly → fix → validate_workflow.

search_templates searchModes

ModeWhen to UseExample
keywordGeneral text searchquery: "slack notification"
by_taskTask-based discoverytask: "webhook_processing"
by_nodesFind templates using specific nodesnodeTypes: ["n8n-nodes-base.slack"]
by_metadataFilter by complexity/audiencecomplexity: "simple"

Filters: complexity, targetAudience, maxSetupMinutes, requiredService.


3. Workflow Patterns

Five proven architectural patterns for n8n workflows. Select based on trigger type and data flow.

Pattern Selection

TriggerData FlowPattern
External HTTP requestReceive → Process → RespondWebhook Processing
Timer or cronFetch → Transform → DeliverScheduled Tasks
Internal triggerCall API → Handle errors → ProcessHTTP API Integration
Data sync neededQuery → Transform → Write → VerifyDatabase Operations
AI/LLM neededAgent → Tools → Memory → OutputAI Agent Workflow

Pattern 1: Webhook Processing

code
Webhook → Validate Input → Transform Data → Business Logic → Respond to Webhook
                ↓ (on error)
          Error Response (4xx)

Key rules:

  • Always validate incoming data before processing
  • Always respond with Respond to Webhook node — timeouts cause client errors
  • Access payload via $json.body, headers via $json.headers
  • Add authentication (header check or HMAC) for production webhooks

Pattern 2: HTTP API Integration

code
Trigger → Set Auth Headers → HTTP Request → IF (status check) → Process Response
                                                    ↓ (on error)
                                              Retry / Error Handler

Key rules:

  • Set continueOnFail: true on HTTP Request to handle errors gracefully
  • Check response status in IF node before processing
  • Implement retry logic for transient failures (429, 503)
  • Store credentials in n8n Credentials, reference via credential ID

Pattern 3: Database Operations

code
Trigger → Query Source → Transform/Map Fields → Upsert Target → Verify Write

Key rules:

  • Use upsert over insert/update to handle both cases
  • Map fields explicitly in a Set node — never pass raw data
  • Add a verification query after writes for critical operations
  • Use splitInBatches for large datasets (>1000 records)

Pattern 4: AI Agent Workflow

code
Trigger → Agent → [Tools: HTTP, Code, etc.] → Memory → Output Parser → Response
              ↑        ↓
         LM Chat    ai_tool connections (NOT main)

Key rules:

  • LangChain nodes use @n8n/n8n-nodes-langchain.* nodeType format
  • Agent connections use ai_agent, ai_tool, ai_memory, ai_outputParser — NOT main
  • Use validate_node(profile: 'ai-friendly') for AI nodes
  • Any node can be an AI tool — not just those marked usableAsTool: true
  • Connect LLM to agent via ai_languageModel connection type

Pattern 5: Scheduled Tasks

code
Schedule Trigger → Fetch Data → Process/Transform → Notify/Store → Log Result

Key rules:

  • Use scheduleTrigger node with cron expressions
  • Add error notification (email/Slack) for failed runs
  • Include execution metadata in logs ($execution.id, $now)
  • Use IF node to skip processing when no new data exists

For full pattern implementations with node configurations, see references/WORKFLOW_PATTERNS.md.


4. Validation & Error Handling

Validation Loop

Expect 2-3 validation iterations per workflow. This is normal.

code
Build Node Config → validate_node(minimal) → Fix Errors
                                                  ↓
                    validate_node(full, runtime) ← ┘
                              ↓
                    Build Workflow JSON
                              ↓
                    validate_workflow → Fix Errors → Re-validate
                              ↓
                    Deploy (n8n_create_workflow)

Top 9 Error Types — Quick Fix Guide

ErrorCauseFix
MISSING_REQUIREDRequired property not setSet the property explicitly — never rely on defaults
INVALID_TYPEWrong value typeCheck expected type with get_node(mode: 'search_properties')
UNKNOWN_PROPERTYProperty doesn't exist on nodeVerify property name in node docs
INVALID_EXPRESSIONMalformed {{ }} expressionCheck syntax — common: missing brackets, typos in $json
MISSING_CONNECTIONNode has no input connectionAdd connection from previous node
CIRCULAR_DEPENDENCYWorkflow contains a loopRestructure to break circular reference
INVALID_CREDENTIALCredential not found or wrong typeVerify credential ID and type match node requirements
DUPLICATE_NODE_NAMETwo nodes share a nameRename to unique names
INVALID_AI_CONNECTIONWrong connection type for AI nodeUse ai_tool/ai_memory/ai_languageModel, not main

False Positive Patterns — When to Ignore

These validation warnings can be safely ignored:

  1. Optional property warnings — Properties with defaults don't need explicit values unless overriding
  2. Credential warnings in development — Credentials are environment-specific; validate only on deployment
  3. Expression validation on dynamic values — Expressions referencing runtime data can't be statically validated
  4. Community node warnings — Community nodes may have incomplete validation schemas
  5. Deprecated property warnings — Still functional; update when convenient
  6. AI tool flexibility warnings — Nodes marked as non-tool can still be used as tools

For complete error catalog with fix procedures, see references/ERROR_CATALOG.md.


5. Node Configuration

Operation-Aware Configuration

n8n nodes reveal different required fields based on the selected resource and operation. Always configure in this order:

code
1. Set resource    → reveals operation options
2. Set operation   → reveals required properties
3. Set required    → reveals optional properties
4. Set optional    → complete configuration

Example — Slack node:

json
// Step 1-2: Resource + Operation determine required fields
{"resource": "message", "operation": "post"}

// Step 3: Required fields for message.post
{"select": "channel", "channelId": "C123", "text": "Hello"}

// Step 4: Optional enhancements
{"jsonParameters": true, "attachments": [...]}

Property Dependency Chains

Some properties only appear when parent properties have specific values:

code
resource: "message"
  └→ operation: "post"
       └→ select: "channel"     ← only shown when operation is "post"
            └→ channelId        ← only shown when select is "channel"

Always use get_node(detail: 'standard') to discover the full dependency tree before configuring.

AI Workflow Connection Rules

LangChain nodes use special connection types, NOT the standard main type:

Connection TypeConnectsExample
ai_agentTrigger → AgentManualTrigger → Agent
ai_languageModelLLM → AgentChatOpenAI → Agent
ai_toolTool → AgentHTTPRequest → Agent (as tool)
ai_memoryMemory → AgentBufferMemory → Agent
ai_outputParserParser → AgentJSONParser → Agent

Authentication Patterns

  • OAuth2: Configure via n8n Credentials UI, reference by credential ID in node config
  • API Key: Store in n8n Credentials or $env variables — never hardcode
  • Header Auth: Use Set node before HTTP Request to add Authorization header
  • No Auth: Set authentication: "none" explicitly — don't rely on defaults

6. Code Node Patterns

When to Use Code Nodes

Use standard n8n nodes for 95% of operations. Use Code nodes only when:

  • Complex data transformation that no standard node handles
  • Custom API response parsing
  • Multi-step calculations or conditional logic beyond IF/Switch

JavaScript (Primary — 95% of Code node use)

Mode Selection

ModeAccess PatternUse When
Run Once for All Items$input.all()Processing arrays, aggregating, batch operations
Run Once for Each Item$input.itemPer-item transformations, simple mapping

Data Access Patterns

javascript
// All Items mode (most common — 26% of usage)
const items = $input.all();
return items.map(item => ({
  json: { ...item.json, processed: true }
}));

// First Item mode (25% of usage)
const data = $input.first().json;
return [{ json: { result: data.value * 2 } }];

// Each Item mode (19% of usage)
const item = $input.item;
return [{ json: { ...item.json, transformed: true } }];

// Reference other nodes
const webhookData = $('Webhook').first().json.body;
const httpResult = $('HTTP Request').first().json;

CRITICAL: Return Format

javascript
// ✅ MUST return array of objects with "json" key
return [{ json: { name: "Alice", status: "active" } }];

// ✅ Multiple items
return items.map(i => ({ json: { id: i.json.id } }));

// ❌ FAILS — missing json wrapper
return [{ name: "Alice" }];

// ❌ FAILS — not an array
return { json: { name: "Alice" } };

Built-in Helpers

javascript
// HTTP requests (no external packages needed)
const response = await $helpers.httpRequest({
  method: 'GET',
  url: 'https://api.example.com/data',
  headers: { 'Authorization': `Bearer ${$env.API_KEY}` }
});
return [{ json: response }];

Top 5 JavaScript Errors

#ErrorFix
1Not returning [{json: {...}}]Always wrap in array + json key
2Using $json instead of $inputIn Code nodes, use $input.first().json
3Webhook data at wrong depthAccess $input.first().json.body not .json
4Async without awaitAdd await before $helpers.httpRequest()
5Modifying input directlyClone with spread: {...item.json}

Python (Secondary — 5% of use cases)

Use Python only when specific standard library functions are needed or Python syntax is strongly preferred.

Key Differences from JavaScript

python
# Data access uses underscore prefix
items = _input.all()          # not $input.all()
first = _input.first()        # not $input.first()
item = _input.item            # not $input.item

# Return format — same structure, Python syntax
return [{"json": {"name": "Alice", "processed": True}}]

# Reference other nodes
webhook = _node["Webhook"].json["body"]

Python Limitations

  • No external libraries — no pandas, numpy, requests, beautifulsoup
  • Standard library only: json, datetime, re, math, collections, itertools, hashlib, base64, urllib
  • No pip install — sandbox environment has no package manager
  • No file system access — cannot read/write files

For production-tested code patterns, see references/CODE_EXAMPLES.md.