The setup I'm targeting looks like this. n8n runs on a small Hetzner box at https://n8n.example.com with API access enabled. Claude Code runs on my laptop. In between sits a tiny MCP server that speaks JSON-RPC over stdio to Claude Code and HTTPS to n8n's REST API. When I type a natural-language request, Claude picks the right n8n workflow, fills in the inputs, and pipes the result back into the conversation. Crucially I want each n8n workflow to show up as a distinct named tool, not a single generic run_workflow blob, because the model behaves dramatically better when tool names and schemas are specific.
There are a few community MCP servers for n8n on GitHub already. I tried two of them and both worked, but the one I ended up shipping was the n8n-mcp package because it auto-generates tool schemas from each workflow's input parameters. It's published on npm and you can read the source at github.com/leonardsellem/n8n-mcp-server. The maintainer has been responsive about issues, which matters in this part of the ecosystem where projects evaporate quickly.
Installing and configuring the MCP server
First, get a personal API key from n8n. Open your n8n instance, go to Settings then n8n API, and click Create an API key. Copy it somewhere safe; you can't view it again. While you're there, scope the key to the minimum permissions you need. For a tool that only triggers workflows, you want workflow read and workflow execute; you almost certainly don't want user management or credential read.
Next, install the server globally with npm so Claude Code can spawn it without a build step every time:
npm install -g n8n-mcp-server@latest
# I pinned to 0.4.3 because 0.5.0 changed the tool naming
# convention in a way that broke my existing prompts.
Now register it with Claude Code. The cleanest way as of the 2.x releases is the claude mcp add CLI, which writes to the right config file for your platform without you having to remember whether it lives in ~/.config/claude or ~/Library/Application Support/Claude:
claude mcp add n8n \
--command npx \
--args n8n-mcp-server \
--env N8N_API_URL=https://n8n.example.com/api/v1 \
--env N8N_API_KEY=eyJhbGciOi... \
--env N8N_WEBHOOK_USERNAME=mcp \
--env N8N_WEBHOOK_PASSWORD=$(security find-generic-password -s n8n-webhook -w)
A few things worth pointing out in that command. The N8N_API_URL must end with /api/v1 — the server doesn't append it for you, and the error message you get when you forget is a generic 404 that sent me down a Cloudflare rabbit hole the first time. I'm pulling the webhook password out of macOS Keychain rather than putting it in shell history. If you're on Linux, swap security find-generic-password for secret-tool lookup or your password manager of choice. Never paste an API key directly into a config file that might end up in dotfiles git.
If you prefer editing the config by hand, on macOS it lives at ~/Library/Application Support/Claude/claude_desktop_config.json and the MCP section looks like this:
{
"mcpServers": {
"n8n": {
"command": "npx",
"args": ["n8n-mcp-server"],
"env": {
"N8N_API_URL": "https://n8n.example.com/api/v1",
"N8N_API_KEY": "eyJhbGciOi...",
"N8N_WEBHOOK_USERNAME": "mcp",
"N8N_WEBHOOK_PASSWORD": "redacted"
}
}
}
}
Restart Claude Code with claude in a new terminal, then run /mcp inside the session. You should see the n8n server listed with a green dot and a count of available tools. On my client's machine it found 14 tools the first time, one per active workflow, named things like n8n_workflow_notion_to_linear_sync and n8n_workflow_weekly_blog_digest.
Registering specific workflows as individual tools
By default the server exposes every active workflow as a tool. That's fine if you have five workflows. It's awful if you have eighty, because Claude has to read every tool definition into its context window on every turn and you'll burn through tokens fast. The fix is to set N8N_WORKFLOW_ALLOWLIST to a comma-separated list of workflow IDs you actually want exposed:
claude mcp update n8n \
--env N8N_WORKFLOW_ALLOWLIST=42,57,113,209
For each allowlisted workflow, the server reads its Webhook trigger node (or Execute Workflow trigger node — both work) and generates a JSON Schema from the input fields. This is the magic that makes the experience actually pleasant: if your workflow takes a customer_email string and an urgency enum, Claude sees that and constructs valid arguments instead of guessing.
To make this work well, take five minutes to annotate your workflow inputs. In n8n's Webhook node, click each parameter and fill in the Description field. The MCP server passes those descriptions straight through to the tool schema and they massively improve the model's ability to pick the right tool. I'd much rather write a one-sentence description than spend a week debugging why Claude keeps calling the wrong workflow.
Here's a minimal example of what a well-described workflow input looks like, exported from n8n:
{
"parameters": {
"httpMethod": "POST",
"path": "notion-to-linear-sync",
"responseMode": "lastNode",
"options": {},
"bodyParameters": [
{
"name": "notion_database_id",
"type": "string",
"description": "Source Notion database UUID. Found in the URL after the workspace slug."
},
{
"name": "linear_team_key",
"type": "string",
"description": "Target Linear team key (e.g. ENG, DES). Case sensitive."
},
{
"name": "dry_run",
"type": "boolean",
"description": "If true, log proposed changes without creating Linear issues. Default false."
}
]
}
}
Debugging the handshake when nothing shows up
If you restart Claude Code and /mcp shows the n8n server in a red error state, you're now in the part of the article I really wrote this for. The MCP stdio handshake is unforgiving and the failure modes are bizarrely diverse. Here's the checklist I run through, in roughly the order that's saved me the most time.
First, check that npx n8n-mcp-server runs at all in a clean shell. If npx tries to download the package and fails — corporate proxy, expired npm registry token, anything — Claude Code just sees a process that died before writing the initial handshake and reports a vague "server failed to start". On the Windows machine I was debugging, the actual problem was that the user's NODE_EXTRA_CA_CERTS wasn't being inherited by the Claude Code subprocess. Setting it explicitly in the env block of the MCP config fixed it instantly.
Second, look at the logs. Claude Code writes per-server MCP logs to ~/Library/Logs/Claude/mcp-server-n8n.log on macOS, and the equivalent %APPDATA%\Claude\logs\ path on Windows. Microsoft's debugging guide for VS Code's MCP integration is also a useful reference because it covers stdio framing issues that aren't specific to either client — see code.visualstudio.com/docs/copilot/customization/mcp-servers. The single most common error in those logs is malformed JSON-RPC, which almost always means the server wrote something to stdout that wasn't a protocol message. The fix is to make sure nothing in your environment is patching console.log in a way that leaks into stdout — I've seen Sentry's auto-instrumentation cause exactly this.
Third, if the server starts but tools don't appear, hit n8n's API directly with curl using the same key and URL the MCP server is using:
curl -H "X-N8N-API-KEY: $N8N_API_KEY" \
"https://n8n.example.com/api/v1/workflows?active=true" | jq '.data | length'
If that returns 0, your problem isn't MCP at all — it's that none of your workflows are flagged active, or your API key doesn't have permission to list them, or you're hitting the wrong tenant. The n8n API reference at docs.n8n.io/api/api-reference is the source of truth for the response shape and error codes.
Fourth, watch out for the Node version requirement. As of n8n-mcp-server 0.4.3 the minimum Node version is 20.10. I had a colleague on Node 18 who got a cryptic SyntaxError at startup; bumping to Node 22 via nvm fixed it. The package's engines field really should warn earlier, but it doesn't, so this stays a footgun.
Real-world caveats I wish someone had told me
Once everything is working, a few things will surprise you.
Workflow execution is synchronous from the MCP server's perspective. If your n8n workflow takes 90 seconds to run, Claude Code will sit there spinning for 90 seconds, and there's no streaming progress indicator. For anything longer than a few seconds I now structure the workflow as fire-and-forget: the MCP-triggered workflow enqueues the real work and returns immediately with a job ID, then a second tool lets Claude poll the status. The user experience is dramatically better.
Webhook authentication is separate from API authentication, and both can bite you. The n8n API key authorizes the MCP server to list and trigger workflows; the webhook username and password (or header auth, if you prefer) authorize the actual HTTP call into the webhook node. If you skip N8N_WEBHOOK_USERNAME and your workflow's webhook node requires basic auth, you'll get a 401 with no clear signal that it's a webhook-level rather than API-level rejection.
Tool descriptions get cached. If you edit a workflow's name or input descriptions in n8n, you need to either restart Claude Code or run /mcp reload n8n in the chat — and that command only landed in 2.3, so older versions need a full restart. I rebooted Claude four times before figuring this out the first day.
Finally, think hard about the security posture before you turn this on for a team. Giving an LLM the ability to trigger workflows that send emails, create Linear issues, or move money is a meaningful expansion of your blast radius. I require human-in-the-loop confirmation for any tool that mutates external state — Claude Code's tool-permission prompts handle this natively, and you can configure default-deny per tool in your settings.json. Worth a few minutes of careful reading. For a deeper take on this trade-off see my piece on letting LLMs trigger real workflows safely and the broader pattern in MCP server design patterns for internal tools.
Frequently asked questions
Do I need n8n Cloud or can I use a self-hosted instance?
Both work. The MCP server just speaks to the standard n8n REST API, which is identical on Cloud and self-hosted. The only practical difference is that self-hosted instances often run behind a corporate proxy or VPN, and the MCP server's HTTP client honors HTTPS_PROXY and NO_PROXY environment variables the way you'd expect.
Can I use this with Claude Desktop instead of Claude Code?
Yes, the MCP configuration is essentially the same. The config file location differs (Claude Desktop uses claude_desktop_config.json, Claude Code looks at slightly different paths depending on platform), but the mcpServers block is portable. I run the same n8n server registered against both clients on my main machine and they share zero state, which is fine.
How do I prevent Claude from invoking destructive workflows by accident?
Two layers. First, in n8n itself, gate destructive workflows behind a confirmation parameter that Claude has to set explicitly — something like a required confirm_destructive: "yes-delete-everything" input. Second, in Claude Code's settings.json, set the tool to require approval on every invocation rather than being auto-approved. Belt and braces.
What happens if n8n is down when Claude tries to invoke a tool?
The MCP server returns a JSON-RPC error response with the underlying HTTP status, and Claude surfaces it in the chat as a tool error. The model usually does the right thing — it tells you n8n appears to be unreachable and asks if you want to try something else. If you want more graceful behavior, you can wrap each n8n workflow in a small health-check tool and instruct Claude in your system prompt to call it first when something fails.
Wrapping up
The first time I got an n8n workflow firing from a Claude Code chat I genuinely laughed out loud at how natural it felt. Twenty minutes of setup turned a tool the team was avoiding into something they use dozens of times a day. The hard part isn't the MCP plumbing — that's well-trodden ground now — it's the discipline of writing clear input descriptions, scoping API keys properly, and building workflows that behave well when an LLM is the one filling in the parameters. Get those three things right and you'll wonder how you worked any other way. If you hit something I didn't cover, the n8n community forum and the MCP GitHub discussions are both unusually responsive in 2026.