n8n_generate_workflow
Generate n8n workflow JSON from plain-English descriptions, supporting triggers, common action nodes, and AI agent setups.
Instructions
Generate a valid n8n workflow JSON from a plain-English description. Handles webhook/schedule/RSS triggers, common action nodes (Slack, Google Sheets, Discord, Gmail, Notion, HTTP), and AI Agent setups (LangChain root agent + chat model + memory + optional HTTP tool, wired with ai_languageModel / ai_memory / ai_tool connections). Returns workflow JSON with unique node IDs, connections, positions, and typeVersion on every node.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| description | Yes | Plain-English workflow description, e.g. 'Stripe webhook -> Slack message + Google Sheets row'. | |
| name | No | Optional workflow name. Derived from the first sentence of the description if omitted. |
Implementation Reference
- src/tools/generate-workflow.ts:209-282 (handler)Main handler function for n8n_generate_workflow. Parses input, detects triggers/actions via regex patterns, builds workflow JSON, and returns it.
export async function generateWorkflow(rawArgs: unknown) { const args = inputZod.parse(rawArgs); if (AI_AGENT_PATTERN.test(args.description)) { return buildAiAgentWorkflow(args); } let trigger: NodeSpec | null = null; for (const p of TRIGGER_PATTERNS) { if (p.match.test(args.description)) { trigger = p.build(); break; } } if (!trigger) { trigger = { id: randomUUID(), name: "Manual Trigger", type: "n8n-nodes-base.manualTrigger", typeVersion: 1, position: [240, 300], parameters: {}, }; } const actions: NodeSpec[] = []; let slot = 0; for (const p of ACTION_PATTERNS) { if (p.match.test(args.description)) { actions.push(p.build(slot++)); } } if (actions.length === 0) { actions.push({ id: randomUUID(), name: "HTTP Request", type: "n8n-nodes-base.httpRequest", typeVersion: 4.2, position: [560, 300], parameters: { method: "POST", url: "https://example.com/api", sendBody: true, bodyParameters: { parameters: [] }, options: {}, }, }); } const nodes = [trigger, ...actions]; const connections: Record<string, { main: MainConnection[][] }> = { [trigger.name]: { main: [ actions.map((a) => ({ node: a.name, type: "main" as const, index: 0 })), ], }, }; const workflow = { name: args.name ?? deriveName(args.description), nodes, connections, active: false, settings: { executionOrder: "v1" }, pinData: {}, }; return { content: [ { type: "text" as const, text: JSON.stringify(workflow, null, 2) }, ], }; } - Helper that builds an AI Agent workflow (chat trigger + agent + chat model + memory + optional HTTP tool) when the description mentions AI/LLM/chatbot.
function buildAiAgentWorkflow(args: { description: string; name?: string }) { const trigger: NodeSpec = { id: randomUUID(), name: "When chat message received", type: "@n8n/n8n-nodes-langchain.chatTrigger", typeVersion: 1.1, position: [240, 300], parameters: { options: {} }, }; const agent: NodeSpec = { id: randomUUID(), name: "AI Agent", type: "@n8n/n8n-nodes-langchain.agent", typeVersion: 1.7, position: [480, 300], parameters: { options: {} }, }; const chatModel: NodeSpec = { id: randomUUID(), name: "OpenAI Chat Model", type: "@n8n/n8n-nodes-langchain.lmChatOpenAi", typeVersion: 1.2, position: [400, 480], parameters: { model: { __rl: true, mode: "list", value: "gpt-4o-mini" }, options: {}, }, }; const memory: NodeSpec = { id: randomUUID(), name: "Window Buffer Memory", type: "@n8n/n8n-nodes-langchain.memoryBufferWindow", typeVersion: 1.3, position: [560, 480], parameters: {}, }; const nodes: NodeSpec[] = [trigger, agent, chatModel, memory]; const connections: Record<string, Record<string, WireConnection[][]>> = { [trigger.name]: { main: [[{ node: agent.name, type: "main", index: 0 }]], }, [chatModel.name]: { ai_languageModel: [ [{ node: agent.name, type: "ai_languageModel", index: 0 }], ], }, [memory.name]: { ai_memory: [[{ node: agent.name, type: "ai_memory", index: 0 }]], }, }; if (/\b(http|api|tool|fetch)\b/i.test(args.description)) { const httpTool: NodeSpec = { id: randomUUID(), name: "HTTP Request Tool", type: "@n8n/n8n-nodes-langchain.toolHttpRequest", typeVersion: 1.1, position: [720, 480], parameters: { toolDescription: "Call an external HTTP API. Replace the URL and parameters before running.", url: "https://example.com/api", method: "GET", sendBody: false, }, }; nodes.push(httpTool); connections[httpTool.name] = { ai_tool: [[{ node: agent.name, type: "ai_tool", index: 0 }]], }; } const workflow = { name: args.name ?? deriveName(args.description), nodes, connections, active: false, settings: { executionOrder: "v1" }, pinData: {}, }; return { content: [ { type: "text" as const, text: JSON.stringify(workflow, null, 2) }, ], }; } - src/tools/generate-workflow.ts:4-19 (schema)Input schema for n8n_generate_workflow: requires 'description' (string) and optional 'name' (string).
export const generateWorkflowInputSchema = { type: "object", properties: { description: { type: "string", description: "Plain-English workflow description, e.g. 'Stripe webhook -> Slack message + Google Sheets row'.", }, name: { type: "string", description: "Optional workflow name. Derived from the first sentence of the description if omitted.", }, }, required: ["description"], } as const; - src/index.ts:46-51 (registration)Registration of the tool with name 'n8n_generate_workflow', description, and input schema.
{ name: "n8n_generate_workflow", description: "Generate a valid n8n workflow JSON from a plain-English description. Handles webhook/schedule/RSS triggers, common action nodes (Slack, Google Sheets, Discord, Gmail, Notion, HTTP), and AI Agent setups (LangChain root agent + chat model + memory + optional HTTP tool, wired with ai_languageModel / ai_memory / ai_tool connections). Returns workflow JSON with unique node IDs, connections, positions, and typeVersion on every node.", inputSchema: generateWorkflowInputSchema, }, - src/index.ts:113-114 (registration)Handler dispatch: routes the 'n8n_generate_workflow' tool call to the generateWorkflow function.
case "n8n_generate_workflow": return generateWorkflow(args ?? {});