Claude.ai MCP Connector Failing to connect to my self-hosted n8n

I’m trying to connect Claude.ai to my self-hosted n8n via Instance-level MCP (OAuth). The OAuth flow appears to complete — I get redirected to n8n, I authorize, and n8n shows Claude as a Connected client. But Claude always returns “Authorization with the MCP server failed.”

I also tried creating a separate workflow with an MCP Server Trigger node (no auth) and using that Production URL as a custom connector in Claude. Same error.

My setup

  • n8n version: 2.12.3

  • Database: SQLite (default)

  • n8n EXECUTIONS_PROCESS setting: default

  • Running n8n via: npm (global install, Node.js v22.21.1 via nvm)

  • Operating system: macOS 14.2.1 (Apple Silicon)

n8n runs as a macOS LaunchAgent and is exposed to the internet via Cloudflare Tunnel (cloudflared 2025.11.1) routing n8n.jeffzeb.comhttp://127.0.0.1:5678.

What I’ve tried

  • Confirmed endpoint is reachable: curl -I returns HTTP 401 with Bearer auth as expected

  • Added N8N_PROXY_HOPS=1 and N8N_TRUST_PROXY=true (fixed an ERR_ERL_UNEXPECTED_X_FORWARDED_FOR error in the MCP SDK)

  • Created a Cloudflare Transform Rule to set Origin: https://n8n.jeffzeb.com (known issue with tunnels stripping the scheme)

  • Revoked old Connected clients and re-added the connector fresh

  • Tested in both Safari and Chrome

  • Tested both Instance-level MCP (OAuth) and MCP Server Trigger (no auth) — both fail with the same error

  • Workflows are enabled for MCP access and active

Key observation

OAuth completes on n8n’s side (Connected clients tab confirms it), but Claude doesn’t recognize the connection as successful. This happens with both the instance-level MCP URL and a standalone MCP Server Trigger URL.

Has anyone successfully connected Claude.ai (not Claude Desktop) to a self-hosted n8n behind a Cloudflare Tunnel? Any ideas what could be failing after the OAuth callback? Also possible issue is on the Claude side, so I’ve reached out to their help support as well.

Hi @GeoffS , welcome to the n8n community :tada:

What stands out to me is that both the OAuth connector and the no-auth MCP Server Trigger fail the same way, so I’d be cautious about blaming OAuth itself, to me that points more toward a reverse-proxy / transport issue after the callback, especially since n8n behind a proxy needs the original forwarded host/proto headers and usually a fixed WEBHOOK_URL, plus Cloudflare can sometimes interfere with streaming/compression behavior.

could you please share the response headers and body you get from the MCP endpoint with curl -i, and whether Cloudflare has compression, caching, Access, or any other edge features enabled on that hostname/path?

Cloudflare Tunnel buffers streaming responses by default, which breaks the MCP transport even though the OAuth redirect works fine. Add disableChunkedEncoding: true to your cloudflared config for that ingress rule. Also make sure WebSockets are enabled in the Cloudflare dashboard under Network for your domain.

Thanks everyone for the quick responses! Here’s what I found after working through them:

@pvdyck

disableChunkedEncoding: true Added this to my cloudflared config and restarted the tunnel. This was a good call and may have fixed the streaming issue, but the auth error persists.

@tamy.santos

Here’s what curl -i shows for the instance-level MCP endpoint:

  • GET returns HTTP 200 with the n8n editor HTML (falls through to frontend)

  • POST with MCP initialize payload returns: {"message":"Unauthorized: Authorization header not sent"}— so the endpoint is alive and correctly requiring auth

For the MCP Server Trigger endpoint (no auth), POST with MCP initialize returns a proper response:

