Menu

mcp serve

n8n-decanter mcp serve [--port N]

Starts the MCP guard-proxy: a localhost HTTP endpoint that speaks n8n’s MCP protocol and forwards everything to your instance’s /mcp-server/http — with decanter as the sole credential holder and one rule enforced technically. It is the HTTP variant of the guard: for agents whose MCP config can spawn a command, prefer mcp connect — the stdio form the scaffolded .mcp.json already wires, with no secret to manage. mcp serve exists for harnesses that only take an MCP URL:

  • Blocked: update_workflow calls that write Code-node source. That covers both routes n8n exposes: a jsCode key anywhere in the arguments (updateNodeParameters, addNode), and a setNodeParameter whose JSON-Pointer path targets jsCode (where the code rides a scalar value and no jsCode key appears). The caller gets an instructive tool error pointing at the file + push flow instead — Code-node source lives in this repo, not in ad-hoc MCP writes. The full op vocabulary is deliberately not enumerated; only the two source-writing routes are intercepted.
  • Blocked: publish_workflow when the draft it would take live carries a dangling $('…') reference — the same check test and publish run. Without it the go-live gate is bypassable: an agent could publish over raw MCP and skip the verb entirely. Fail-closed — if the check itself cannot run (n8n unreachable), the publish is refused too, and the message says the check failed rather than blaming the workflow.
  • Everything else passes through untouched, including SSE responses: reads, structure edits, wiring, the n8n build/lifecycle tools.

Like mcp connect, a forwarded structure edit also triggers the live mirror — a debounced background pull that refreshes the read-only workflow.json snapshot with no manual pull (fire-and-forget, git-gated, tracked-only; on by default, "liveMirror": false to disable).

Point your agent’s MCP config at the printed URL with the printed session secret as its Authorization header — the agent never sees an n8n credential, and the secret rotates on every mcp serve run. The current endpoint + secret also land in a gitignored .decanter-proxy.json, which the scaffolded mcp-route-check.mjs session hook uses to nudge agents whose MCP config still points at the instance directly.

{
  "mcpServers": {
    "n8n-instance": {
      "type": "http",
      "url": "http://127.0.0.1:5680/mcp-server/http",
      "headers": { "Authorization": "Bearer <printed secret>" }
    }
  }
}

Safety properties: binds 127.0.0.1 only; unparseable request bodies are refused (fail closed), oversized bodies are capped; requests without the session secret never reach n8n. The blast radius of a proxy outage is availability, not integrity — decanter’s own sync (pull/push/watch) never routes through the proxy.

--port picks the listen port (default 5680; 0 for an ephemeral one — note your agent config then changes every run). Stop with Ctrl-C.