docs/N8N_DEPLOYMENT.md
This guide covers how to deploy n8n-MCP and connect it to your n8n instance. Whether you're testing locally or deploying to production, we'll show you how to set up n8n-MCP for use with n8n's MCP Client Tool node.
n8n-MCP is a Model Context Protocol server that provides AI assistants with comprehensive access to n8n node documentation and management capabilities. When connected to n8n via the MCP Client Tool node, it enables:
Test n8n-MCP locally with the provided test script:
# Clone the repository
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
# Build the project
npm install
npm run build
# Run the integration test script
./scripts/test-n8n-integration.sh
This script will:
For development or custom testing:
Prerequisites:
Start n8n-MCP:
# Set environment variables
export N8N_MODE=true
export MCP_MODE=http # Required for HTTP mode
export N8N_API_URL=http://localhost:5678 # Your n8n instance URL
export N8N_API_KEY=your-api-key-here # Your n8n API key
export WEBHOOK_SECURITY_MODE=moderate # Required when N8N_API_URL is localhost or RFC1918
export MCP_AUTH_TOKEN=test-token-minimum-32-chars-long
export AUTH_TOKEN=test-token-minimum-32-chars-long # Same value as MCP_AUTH_TOKEN
export PORT=3001
# Start the server
npm start
# Check health
curl http://localhost:3001/health
# Check MCP protocol endpoint (this is the endpoint n8n connects to)
curl http://localhost:3001/mcp
# Should return: {"protocolVersion":"2024-11-05"} for n8n compatibility
| Variable | Required | Description | Example Value |
|---|---|---|---|
N8N_MODE | Yes | Enables n8n integration mode | true |
MCP_MODE | Yes | Enables HTTP mode for n8n MCP Client | http |
N8N_API_URL | Yes* | URL of your n8n instance | http://localhost:5678 |
N8N_API_KEY | Yes* | n8n API key for workflow management | n8n_api_xxx... |
WEBHOOK_SECURITY_MODE | No | SSRF gate (strict default, moderate, permissive). Set to moderate when N8N_API_URL is localhost or an RFC1918 host on the same network. | moderate |
MCP_AUTH_TOKEN | Yes | Authentication token for MCP requests (min 32 chars) | secure-random-32-char-token |
AUTH_TOKEN | Yes | MUST match MCP_AUTH_TOKEN exactly | secure-random-32-char-token |
PORT | No | Port for the HTTP server | 3000 (default) |
LOG_LEVEL | No | Logging verbosity | info, debug, error |
*Required only for workflow management features. Documentation tools work without these.
Starting with version 2.9.2, we use a single optimized Dockerfile for all deployments:
Dockerfile.n8n has been removed as redundantN8N_MODE=true environment variableDockerfile⚠️ Critical: Docker caches images locally. Always run
docker pull ghcr.io/czlonkowski/n8n-mcp:latestbefore deploying to ensure you have the latest version. This simple step prevents most deployment issues.
If you're running n8n-MCP on the same server as your n8n instance:
The pre-built images are automatically updated with each release and are the easiest way to get started.
IMPORTANT: Always pull the latest image to avoid using cached versions:
# ALWAYS pull the latest image first
docker pull ghcr.io/czlonkowski/n8n-mcp:latest
# Generate a secure token (save this!)
AUTH_TOKEN=$(openssl rand -hex 32)
echo "Your AUTH_TOKEN: $AUTH_TOKEN"
# Create a Docker network if n8n uses one
docker network create n8n-net
# Run n8n-MCP container
docker run -d \
--name n8n-mcp \
--network n8n-net \
-p 3000:3000 \
-e N8N_MODE=true \
-e MCP_MODE=http \
-e N8N_API_URL=http://n8n:5678 \
-e N8N_API_KEY=your-n8n-api-key \
-e WEBHOOK_SECURITY_MODE=permissive \
-e MCP_AUTH_TOKEN=$AUTH_TOKEN \
-e AUTH_TOKEN=$AUTH_TOKEN \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/czlonkowski/n8n-mcp:latest
Only build from source if you need custom modifications or are contributing to development:
# Clone and build
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
# Build Docker image
docker build -t n8n-mcp:latest .
# Run using your local image
docker run -d \
--name n8n-mcp \
-p 3000:3000 \
-e N8N_MODE=true \
-e MCP_MODE=http \
-e MCP_AUTH_TOKEN=$(openssl rand -hex 32) \
-e AUTH_TOKEN=$(openssl rand -hex 32) \
# ... other settings
n8n-mcp:latest
# Create service file
sudo cat > /etc/systemd/system/n8n-mcp.service << EOF
[Unit]
Description=n8n-MCP Server
After=network.target
[Service]
Type=simple
User=nodejs
WorkingDirectory=/opt/n8n-mcp
Environment="N8N_MODE=true"
Environment="MCP_MODE=http"
Environment="N8N_API_URL=http://localhost:5678"
Environment="N8N_API_KEY=your-n8n-api-key"
Environment="WEBHOOK_SECURITY_MODE=moderate"
Environment="MCP_AUTH_TOKEN=your-secure-token-32-chars-min"
Environment="AUTH_TOKEN=your-secure-token-32-chars-min"
Environment="PORT=3000"
ExecStart=/usr/bin/node /opt/n8n-mcp/dist/mcp/index.js
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# Enable and start
sudo systemctl enable n8n-mcp
sudo systemctl start n8n-mcp
Deploy n8n-MCP on a separate server from your n8n instance:
Always pull the latest image to ensure you have the current version:
# On your cloud server (Hetzner, AWS, DigitalOcean, etc.)
# ALWAYS pull the latest image first
docker pull ghcr.io/czlonkowski/n8n-mcp:latest
# Generate auth tokens
AUTH_TOKEN=$(openssl rand -hex 32)
echo "Save this AUTH_TOKEN: $AUTH_TOKEN"
# Run the container
docker run -d \
--name n8n-mcp \
-p 3000:3000 \
-e N8N_MODE=true \
-e MCP_MODE=http \
-e N8N_API_URL=https://your-n8n-instance.com \
-e N8N_API_KEY=your-n8n-api-key \
-e MCP_AUTH_TOKEN=$AUTH_TOKEN \
-e AUTH_TOKEN=$AUTH_TOKEN \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/czlonkowski/n8n-mcp:latest
Only needed if you're modifying the code:
# Clone and build
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
docker build -t n8n-mcp:latest .
# Run using local image
docker run -d \
--name n8n-mcp \
-p 3000:3000 \
# ... same environment variables as above
n8n-mcp:latest
Server Requirements:
Initial Setup:
# SSH into your server
ssh root@your-server-ip
# Update and install Docker
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
Using Docker Compose (Recommended)
# Create docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
n8n-mcp:
image: ghcr.io/czlonkowski/n8n-mcp:latest
pull_policy: always # Always pull latest image
container_name: n8n-mcp
restart: unless-stopped
environment:
- N8N_MODE=true
- MCP_MODE=http
- N8N_API_URL=${N8N_API_URL}
- N8N_API_KEY=${N8N_API_KEY}
- MCP_AUTH_TOKEN=${MCP_AUTH_TOKEN}
- AUTH_TOKEN=${AUTH_TOKEN}
- PORT=3000
- LOG_LEVEL=info
networks:
- web
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- web
networks:
web:
driver: bridge
volumes:
caddy_data:
caddy_config:
EOF
Note: The pull_policy: always ensures you always get the latest version.
Building from Source (if needed)
# Only if you need custom modifications
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
docker build -t n8n-mcp:local .
# Then update docker-compose.yml to use:
# image: n8n-mcp:local
container_name: n8n-mcp
restart: unless-stopped
environment:
- N8N_MODE=true
- MCP_MODE=http
- N8N_API_URL=${N8N_API_URL}
- N8N_API_KEY=${N8N_API_KEY}
- MCP_AUTH_TOKEN=${MCP_AUTH_TOKEN}
- AUTH_TOKEN=${AUTH_TOKEN}
- PORT=3000
- LOG_LEVEL=info
networks:
- web
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- web
networks:
web:
driver: bridge
volumes:
caddy_data:
caddy_config:
EOF
Complete the Setup
# Create Caddyfile
cat > Caddyfile << 'EOF'
mcp.yourdomain.com {
reverse_proxy n8n-mcp:3000
}
EOF
# Create .env file
AUTH_TOKEN=$(openssl rand -hex 32)
cat > .env << EOF
N8N_API_URL=https://your-n8n-instance.com
N8N_API_KEY=your-n8n-api-key-here
MCP_AUTH_TOKEN=$AUTH_TOKEN
AUTH_TOKEN=$AUTH_TOKEN
EOF
# Save the AUTH_TOKEN!
echo "Your AUTH_TOKEN is: $AUTH_TOKEN"
echo "Save this token - you'll need it in n8n MCP Client Tool configuration"
# Start services
docker compose up -d
AWS EC2:
DigitalOcean:
Google Cloud:
In your n8n workflow, add the MCP Client Tool node
Configure the connection:
Server URL (MUST include /mcp endpoint):
- Same server: http://localhost:3000/mcp
- Docker network: http://n8n-mcp:3000/mcp
- Different server: https://mcp.yourdomain.com/mcp
Auth Token: [Your MCP_AUTH_TOKEN/AUTH_TOKEN value]
Transport: HTTP Streamable (SSE)
⚠️ Critical: The Server URL must include the /mcp endpoint path. Without this, the connection will fail.
Test the connection by selecting a simple tool like list_nodes
Once connected, you can use these MCP tools in n8n:
Documentation Tools (No API key required):
list_nodes - List all n8n nodes with filteringsearch_nodes - Search nodes by keywordget_node_info - Get detailed node informationget_node_essentials - Get only essential propertiesvalidate_workflow - Validate workflow configurationsget_node_documentation - Get human-readable docsManagement Tools (Requires n8n API key):
n8n_create_workflow - Create new workflowsn8n_update_workflow - Update existing workflowsn8n_get_workflow - Retrieve workflow detailsn8n_list_workflows - List all workflowsn8n_trigger_webhook_workflow - Trigger webhook workflowsConnect n8n-MCP to AI Agent nodes for intelligent automation:
You are an n8n workflow expert. Use the MCP tools to:
1. Search for appropriate nodes using search_nodes
2. Get configuration details with get_node_essentials
3. Validate configurations with validate_workflow
4. Create the workflow if all validations pass
docker pull before deployment--read-only flag if possible:latest in productiondocker pull ghcr.io/czlonkowski/n8n-mcp:latestUsing Outdated Cached Images
docker pull ghcr.io/czlonkowski/n8n-mcp:latest before deploymentdocker images | grep n8n-mcpMissing MCP_MODE=http Environment Variable
/mcp endpointMCP_MODE=http to your environment variablesServer URL Missing /mcp Endpoint
/mcp (e.g., http://localhost:3000/mcp)/mcp endpoint specifically, not the root URLMismatched Auth Tokens
MCP_AUTH_TOKEN and AUTH_TOKEN have the same value"Connection refused" in n8n MCP Client Tool
Check n8n-MCP is running:
# Docker
docker ps | grep n8n-mcp
docker logs n8n-mcp --tail 20
# Systemd
systemctl status n8n-mcp
journalctl -u n8n-mcp --tail 20
Verify endpoints are accessible:
# Health check (should return status info)
curl http://your-server:3000/health
# MCP endpoint (should return protocol version)
curl http://your-server:3000/mcp
Check firewall and networking:
# Test port accessibility from n8n server
telnet your-mcp-server 3000
# Check firewall rules (Ubuntu/Debian)
sudo ufw status
# Check if port is bound correctly
netstat -tlnp | grep :3000
"Invalid auth token" or "Authentication failed"
Verify token format:
# Check token length (should be 64 chars for hex-32)
echo $MCP_AUTH_TOKEN | wc -c
# Verify both tokens match
echo "MCP_AUTH_TOKEN: $MCP_AUTH_TOKEN"
echo "AUTH_TOKEN: $AUTH_TOKEN"
Common token issues:
MCP_AUTH_TOKEN and AUTH_TOKEN"Cannot connect to n8n API"
Verify n8n configuration:
# Test n8n API accessibility
curl -H "X-N8N-API-KEY: your-api-key" \
https://your-n8n-instance.com/api/v1/workflows
Common n8n API issues:
N8N_API_URL missing protocol (http:// or https://)"Features Not Working as Expected"
docker pull ghcr.io/czlonkowski/n8n-mcp:latestdocker inspect ghcr.io/czlonkowski/n8n-mcp:latest | grep Created"Protocol version mismatch"
/mcp endpoint returns correct versionComplete Environment Variable Checklist:
# Required for all deployments
export N8N_MODE=true # Enables n8n integration
export MCP_MODE=http # Enables HTTP mode for n8n
export MCP_AUTH_TOKEN=your-secure-32-char-token # Auth token
export AUTH_TOKEN=your-secure-32-char-token # Same value as MCP_AUTH_TOKEN
# Required for workflow management features
export N8N_API_URL=https://your-n8n-instance.com # Your n8n URL
export N8N_API_KEY=your-n8n-api-key # Your n8n API key
# Optional
export PORT=3000 # HTTP port (default: 3000)
export LOG_LEVEL=info # Logging level
Container Build Failures
# Clear Docker cache and rebuild
docker system prune -f
docker build --no-cache -t n8n-mcp:latest .
Container Runtime Issues
# Check container logs for detailed errors
docker logs n8n-mcp -f --timestamps
# Inspect container environment
docker exec n8n-mcp env | grep -E "(N8N|MCP|AUTH)"
# Test container connectivity
docker exec n8n-mcp curl -f http://localhost:3000/health
HTTPS/SSL Problems
# Test SSL certificate
openssl s_client -connect mcp.yourdomain.com:443
# Check Caddy logs
docker logs caddy -f --tail 50
Docker Network Issues
# Check if containers can communicate
docker network ls
docker network inspect bridge
# Test inter-container connectivity
docker exec n8n curl http://n8n-mcp:3000/health
# For Docker
docker run -d \
--name n8n-mcp \
-e DEBUG_MCP=true \
-e LOG_LEVEL=debug \
-e N8N_MODE=true \
-e MCP_MODE=http \
# ... other settings
# For systemd, add to service file:
Environment="DEBUG_MCP=true"
Environment="LOG_LEVEL=debug"
# 1. Health check (basic server functionality)
curl -v http://localhost:3000/health
# 2. MCP protocol endpoint (what n8n connects to)
curl -v http://localhost:3000/mcp
# 3. Test authentication (if working, returns tools list)
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer YOUR_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
# 4. Test a simple tool (documentation only, no n8n API needed)
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer YOUR_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_database_statistics","arguments":{}},"id":2}'
# Success patterns
grep "Server started" /var/log/n8n-mcp.log
grep "Protocol version" /var/log/n8n-mcp.log
# Error patterns
grep -i "error\|failed\|invalid" /var/log/n8n-mcp.log
grep -i "auth\|token" /var/log/n8n-mcp.log
grep -i "connection\|network" /var/log/n8n-mcp.log
If you're still experiencing issues:
# System info
docker --version
docker-compose --version
uname -a
# n8n-MCP version
docker exec n8n-mcp node dist/index.js --version
# Environment check
docker exec n8n-mcp env | grep -E "(N8N|MCP|AUTH)" | sort
# Container status
docker ps | grep n8n-mcp
docker stats n8n-mcp --no-stream
# Test with minimal configuration
docker run -d \
--name n8n-mcp-test \
-p 3001:3000 \
-e N8N_MODE=true \
-e MCP_MODE=http \
-e MCP_AUTH_TOKEN=test-token-minimum-32-chars-long \
-e AUTH_TOKEN=test-token-minimum-32-chars-long \
-e LOG_LEVEL=debug \
n8n-mcp:latest
# Test basic functionality
curl http://localhost:3001/health
curl http://localhost:3001/mcp
Need help? Open an issue on GitHub or check the n8n forums