event: message
data: {"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"MCP_Server_Trigger","version":"0.1.0"},"jsonrpc":"2.0","id":1}

Response headers include content-type: text/html; charset=utf-8, access-control-allow-origin: ``https://n8n.xxxxxxxx.com, cache-control: no-cache, no-store, cf-cache-status: DYNAMIC. No compression or caching issues visible.

BenB

As shown above, the MCP Server Trigger returns a valid initialize response with correct tools capability and protocol version. Transport is working fine — the disableChunkedEncoding fix plus WebSockets enabled in Cloudflare means streaming isn’t being buffered.

Both endpoints work correctly at the transport level when tested with curl. The OAuth flow also completes — n8n shows Claude as a Connected client after I authorize. But Claude.ai still returns “Authorization with the MCP server failed” every time.

Even the no-auth MCP Server Trigger fails with the same error, which suggests Claude.ai’s custom connector is attempting OAuth regardless and something in that exchange isn’t completing on Claude’s side.

I also fixed an ERR_ERL_UNEXPECTED_X_FORWARDED_FOR error earlier by adding N8N_TRUST_PROXY=true — the error log is clean now.

Has anyone gotten Claude.ai (not Claude Desktop) working with a self-hosted n8n behind Cloudflare Tunnel specifically? Starting to wonder if this is a Claude-side issue with the OAuth callback.

Also, @tamy.santos here’s what you asked for.

curl -i against the instance-level MCP endpoint (POST):

HTTP/2 401
content-type: application/json; charset=utf-8
content-length: 57
access-control-allow-credentials: true
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, push-ref, browser-id, anonymousid, authorization, x-authorization
access-control-allow-methods: GET, POST, OPTIONS, PUT, PATCH, DELETE
access-control-allow-origin: https://n8n.xxxxxxx.com
etag: W/"39-2hSNeRgbNg6crq17Q/2hLPX4gMU"
vary: Accept-Encoding
www-authenticate: Bearer realm="n8n MCP Server"
cf-cache-status: DYNAMIC

{"message":"Unauthorized: Authorization header not sent"}

curl -i against the MCP Server Trigger endpoint (no auth, POST):

HTTP/2 200
content-type: text/event-stream
content-length: 178
access-control-allow-methods: OPTIONS, DELETE, GET, POST
access-control-allow-origin: https://n8n.xxxxxxx.com
cache-control: no-cache
mcp-session-id: 9bcea911-251c-4dd2-ab03-d8c28c93fc9a
vary: Accept-Encoding
cf-cache-status: DYNAMIC

event: message
data: {"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"MCP_Server_Trigger","version":"0.1.0"},"jsonrpc":"2.0","id":1}

Cloudflare edge features:

  • No custom caching, compression, or Access policies on this hostname

  • WebSockets enabled

  • One active rule: Modify Request Header setting Origin: https://n8n.xxxxxxx.com

  • Tunnel config has disableChunkedEncoding: true per @pvdyck’s suggestion

@GeoffS Falls du offen dafür bist, Claude Desktop oder Claude Code CLI statt Claude.ai Web zu nutzen, gibt es einen Ansatz, der das OAuth-Problem völlig vermeidet. Ich habe einen Python MCP Server gebaut, der sich über stdio direkt mit der n8n REST API verbindet; keine Cloudflare-Tunneling-Komplikationen, kein OAuth-Handshake. Könnte einen Versuch wert sein: https://github.com/DerJams/n8n-mcp-server-python

Danke für die Informationen @GeoffS

also, tut mir leid, das sagen zu müssen, aber es sieht so aus, als würde das Problem aus dem Unterschied zwischen Claude Desktop und Claude AI stammen. Die Dokumentation spricht vom MCP Trigger nur in Bezug auf Claude Desktop, ich habe nichts über den Claude.ai Custom Connector gefunden, und die Tatsache, dass der Endpoint ohne Authentifizierung mit dem gleichen Fehler fehlschlägt, deutet darauf hin, dass er möglicherweise einen eigenen Autorisierungsfluss anwendet oder diesen Typ von Endpoint nicht akzeptiert. Der praktische Workaround wäre, mit Claude Desktop oder einem anderen unterstützten/dokumentierten MCP zu testen. Falls Claude.ai zwingend erforderlich ist, würde ich vorübergehend einen Proxy/Adapter zwischen Claude.ai und n8n verwenden.

Hier sind die Docs zur Unterstützung
MCP connector - Claude API Docs
MCP Server Trigger node documentation | n8n Docs
Set up and use n8n MCP server | n8n Docs

Danke @tamy.santos. Ich hatte dieses Projekt eine Zeit lang auf der Rückseite, aber ich werde mich mit deinen Dokumenten noch mal damit befassen. Leider hatte ich auch mit Claude Desktop kein Glück.

ach :frowning:
schade.

Update: Funktioniert jetzt.

Der OAuth-Connector-Flow funktioniert immer noch nicht — das scheint ein Claude-seitiger Bug zu sein, bei dem der OAuth-Handshake abgeschlossen wird, aber das Bearer-Token nie an nachfolgende MCP-Anfragen angehängt wird. Ich habe das an den Anthropic-Support gemeldet und sie haben es als bekanntes Problem bestätigt.

Was funktioniert hat: OAuth vollständig umgehen, indem die Claude Desktop-Konfigurationsdatei mit einem Bearer-Token verwendet wird.

  1. Rufe dein Access Token unter n8n Settings → Instance-level MCP → Connection details → Access Token tab auf

  2. Bearbeite ~/Library/Application Support/Claude/claude_desktop_config.json

  3. Füge einen mcpServers-Block hinzu:

{
  "mcpServers": {
    "n8n": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://your-n8n-domain.com/mcp-server/http",
        "--header",
        "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
      ]
    }
  }
}

  1. Starte Claude Desktop neu

Dies verwendet mcp-remote, um Claude Desktops Stdio-Transport mit n8ns HTTP-Endpoint zu verbinden, wobei das Token direkt weitergegeben wird. Kein OAuth-Tanz erforderlich.

Hinweis: Dies funktioniert nur in Claude Desktop, nicht in claude.ai im Browser. Das Token kann auch ablaufen, daher kann es notwendig sein, es regelmäßig zu aktualisieren.

Weitere Fixes, die unterwegs notwendig waren (wenn du n8n hinter einem Cloudflare Tunnel betreibst):

  • disableChunkedEncoding: true in der cloudflared-Konfiguration (verhindert SSE-Pufferung)

  • N8N_TRUST_PROXY=true Umgebungsvariable (behebt ERR_ERL_UNEXPECTED_X_FORWARDED_FOR im MCP SDK)

  • Cloudflare Transform Rule zum Setzen von Origin: https://your-domain.com (behebt das Schema-Stripping-Problem)

  • WebSockets aktiviert in den Cloudflare-Netzwerkeinstellungen

Danke @tamy.santos, BenB, pvdyck, unstableentity und @syed_noor für die ganze Hilfe beim Eingrenzen.

Großartig! Eine Sache, die es zu beachten gilt:

MCP-Server funktionieren am besten mit stdio-Transport

für lokale Claude Desktop-Setups und SSE

für Remote-/Server-Bereitstellungen.

Ich betreibe einen benutzerdefinierten Flowmatic-MCP-

Server, der Claude mit Live-Marktdaten

und Portfoliomanagement verbindet — ich helfe gerne,

die Architektur zu teilen, wenn nützlich.