How to connect Claude Desktop to a self-hosted n8n
Self-hosted n8n doesn't connect to Claude Desktop out of the box — OAuth is broken, and the config file doesn't support HTTP servers. This walkthrough covers the full setup: Cloudflare Tunnel, environment variables, supergateway as a stdio-to-HTTP bridge, and triggering workflows via MCP.
I wanted Claude to trigger my n8n automations. The docs make it look like a five-minute job, but it took me an evening of trial and error before everything worked. Here's the walkthrough so you don't have to repeat my mistakes.
What we are building
The goal: run a scheduled task of making a weekly news digest and publish it to my social networks by running n8n workflow.
I'm using self-hosted Community Edition of n8n to avoid limits and without paying for usage.
The setup
- macOS with Claude Desktop
- n8n community edition, self-hosted (Docker)
- A domain you control (I used a subdomain
n8n.yourdomain.com)
Step 1: Make n8n reachable from the??internet
Claude Desktop needs to reach your n8n instance over HTTPS. If n8n runs on localhost:5678, that's not going to work on its own. Self-hosted n8n also needs to run behind a custom domain to support web hooks to make third-party services be able to call your webhooks.
I went with Cloudflare Tunnel because it's free, gives you a permanent URL on your own domain, and doesn't require opening ports on your router.
Install cloudflared:
brew install cloudflaredAuthenticate and create a tunnel:
cloudflared tunnel login
cloudflared tunnel create n8n-tunnelThen configure it to route your subdomain to localhost:5678. Once it's running, https://n8n.yourdomain.com should load your n8n interface.
Step 2: Tell n8n about its public??address
This one tripped me up: after setting up the tunnel, n8n still thought it lived at localhost:5678. The MCP settings page showed the server URL as https://n8n.yourdomain.com:5678/mcp-server/http with the port number baked in. Claude couldn't connect to that because Cloudflare Tunnel serves traffic on standard port 443, not 5678.
The fix: set environment variables so n8n knows its public identity.
If you use Docker, add these to your environment section:
environment:
- WEBHOOK_URL=https://n8n.yourdomain.com
- N8N_HOST=n8n.yourdomain.com
- N8N_PROTOCOL=https
- N8N_EDITOR_BASE_URL=https://n8n.yourdomain.comI asked Docker's Gordon AI assistant to do that and was impressed by how easy it was. It added env variables and restarted the container.
Go to Settings > Instance-level MCP and toggle it on.
Open Connection details (button in the top-right corner). The server URL should now show https://n8n.yourdomain.com/mcp-server/http no port.
In the same Connection details open Access Token tab. Generate a token and copy it — you won't be able to see it again later.
Step 3: Connect Claude Desktop
In n8n go to Settings > Instance-level MCP and mark at least one workflow as MCP-accessible. You can also do it from workflow's settings (toggle "Available in MCP"). Note that to be available for execution the workflow must be published, not a draft.
Here's where things got interesting. There are two ways to connect, and only one of them worked for me.
What didn't work: the Connectors UI
Claude Desktop has a nice Settings > Connectors panel where you can add MCP servers. n8n even shows up in the marketplace. You paste your URL, it opens an OAuth flow, n8n says "Succeed" and Claude returns "Authorization with the MCP server failed."
I tried everything: fixed the base URLs, verified the OAuth endpoint responds correctly (curl https://n8n.yourdomain.com/.well-known/oauth-authorization-server returns valid JSON), checked for Cloudflare Access policies. Nothing helped.
This turns out to be a known bug with self-hosted n8n instances. It's been reported on GitHub and the n8n community forum. The OAuth handshake completes on n8n's side, but Claude rejects the token. As of early 2026, it's still not fixed.
What worked: supergateway + config??file
The claude_desktop_config.json file lets you define MCP servers that run as local processes. The problem is that n8n's MCP server speaks HTTP, and this config file only supports servers that communicate over stdio. You need a bridge.
That bridge is supergateway. It's an npm package that takes stdio input from Claude Desktop and forwards them as HTTP requests to your n8n instance.
Open ~/Library/Application Support/Claude/claude_desktop_config.json and add:
{
"mcpServers": {
"n8n-mcp": {
"command": "npx",
"args": [
"-y", "supergateway",
"--streamableHttp", "https://n8n.yourdomain.com/mcp-server/http",
"--header", "Authorization: Bearer YOUR_MCP_ACCESS_TOKEN"
]
}
}
}Replace YOUR_MCP_ACCESS_TOKEN with the token you copied from n8n's MCP settings. Note: You need Node.js installed for npx to work.
Here???s what???s happening when you talk to Claude and it interacts with n8n:
Claude Desktop (stdio) -> supergateway (HTTPS) -> Cloudflare Tunnel -> localhost:5678 (n8n)
Claude Desktop can only talk to MCP servers over stdio. Your n8n speaks HTTP. Supergateway translates between the two. Cloudflare Tunnel makes your local n8n reachable over the internet. Each piece solves one specific problem.
Completely quit Claude Desktop (Cmd+Q, not just close the window) and reopen it. If the connection works, you won't see any error banners. Ask Claude something like "What n8n workflows do I have available" and it should query your instance and respond.
What Claude can do with??n8n
Once connected through Instance-level MCP, Claude gets a specific set of tools:
- search_workflows — list workflows available in MCP
- get_workflow_details — inspect a specific workflow
- publish_workflow / unpublish_workflow — activate or deactivate
- get_execution — check execution results
Notice what's missing: there's no "execute_workflow" tool. Instance-level MCP is about managing workflows, not running them.
To actually trigger workflows from Claude, you have two options:
Option A: Webhook triggers. Give your workflow a Webhook node as its trigger. Claude can call the webhook URL via HTTP. This works but requires you to manage URLs manually.
Option B: MCP Server Trigger node. This is the more elegant path. Add an "MCP Server Trigger" node inside a workflow. It turns that specific workflow into a custom MCP tool with a name and parameters that Claude can call directly. This is a per-workflow setup, separate from Instance-level MCP.
Things I wish I'd known earlier
The port issue is invisible. n8n generates MCP URLs using its internal port. If you don't set WEBHOOK_URL and N8N_HOST, everything looks fine in the n8n UI, but Claude gets a URL with :5678 that doesn't resolve through Cloudflare.
The OAuth connector is broken for self-hosted. Don't spend hours debugging the "Authorization failed" error in Claude's Connectors UI. It's a known issue. Use supergateway with an Access Token instead.
The config file doesn't support HTTP-type servers. When n8n shows you a JSON config with "type": "http" that's meant for MCP clients that support HTTP transport natively. Claude Desktop's claude_desktop_config.json is not one of them. It needs "command" and "args".
Cloudflare Tunnel is free and stable. Unlike ngrok's free tier (where URLs change on every restart and you get interstitial pages), Cloudflare gives you a permanent subdomain at no cost.
MCP access in n8n is off by default. Both at the instance level and per workflow. You have to explicitly turn on both.
Wrapping up
The connection between Claude and n8n works well once you get past the setup friction. The main obstacles are the OAuth bug, the HTTP-to-stdio gap, and the port mismatch — all solvable, just not obvious from the documentation.
The payoff: you can manage your automations from a conversation. Ask Claude what's running, check execution results, and with MCP Server Trigger nodes, execute workflows by just describing what you want done.
Not bad for a self-hosted setup that costs nothing beyond a domain name.