Hi all, I’m running a production self-hosted n8n instance (v1.21.0, Docker Compose) and trying to enable MCP (Modular Control Plane) in native mode with one main and one runner container.
What I’ve already set up:
- Docker Compose with:
yaml
CopiarEditar
services:
n8n-main:
image: n8nio/n8n:latest
environment:
- N8N_MCP_SERVER=true
- EXECUTIONS_MODE=queue
- N8N_RUNNER_MODE=main
- N8N_MCP_SKIP_SSL_VALIDATION=true
- N8N_MCP_USE_REVERSE_PROXY=true
- N8N_MCP_TRUST_PROXY=true
n8n-runner:
image: n8nio/n8n:latest
environment:
- EXECUTIONS_MODE=queue
- N8N_RUNNER_MODE=runner
- N8N_MCP_SKIP_SSL_VALIDATION=true
- N8N_MCP_USE_REVERSE_PROXY=true
- N8N_MCP_TRUST_PROXY=true
- Reverse proxy using NGINX (with HTTPS) and a specific block for
/mcp/, including SSE proxy settings:
nginx
CopiarEditar
location /mcp/ {
proxy_pass http://n8n-main:5678;
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
gzip off;
chunked_transfer_encoding off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection '';
}
The issue:
Even after all of this, accessing the /mcp/.../sse endpoint returns:
json
CopiarEditar
{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "bad request: server not initialized"
},
"id": null
}
- Both
n8n-mainandn8n-runnercontainers are up - UI works fine
- No workflows execute, and no runner appears to register with MCP
- Logs do not show any “registered” or “initialized” messages
What I’m trying to understand:
- Is there something missing in the init handshake from the runner to MCP?
- Are there other required settings not documented for this setup?
- Could this be related to the reverse proxy or Docker network setup?
- How can I validate that MCP is waiting for runners?
Any ideas, examples or guidance would be greatly appreciated. Thanks in advance!