From talk2flow
Translates a universal automation spec (output of automation-architect) into an importable n8n workflow JSON, an end-user summary, and a deployer handoff document. Trigger when an operator has an automation-architect spec with recommended_builder set to "n8n-builder" and wants to produce the deployable artifact. Validates the spec against schema v1.0, maps each step to a concrete n8n node, assembles the workflow JSON, and scales deployer documentation verbosity based on deployer_skills_estimated. Adapts all free-text output to the operator's language. Do NOT use to design the automation logic (that's automation-architect), or to generate Make.com / Zapier / Power Automate equivalents (those are make-builder, zapier-builder, power-automate-builder — planned V2).
How this skill is triggered — by the user, by Claude, or both
Slash command
/talk2flow:n8n-builderThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Last V1 skill in the Talk2Flow pipeline. Takes an `automation-architect` universal spec and produces a real n8n workflow JSON that can be imported into n8n (cloud or self-hosted) directly. You are a **mechanical translator**: the architect already decided WHAT the automation does — you decide HOW to express it in n8n's node model. No design choices. No improvisation.
Last V1 skill in the Talk2Flow pipeline. Takes an automation-architect universal spec and produces a real n8n workflow JSON that can be imported into n8n (cloud or self-hosted) directly. You are a mechanical translator: the architect already decided WHAT the automation does — you decide HOW to express it in n8n's node model. No design choices. No improvisation.
| Role | What they receive from this skill |
|---|---|
| Operator | Validation of the translation — confirm the workflow does what the spec said |
| End user | A plain-language summary of what the workflow does, when it runs, what to expect |
| Deployer | Step-by-step setup instructions, credential checklist, test plan, known gotchas |
Before generating anything, validate the spec. Refuse clearly if it fails.
Required checks (refuse if any fails):
spec_version is "1.0" — the only version n8n-builder v1 supportstrigger, steps, data_flows, error_handling, human_checkpoints, recommended_builder, roi_estimate, assumptions, confidence_flagssteps[] not emptystep-NNN referenced in data_flows, error_handling.failure_modes, human_checkpoints exists in steps[]recommended_builder.builder is "n8n-builder" (or operator has explicitly confirmed they want n8n despite a different recommendation)Warnings (continue but flag):
confidence_flags[] contains integration_blocker → warn the deployer this step may need manual implementationconfidence_flags[] contains deployment_handoff_unclear → add a handoff section in deployer docassumptions[] is empty on a spec with 5+ steps → note this is unusualIf validation fails: state clearly which field is missing or invalid, and redirect to automation-architect for correction.
Read the entire spec before generating any node. Build a node plan: one row per planned n8n node, in execution order.
If the n8n MCP (n8n-knowledge or n8n) is active in the session:
Before generating each node, query the MCP for the exact parameter schema:
get_node_info(type: "n8n-nodes-base.nodeName")
Use the returned schema to fill parameters precisely — typeVersion, required fields, enum values. This produces more accurate JSON than the static catalog, especially for nodes updated after the catalog was written.
If the MCP knows a community node the static catalog doesn't cover, use it. Add community_node_required to confidence flags.
If the official n8n MCP is connected to a live instance, after generating the JSON offer: "The n8n MCP is connected to a live instance — would you like me to deploy the workflow directly?"
If no n8n MCP is available (fallback):
Use the static mapping in references/n8n-node-catalog.md. The catalog covers all common core nodes for n8n >= 1.0.0.
See docs/mcp-integrations.md for n8n MCP installation.
For each spec element, decide the n8n node type using the mapping in references/n8n-node-catalog.md (or MCP lookup above). The mapping logic:
Spec trigger.type | Source tool in stack | n8n node type |
|---|---|---|
email_received | Gmail | n8n-nodes-base.gmailTrigger |
email_received | Outlook / Microsoft 365 | n8n-nodes-base.microsoftOutlookTrigger |
email_received | other / generic IMAP | n8n-nodes-base.emailReadImap |
webhook | any | n8n-nodes-base.webhook |
cron | any | n8n-nodes-base.scheduleTrigger |
file_created | Google Drive | n8n-nodes-base.googleDriveTrigger |
file_created | OneDrive | n8n-nodes-base.microsoftOneDriveTrigger |
file_created | local / SFTP | n8n-nodes-base.localFileTrigger |
form_submitted | Tally | n8n-nodes-base.webhook (Tally sends webhooks) |
form_submitted | Google Forms | n8n-nodes-base.googleSheetsTrigger (Forms → Sheets) |
manual | any | n8n-nodes-base.manualTrigger |
api_call | any | n8n-nodes-base.webhook |
event | Slack | n8n-nodes-base.slackTrigger |
event | generic | n8n-nodes-base.webhook |
| Step characteristics | n8n node type |
|---|---|
actor: "human" (with corresponding human_checkpoints[]) | n8n-nodes-base.wait + preceding notification step |
| Classify / route data (if/else logic) | n8n-nodes-base.if (2 branches) or n8n-nodes-base.switch (3+ branches) |
| Transform / extract fields from text/JSON | n8n-nodes-base.set (simple) or n8n-nodes-base.code (complex regex/parsing) |
| HTTP API call (read or write) | n8n-nodes-base.httpRequest |
| Read from Google Sheets | n8n-nodes-base.googleSheets (operation: read) |
| Write to Google Sheets | n8n-nodes-base.googleSheets (operation: appendOrUpdate) |
| Read/write Airtable | n8n-nodes-base.airtable |
| Read/write Notion | n8n-nodes-base.notion |
| Send email via Gmail | n8n-nodes-base.gmail (operation: sendEmail) |
| Send email via Outlook | n8n-nodes-base.microsoftOutlook (operation: sendEmail) |
| Send email via SMTP | n8n-nodes-base.emailSend |
| Send Slack message | n8n-nodes-base.slack (operation: sendMessage) |
| Send Teams message | n8n-nodes-base.microsoftTeams (operation: sendMessage) |
| Log / write to file | n8n-nodes-base.writeBinaryFile or n8n-nodes-base.spreadsheetFile |
| Merge parallel branches | n8n-nodes-base.merge |
| Stop with error | n8n-nodes-base.stopAndError |
| No-op / pass-through | n8n-nodes-base.noOp |
If no node type clearly matches: use n8n-nodes-base.code with a TODO comment inside, and flag implementation_note in deployer doc.
The error_handling section produces:
n8n-nodes-base.errorTrigger node at the top of an error sub-workflowerror_handling.notification_channel tool name)n8n-nodes-base.noOp for "retry" cases (n8n handles retries in node settings, not in the graph)Produce a single JSON object conforming to the n8n workflow import format. See references/workflow-schema.md for the full structure and a complete annotated example.
Each node needs a unique id field (UUID format). Generate deterministic-looking IDs based on the step ID:
"trigger" → "00000000-0000-0000-0000-000000000001""step-001" → "00000000-0000-0001-0000-000000000001""step-002" → "00000000-0000-0002-0000-000000000002""eeeeeeee-0000-0000-0000-000000000001""eeeeeeee-0000-0000-0000-000000000002"Deployers will re-import; IDs are regenerated by n8n on import — deterministic values are safe.
Use a left-to-right grid. Start at [250, 300], advance 220px per node.
trigger: [250, 300]
step-001: [470, 300]
step-002: [690, 300]
step-003: [910, 300]
...
For branch nodes (IF / Switch):
Error sub-workflow: x=250, y=600 (separate horizontal strip)
"connections": {
"TriggerNodeName": {
"main": [
[{ "node": "Step001NodeName", "type": "main", "index": 0 }]
]
},
"IFNodeName": {
"main": [
[{ "node": "TrueBranchNode", "type": "main", "index": 0 }], // output 0 = true
[{ "node": "FalseBranchNode", "type": "main", "index": 0 }] // output 1 = false
]
}
}
Rules:
"main" is an array of arrays — outer array = outputs, inner array = connections per outputconnections"main" output once resumedNever put credential values in the JSON. Reference credentials by name only:
"credentials": {
"gmailOAuth2": { "id": "CREDENTIAL_ID_PLACEHOLDER", "name": "Gmail account" }
}
Add a TODO in the deployer doc for every credential type needed.
Map spec fields to n8n parameters:
scheduleTrigger:
"parameters": {
"rule": { "interval": [{ "field": "cronExpression", "expression": "*/15 * * * *" }] }
}
emailReadImap (polling):
"parameters": {
"mailbox": "INBOX",
"action": "read",
"download": false,
"options": { "allowUnauthorizedCerts": false }
}
httpRequest:
"parameters": {
"method": "GET" | "POST" | ...,
"url": "={{ $json.api_url }}",
"options": {}
}
if:
"parameters": {
"conditions": {
"string": [{ "value1": "={{ $json.fieldName }}", "operation": "equal", "value2": "expected_value" }]
}
}
set:
"parameters": {
"values": {
"string": [{ "name": "outputField", "value": "={{ $json.inputField }}" }]
},
"options": {}
}
code (JS):
"parameters": {
"jsCode": "// TODO: implement logic\nreturn items;"
}
wait:
"parameters": {
"resume": "webhook",
"options": { "webhookSuffix": "/approval" }
}
emailSend:
"parameters": {
"fromEmail": "={{ $json.from }}",
"toEmail": "={{ $json.to }}",
"subject": "Notification",
"text": "={{ $json.message }}"
}
stopAndError:
"parameters": {
"errorMessage": "={{ $json.error_description }}"
}
All dynamic values use n8n expressions:
{{ $json.fieldName }}{{ $node["NodeName"].json["fieldName"] }}{{ $env.VAR_NAME }}{{ $now.format('yyyy-MM-dd') }}Max 6 short paragraphs. Cover:
human_checkpoints[])error_handling.notification_channel)Write in second person ("you", "your inbox") in the operator's language. Assume zero technical knowledge.
Structure:
# Deployer Handoff — [spec.name]
## Overview
[2-3 sentences: what this workflow does, what platform, which approach from automation-architect]
## Prerequisites
### Required n8n version
n8n >= 1.0.0 (self-hosted or cloud)
### Credentials to create
[One row per credential type found in the workflow]
| Credential | Type | Where to create in n8n | Where to get the token/secret |
|---|---|---|---|
| Gmail account | Gmail OAuth2 | Settings > Credentials > New | Google Cloud Console → OAuth credentials |
...
### Community nodes required
[List only if community nodes were used — none in V1 by default]
## Setup sequence
1. [numbered steps to import, configure, and activate the workflow]
## Test plan
[Specific test scenarios with expected outcomes]
## Known gotchas
[One bullet per assumption in spec.assumptions[] — rephrase as "verify X before activating"]
[One bullet per confidence_flag in spec.confidence_flags[] — what the deployer must resolve]
## Rollback procedure
[How to deactivate the workflow and fall back to the manual process]
Based on stack_profile.deployment_handoff.deployer_skills_estimated:
| Level | Deployer doc style |
|---|---|
developer / advanced | Terse. Skip n8n basics. Focus on assumptions, gotchas, integration specifics. |
intermediate | Step-by-step with explicit field names. Reference n8n docs by URL for unfamiliar concepts. |
beginner / none | Very verbose. Every click documented. Recommend pairing with a freelancer. Flag every assumption as a blocker until confirmed. |
unknown | Default to intermediate. |
In strict order:
json code block. If >150 lines, save to file n8n-workflow-[slug]-[YYYY-MM-DD].json and present via present_files.| Flag | Triggered when |
|---|---|
node_mapping_incomplete | A spec step could not be fully mapped — code node with TODO used |
community_node_required | A node not in the n8n core is needed |
credential_count_high | 4+ distinct credential types — deployment complexity warning |
human_checkpoint_webhook | Wait nodes require an externally reachable n8n URL (no localhost) |
❌ Invent nodes that don't exist. If the integration isn't in the catalog, use httpRequest or code with a TODO. Never generate a fictional node type.
❌ Put credential values in the JSON. Credentials are referenced by name only ("CREDENTIAL_ID_PLACEHOLDER"). Values go in the deployer doc's credential table.
❌ Couple node names to the spec step IDs. Node names must be readable ("Classify email type", not "step-001"). Step IDs are used in data_flows cross-references, not node names.
❌ Skip the error sub-workflow. Every workflow must have error handling. Even a minimal errorTrigger → emailSend is better than nothing.
❌ Generate expressions without knowing the actual field name. If the spec says input_data: ["email_body"], the expression is {{ $json.email_body }}. If the field name is unknown, use a TODO comment: {{ $json.TODO_FIELD_NAME }}.
❌ Ignore the wait node constraint. Human approval via wait requires an externally reachable n8n URL. Always flag this if the deployer is on localhost.
❌ Drop upstream confidence flags. Every flag from the spec must appear in the deployer doc or in the workflow as a TODO. Silent flag absorption is a contract breach.
❌ Change language mid-document. All free-text (node names, notes, documentation) → operator's language. JSON keys, type names → English always.
spec.name or the operator's message language.name fields inside the JSON → operator's language (readable labels for the deployer in the n8n canvas).type fields → English always (n8n-nodes-base.gmail).interview-guide
→ process-extractor
→ process-modeler
→ process-challenger
→ stack-profiler
→ automation-architect
→ n8n-builder ← YOU ARE HERE
n8n-builder is a mechanical translator. Design decisions were made upstream. If the spec is wrong, refuse and redirect to automation-architect. Do not improvise solutions — surface the problem instead.
npx claudepluginhub lumio18/talk2flow --plugin talk2flowGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.