MCP Issue connect with the VAPI portal

Hi everyone,

I’m having trouble getting the Model Context Protocol (MCP) server to work on n8n version 2.3.5 (Self-hosted Docker).

My Setup:

  • n8n Version: 2.3.5

  • Deployment: Docker Compose in Queue Mode (1 Main + 4 Workers).

  • Infrastructure: AWS EC2 behind an Nginx Reverse Proxy.

  • MCP Node: Using the MCP Server Trigger.

The Issue:
Even with N8N_FEATURE_FLAG_MCP=true enabled on both Main and Workers, and N8N_TRUST_PROXY=true set, I am seeing the following error in my logs:
ValidationError: The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). Code: ERR_ERL_UNEXPECTED_X_FORWARDED_FOR

This seems to be preventing the MCP SSE stream from establishing.

Nginx Config Snippet:
I have already disabled buffering and gzip for the /mcp/ path:

nginx

server {
    server_name example.com;

    # === MCP Location Block ===
    location /mcp/ {
        proxy_pass http://127.0.0.1:5678;

        # CRITICAL: Disable compression for SSE
        gzip off; 

        proxy_http_version 1.1;
        proxy_set_header Connection ""; 
        proxy_buffering off;           
        proxy_cache off;
        chunked_transfer_encoding on;
        proxy_read_timeout 3600s;      

        # Required for n8n to recognize the proxy protocol
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Prevent Nginx from timing out the SSE stream early
        proxy_connect_timeout 10s;
        proxy_send_timeout 3600s;
    }

    # === Normal n8n UI & API ===
    location / {
        proxy_pass http://127.0.0.1:5678;

        # Ensure headers are correctly forwarded
        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 X-Forwarded-Host $host;

        # Optional: Handle WebSocket connections (if applicable)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeouts to avoid 504 errors
        proxy_connect_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_read_timeout 3600s;

    }

The issue appears to be related to the MCP server not starting correctly, despite the feature flag and proxy settings. You should double-check your Docker Compose file to ensure the environment variables `N8N_FEATURE_FLAG_MCP` and `N8N_TRUST_PROXY` are correctly set for both the main n8n instance and all worker instances. Also, confirm your Nginx configuration correctly forwards traffic to the n8n application.

Ok, thank you for your guidance. I have already configured all the items you mentioned, as you can see in the docker-compose file and the Nginx virtual host configuration below.

nginx

server {
server_name example.com;

# === MCP Location Block ===
location /mcp/ {
    proxy_pass http://127.0.0.1:5678;

    # CRITICAL: Disable compression for SSE
    gzip off; 

    proxy_http_version 1.1;
    proxy_set_header Connection ""; 
    proxy_buffering off;           
    proxy_cache off;
    chunked_transfer_encoding on;
    proxy_read_timeout 3600s;      

    # Required for n8n to recognize the proxy protocol
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    
    # Prevent Nginx from timing out the SSE stream early
    proxy_connect_timeout 10s;
    proxy_send_timeout 3600s;
}

# === Normal n8n UI & API ===
location / {
    proxy_pass http://127.0.0.1:5678;

    # Ensure headers are correctly forwarded
    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 X-Forwarded-Host $host;

    # Optional: Handle WebSocket connections (if applicable)
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    # Timeouts to avoid 504 errors
    proxy_connect_timeout 3600s;
    proxy_send_timeout 3600s;
    proxy_read_timeout 3600s;

}

docker-compose file

version: “3.8”

services:
n8n:
image: Package n8n · GitHub
container_name: n8n
restart: unless-stopped
ports:
- “5678:5678”
environment:
- NODE_ENV=production
- N8N_INSTANCE_NAME=prod-n8n
- GENERIC_TIMEZONE=UTC
- N8N_HOST=example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://example.com
- N8N_TRUST_PROXY=true
- N8N_PROXY_HOPS=1
- N8N_SECURE_COOKIE=true
- EXECUTIONS_MODE=queue
- OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true

  # === MCP FIXES FOR MAIN ===
  - N8N_FEATURE_FLAG_MCP=true
  - N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true
  # ==========================

  - QUEUE_BULL_REDIS_HOST=redis
  - QUEUE_BULL_REDIS_PORT=6379
  - DB_TYPE=postgresdb
  - DB_POSTGRESDB_HOST=postgres
  - DB_POSTGRESDB_PORT=5432
  - DB_POSTGRESDB_DATABASE=n8n
  - DB_POSTGRESDB_USER=n8n_postgres
  - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
  - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
  - N8N_BLOCK_ENV_ACCESS_IN_NODE=true # Kept TRUE for security as requested
  - N8N_RUNNERS_ENABLED=false
  - N8N_REINSTALL_MISSING_PACKAGES=true
  - N8N_NATIVE_PYTHON_RUNNER=false
volumes:
  - n8n_data:/home/node/.n8n
depends_on:
  - postgres
  - redis

n8n-worker:
image: Package n8n · GitHub
command: worker
restart: unless-stopped
environment:
- NODE_ENV=production
- EXECUTIONS_MODE=queue

  # === MCP FIXES FOR WORKERS ===
  - N8N_FEATURE_FLAG_MCP=true
  - N8N_REINSTALL_MISSING_PACKAGES=true
  - N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true
  # =============================

  - QUEUE_BULL_REDIS_HOST=redis
  - QUEUE_BULL_REDIS_PORT=6379
  - DB_TYPE=postgresdb
  - DB_POSTGRESDB_HOST=postgres
  - DB_POSTGRESDB_PORT=5432
  - DB_POSTGRESDB_DATABASE=n8n
  - DB_POSTGRESDB_USER=n8n_postgres
  - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
  - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
depends_on:
  - redis
  - postgres
deploy:
  replicas: 4

redis:
image: redis:7.2
container_name: redis
restart: unless-stopped
command: redis-server --save “” --appendonly no

postgres:
image: postgres:15
container_name: postgres
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n_postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data

volumes:
n8n_data:
postgres_data:

1 Like

Can you restart your instance now and let me know if anything changes?