From n8n
Build, test, and deploy n8n workflows via REST API with incremental testing. Expert automation for n8n. This is Step 3 of 3 in the Pattern AI Automations build pipeline. USE THIS SKILL WHEN: - User says "create workflow", "build automation", "deploy to n8n", "activate workflow", "build the workflow" - User needs to list, update, delete, or test workflows - User mentions webhook execution, checking executions, debugging workflow runs - User asks about n8n nodes, expressions, credentials, or Code nodes - User needs JavaScript or Python code for n8n Code nodes - User mentions {{ }} expressions, $json, $input, or $node references - User asks about AI Agent, OpenAI, Anthropic, Google Sheets, Airtable, Slack, or other n8n nodes - User has completed n8n-project-init and is ready to build
npx claudepluginhub jonmcgee37/n8n-automations-toolkit --plugin n8nThis skill uses the workspace's default tool permissions.
Build, test, and deploy n8n workflows via REST API with incremental testing.
Verifies tests pass on completed feature branch, presents options to merge locally, create GitHub PR, keep as-is or discard; executes choice and cleans up worktree.
Writes implementation plans from specs for multi-step tasks, mapping files and breaking into TDD bite-sized steps before coding.
Executes pre-written implementation plans: critically reviews, follows bite-sized steps exactly, runs verifications, tracks progress with checkpoints, uses git worktrees, stops on blockers.
Build, test, and deploy n8n workflows via REST API with incremental testing.
This is Step 3 of 3 in the build pipeline:
[Step 1] PRD Generator → [Step 2] Project Init → [Step 3] n8n Builder ← YOU ARE HERE
Use the Read tool to read these files NOW:
1. Read references/pitfalls.md (critical command format rules)
2. Read references/build-process.md (step-by-step build workflow)
Read the project's CLAUDE.md file in the current working directory:
Read CLAUDE.md
Extract and hold in context:
.envIf CLAUDE.md is missing:
"I don't see a CLAUDE.md in this directory. This project may not have been initialized. Run
Set up a new n8n projectfirst, then come back to build."
If CLAUDE.md exists but the Blueprint Reference section is empty:
"There's no blueprint in CLAUDE.md. You can paste your blueprint now and I'll use it as the build spec, or describe the workflow and I'll proceed from your description."
Read the .env file in the working directory to verify:
- N8N_API_URL is set
- N8N_API_KEY is set
- N8N_CREDENTIALS_TEMPLATE_URL is set
If any values are missing, stop and tell the user to run the project initializer first.
Briefly confirm what you're about to build based on the blueprint:
"Ready to build: [Project Name] Trigger: [trigger type] Steps: [count] nodes Output: [destination]
Building node by node with testing after each step. Starting now."
Then create a todo list with one item per node/major step from the blueprint.
SKILL LOADS -> READ REFS -> READ CLAUDE.md -> CHECK .env -> CONFIRM SPEC -> BUILD
If the user mentions specific tools, nodes, or services - YOU MUST USE THEM.
User says "use Apify" -> You use Apify node
User says "use OpenAI" -> You use OpenAI Chat Model
Never substitute, skip, or defer user-requested tools.
Loop node has error -> Debug why -> Fix the loop configuration
Don't switch to "simpler" approaches. Keep the correct architecture.
Never add nodes requiring authentication unless:
Always copy type AND typeVersion from the credentials template.
ADD NODE -> TEST -> ADD NEXT NODE -> TEST -> REPEAT
NEVER add 2+ nodes without testing between them.
Node fails -> Debug the error -> Update the same workflow (PUT)
One workflow ID for the entire build process.
| Priority | Use When |
|---|---|
| 1. Native node | Built-in exists (Slack, Sheets, etc.) |
| 2. AI Agent node | For ANY AI/LLM task |
| 3. Loop node | For processing multiple items |
| 4. HTTP Request | Native has issues OR no node exists |
| 5. Code node | Complex logic only |
Never use placeholder URLs, fake IDs, or "REPLACE_ME" values.
Always set limit=2 on data-fetching nodes for fast testing.
Never check, run, or modify workflows the user didn't mention.
1. Create temp workflow: Webhook + getSchema/getAll node
2. Execute to fetch actual field names
3. Use exact field names in main workflow
1. Read references/triggers.md
2. Create workflow with trigger only
3. Test trigger
1. Read relevant reference file for this node type
2. Add ONE node to workflow
3. Test workflow
4. If ERROR -> fix -> retry
5. If SUCCESS -> move to next node
1. All nodes added and tested
2. Workflow activated
3. Report success to user
| Operation | Method | Endpoint |
|---|---|---|
| Create | POST | /api/v1/workflows |
| Update | PUT | /api/v1/workflows/{id} |
| Activate | POST | /api/v1/workflows/{id}/activate |
| Deactivate | POST | /api/v1/workflows/{id}/deactivate |
| Delete | DELETE | /api/v1/workflows/{id} |
| Execute | POST | /webhook/{path} |
CRITICAL RULES:
\ line continuations - Causes errorsGET:
export $(cat .env | grep -v '^#' | xargs) && curl -s "${N8N_API_URL}/api/v1/ENDPOINT" -H "X-N8N-API-KEY: ${N8N_API_KEY}" | jq .
POST/PUT (large JSON):
export $(cat .env | grep -v '^#' | xargs) && curl -s -X POST "${N8N_API_URL}/api/v1/workflows" -H "X-N8N-API-KEY: ${N8N_API_KEY}" -H "Content-Type: application/json" -d "$(cat <<'EOF'
{
"name": "My Workflow",
"nodes": [...],
"connections": {},
"settings": {"executionOrder": "v1"}
}
EOF
)"
{
"name": "Workflow Name",
"nodes": [
{
"id": "unique-node-id",
"name": "Node Display Name",
"type": "n8n-nodes-base.nodeName",
"typeVersion": 1,
"position": [250, 300],
"parameters": {},
"credentials": {}
}
],
"connections": {
"Source Node Name": {
"main": [[{"node": "Target Node Name", "type": "main", "index": 0}]]
}
},
"settings": {"executionOrder": "v1"}
}
Read these files as needed using the Read tool:
| File | Contents |
|---|---|
| references/api-reference.md | All API commands (CRUD, executions, tags, variables) |
| references/build-process.md | Step-by-step build-test workflow |
| references/pitfalls.md | CRITICAL: Command format rules, common mistakes |
| File | Contents |
|---|---|
| references/triggers.md | Webhook, Schedule, Form, Chat, and service triggers |
| references/ai-nodes.md | AI Agent, OpenAI/Anthropic Chat Models, Memory, Vector Store |
| references/data-nodes.md | Google Sheets, Airtable, Notion, Postgres, Slack, Gmail, etc. |
| references/transform-nodes.md | Set, If, Switch, Filter, Merge, Code, HTTP Request, Loops |
| File | Contents |
|---|---|
| references/javascript.md | JavaScript patterns for Code nodes |
| references/python.md | Python patterns for Code nodes |
| references/node-config.md | Node configurations and workflow patterns |
| references/expressions.md | Expression syntax ({{ $json.field }}) |
| references/credentials.md | Credential template usage |
Before adding ANY node:
1. Read the relevant reference file (triggers.md, ai-nodes.md, etc.)
2. Check if node is in credentials template
3. Get correct typeVersion and parameters
4. If DATABASE node -> FETCH SCHEMA first
5. Add node with correct config
// Webhook body (CRITICAL - data is under .body!)
{{ $json.body.fieldName }}
// Other node reference
{{ $('Node Name').item.json.field }}
// Default value
{{ $json.field ?? 'default' }}
// Safe access
{{ $json.obj?.nested?.field }}
// Current date
{{ $now.toFormat('yyyy-MM-dd') }}
In Code nodes, use plain JavaScript - NOT {{ }}:
const data = $input.first().json.body;
return [{ json: { result: data.fieldName } }];
// Input access
const items = $input.all();
const first = $input.first().json;
// Other nodes
const data = $('Node Name').first().json;
// Return (MUST be array with json key)
return [{ json: { result: 'value' } }];
# Input access
items = _input.all()
first = _input.first().json
# Return (MUST be list)
return [{"json": {"result": "value"}}]
# 1. Activate
curl -X POST "${N8N_API_URL}/api/v1/workflows/{id}/activate"
# 2. Execute
curl -X POST "${N8N_API_URL}/webhook/{path}" -d '{}'
# 3. Check status
curl "${N8N_API_URL}/api/v1/executions?limit=1" | jq '.data[0].status'
# 4. Verify node ran
curl "${N8N_API_URL}/api/v1/executions/{id}?includeData=true" | jq '.data.resultData.runData | keys'
Do NOT proceed until status = "success" and new node appears in runData.
After all nodes are built and tested, output a structured summary:
─────────────────────────────────────────────
BUILD COMPLETE — <Project Name>
─────────────────────────────────────────────
Workflow: <workflow name>
Status: Active
URL: https://pattern.app.n8n.cloud/workflow/<id>
Nodes built and tested:
✓ [Trigger type] — working
✓ [Node 2 name] — working (N results)
✓ [Node 3 name] — working
...
Output: <what was created/sent/updated>
─────────────────────────────────────────────
If any node requires manual configuration in the UI:
Manual setup required:
• [Node name]: [exactly what the user needs to do in the UI]
After reporting build complete, always ask about error handling using AskUserQuestion:
First question:
Question: "Do you want to add error handling to this workflow?"
Header: "Error Handling"
Options:
- "Yes — attach an existing error workflow"
- "Yes — create a new error workflow for this project"
- "No — skip for now"
If "attach an existing error workflow":
# Update workflow settings to attach error workflow
PUT /api/v1/workflows/{id}
# Set settings.errorWorkflow to the error workflow ID
<name> attached."If "create a new error workflow":
Question: "How should the error alert be sent?"
Header: "Alert Channel"
Options:
- "Slack"
- "Gmail"
- "Both Slack and Gmail"
n8n-nodes-base.errorTrigger)❌ Workflow Error: {{ $json.workflow.name }}
Error: {{ $json.execution.error.message }}
Execution: https://pattern.app.n8n.cloud/execution/{{ $json.execution.id }}
If "skip for now":
After build complete and error handling decision, output:
─────────────────────────────────────────────
DONE — <Project Name> is live on Pattern n8n
Update your CLAUDE.md status checklist:
✓ Workflow built and tested
✓ Error handling: <added / skipped>
□ Stakeholder review
□ Activated in production (if not already)
□ Documentation complete
─────────────────────────────────────────────