# HTTP Deployment Guide for n8n-MCP Deploy n8n-MCP as a remote HTTP server to provide n8n knowledge to Claude from anywhere. 📌 **Latest Version**: v2.7.6 (includes trust proxy support for correct IP logging behind reverse proxies) ## 🎯 Overview n8n-MCP HTTP mode enables: - ☁️ Cloud deployment (VPS, Docker, Kubernetes) - 🌐 Remote access from any Claude Desktop client - 🔒 Token-based authentication - ⚡ Production-ready performance (~12ms response time) - 🔧 Fixed implementation (v2.3.2) for stability - 🚀 Optional n8n management tools (16 additional tools when configured) ## 📐 Deployment Scenarios ### 1. Local Development (Simplest) Use **stdio mode** - Claude Desktop connects directly to the Node.js process: ``` Claude Desktop → n8n-mcp (stdio mode) ``` - ✅ No HTTP server needed - ✅ No authentication required - ✅ Fastest performance - ❌ Only works locally ### 2. Local HTTP Server Run HTTP server locally for testing remote features: ``` Claude Desktop → http-bridge.js → localhost:3000 ``` - ✅ Test HTTP features locally - ✅ Multiple Claude instances can connect - ✅ Good for development - ❌ Still only local access ### 3. Remote Server Deploy to cloud for access from anywhere: ``` Claude Desktop → mcp-remote → https://your-server.com ``` - ✅ Access from anywhere - ✅ Team collaboration - ✅ Production-ready - ❌ Requires server setup ⚠️ **Experimental Feature**: Remote server deployment has not been thoroughly tested. If you encounter any issues, please [open an issue](https://github.com/czlonkowski/n8n-mcp/issues) on GitHub. ## 📋 Prerequisites **Server Requirements:** - Node.js 16+ or Docker - 512MB RAM minimum - Public IP or domain name - (Recommended) SSL certificate for HTTPS **Client Requirements:** - Claude Desktop - Node.js 18+ (for mcp-remote) - Or Claude Pro/Team (for native remote MCP) ## 🚀 Quick Start ### Option 1: Docker Deployment (Recommended for Production) ```bash # 1. Create environment file cat > .env << EOF AUTH_TOKEN=$(openssl rand -base64 32) USE_FIXED_HTTP=true MCP_MODE=http PORT=3000 # Optional: Enable n8n management tools # N8N_API_URL=https://your-n8n-instance.com # N8N_API_KEY=your-api-key-here EOF # 2. Deploy with Docker docker run -d \ --name n8n-mcp \ --restart unless-stopped \ --env-file .env \ -p 3000:3000 \ ghcr.io/czlonkowski/n8n-mcp:latest # 3. Verify deployment curl http://localhost:3000/health ``` ### Option 2: Local Development (Without Docker) ```bash # 1. Clone and setup git clone https://github.com/czlonkowski/n8n-mcp.git cd n8n-mcp npm install npm run build npm run rebuild # 2. Configure environment export MCP_MODE=http export USE_FIXED_HTTP=true # Important: Use fixed implementation export AUTH_TOKEN=$(openssl rand -base64 32) export PORT=3000 # 3. Start server npm run start:http ``` ### Option 3: Direct stdio Mode (Simplest for Local) Skip HTTP entirely and use stdio mode directly: ```json { "mcpServers": { "n8n-local": { "command": "node", "args": [ "/path/to/n8n-mcp/dist/mcp/index.js" ], "env": { "N8N_API_URL": "https://your-n8n-instance.com", "N8N_API_KEY": "your-api-key-here" } } } } ``` 💡 **Save your AUTH_TOKEN** - clients will need it to connect! ## ⚙️ Configuration ### Required Environment Variables | Variable | Description | Example | |----------|-------------|------| | `MCP_MODE` | Must be set to `http` | `http` | | `USE_FIXED_HTTP` | **Important**: Set to `true` for v2.3.2 fixes | `true` | | `AUTH_TOKEN` | Secure token (32+ characters) | `generated-token` | ### Optional Settings | Variable | Description | Default | |----------|-------------|---------| | `PORT` | Server port | `3000` | | `HOST` | Bind address | `0.0.0.0` | | `LOG_LEVEL` | Log verbosity | `info` | | `NODE_ENV` | Environment | `production` | | `TRUST_PROXY` | Trust proxy headers for correct IP logging | `0` | | `BASE_URL` | Public URL for the server (v2.7.14+) | Auto-detected | | `PUBLIC_URL` | Alternative to BASE_URL | Auto-detected | ### n8n Management Tools (Optional) Enable 16 additional tools for managing n8n workflows by configuring API access: ⚠️ **Requires v2.7.1+** - Earlier versions had an issue with tool registration in Docker environments. | Variable | Description | Example | |----------|-------------|---------| | `N8N_API_URL` | Your n8n instance URL | `https://your-n8n.com` | | `N8N_API_KEY` | n8n API key (from Settings > API) | `n8n_api_key_xxx` | | `N8N_API_TIMEOUT` | Request timeout (ms) | `30000` | | `N8N_API_MAX_RETRIES` | Max retry attempts | `3` | #### What This Enables When configured, you get **16 additional tools** (total: 38 tools): **Workflow Management (11 tools):** - `n8n_create_workflow` - Create new workflows - `n8n_get_workflow` - Get workflow by ID - `n8n_update_full_workflow` - Update entire workflow - `n8n_update_partial_workflow` - Update using diff operations (v2.7.0+) - `n8n_delete_workflow` - Delete workflows - `n8n_list_workflows` - List all workflows - And more workflow detail/structure tools **Execution Management (4 tools):** - `n8n_trigger_webhook_workflow` - Execute via webhooks - `n8n_get_execution` - Get execution details - `n8n_list_executions` - List workflow runs - `n8n_delete_execution` - Delete execution records **System Tools:** - `n8n_health_check` - Check n8n connectivity - `n8n_diagnostic` - System diagnostics - `n8n_validate_workflow` - Validate from n8n instance #### Getting Your n8n API Key 1. Log into your n8n instance 2. Go to **Settings** > **API** 3. Click **Create API Key** 4. Copy the generated key ⚠️ **Security Note**: Store API keys securely and never commit them to version control. ## 🌐 Reverse Proxy Configuration ### URL Configuration (v2.7.14+) n8n-MCP now intelligently detects the correct URL for your deployment: 1. **Explicit Configuration** (highest priority): ```bash BASE_URL=https://n8n-mcp.example.com # Explicitly set public URL # or PUBLIC_URL=https://your-domain.com:8443 ``` 2. **Auto-Detection from Proxy Headers** (when TRUST_PROXY is enabled): - Detects from `X-Forwarded-Proto` and `X-Forwarded-Host` headers - Perfect for Cloudflare, Nginx, and other proxies 3. **Fallback** (when not configured): - Uses `HOST` and `PORT` configuration - Shows `localhost` when bound to `0.0.0.0` **Example scenarios:** ```bash # Behind Cloudflare (auto-detected) TRUST_PROXY=1 # Console shows: https://n8n-mcp.example.com # Explicit configuration BASE_URL=https://api.mycompany.com/mcp # Console shows: https://api.mycompany.com/mcp # Local development (no proxy) # Console shows: http://localhost:3000 ``` ### Trust Proxy for Correct IP Logging When running n8n-MCP behind a reverse proxy (Nginx, Traefik, etc.), enable trust proxy to log real client IPs instead of proxy IPs: ```bash # Enable trust proxy in your environment TRUST_PROXY=1 # Trust 1 proxy hop (standard setup) # or TRUST_PROXY=2 # Trust 2 proxy hops (CDN → Load Balancer → n8n-mcp) ``` **Without TRUST_PROXY:** ``` [INFO] GET /health { ip: '172.19.0.2' } # Docker internal IP ``` **With TRUST_PROXY=1:** ``` [INFO] GET /health { ip: '203.0.113.1' } # Real client IP ``` This is especially important when: - Running in Docker/Kubernetes - Using load balancers - Debugging client issues - Implementing rate limiting ## 🔐 Security Setup ### Authentication All requests require Bearer token authentication: ```bash # Test authentication curl -H "Authorization: Bearer $AUTH_TOKEN" \ https://your-server.com/health ``` ### SSL/HTTPS (Strongly Recommended) Use a reverse proxy for SSL termination: **Nginx example:** ```nginx server { listen 443 ssl; server_name your-domain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location /mcp { proxy_pass http://localhost:3000; proxy_set_header Authorization $http_authorization; # Important: Forward client IP headers 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; } } ``` **Caddy example (automatic HTTPS):** ```caddy your-domain.com { reverse_proxy /mcp localhost:3000 } ``` ## 💻 Client Configuration ### Understanding the Architecture Claude Desktop only supports stdio (standard input/output) communication, but our HTTP server requires HTTP requests. We bridge this gap using one of two methods: ``` Method 1: Using mcp-remote (npm package) Claude Desktop (stdio) → mcp-remote → HTTP Server Method 2: Using custom bridge script Claude Desktop (stdio) → http-bridge.js → HTTP Server ``` ### Method 1: Using mcp-remote (Recommended) **Requirements**: Node.js 18+ installed locally ```json { "mcpServers": { "n8n-remote": { "command": "npx", "args": [ "-y", "mcp-remote", "https://your-server.com/mcp", "--header", "Authorization: Bearer ${AUTH_TOKEN}" ], "env": { "AUTH_TOKEN": "your-auth-token-here" } } } } ``` ### Method 2: Using Custom Bridge Script For local testing or when mcp-remote isn't available: ```json { "mcpServers": { "n8n-local-http": { "command": "node", "args": [ "/path/to/n8n-mcp/scripts/http-bridge.js" ], "env": { "MCP_URL": "http://localhost:3000/mcp", "AUTH_TOKEN": "your-auth-token-here" } } } } ``` ### Local Development with Docker When testing locally with Docker: ```json { "mcpServers": { "n8n-docker-http": { "command": "node", "args": [ "/path/to/n8n-mcp/scripts/http-bridge.js" ], "env": { "MCP_URL": "http://localhost:3001/mcp", "AUTH_TOKEN": "docker-test-token" } } } } ``` ### For Claude Pro/Team Users Use native remote MCP support: 1. Go to Settings > Integrations 2. Add your MCP server URL 3. Complete OAuth flow (if implemented) ⚠️ **Note**: Direct config file entries won't work for remote servers in Pro/Team. ## 🌐 Production Deployment ### Docker Compose Setup ```yaml version: '3.8' services: n8n-mcp: image: ghcr.io/czlonkowski/n8n-mcp:latest container_name: n8n-mcp restart: unless-stopped environment: MCP_MODE: http USE_FIXED_HTTP: true AUTH_TOKEN: ${AUTH_TOKEN:?AUTH_TOKEN required} NODE_ENV: production LOG_LEVEL: info TRUST_PROXY: 1 # Enable if behind reverse proxy # Optional: Enable n8n management tools # N8N_API_URL: ${N8N_API_URL} # N8N_API_KEY: ${N8N_API_KEY} ports: - "127.0.0.1:3000:3000" # Bind to localhost only volumes: - n8n-mcp-data:/app/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 deploy: resources: limits: memory: 512M reservations: memory: 256M volumes: n8n-mcp-data: ``` ### Systemd Service (Linux) Create `/etc/systemd/system/n8n-mcp.service`: ```ini [Unit] Description=n8n-MCP HTTP Server After=network.target [Service] Type=simple User=n8n-mcp WorkingDirectory=/opt/n8n-mcp ExecStart=/usr/bin/node dist/mcp/index.js Restart=always RestartSec=10 # Environment Environment="MCP_MODE=http" Environment="USE_FIXED_HTTP=true" Environment="NODE_ENV=production" EnvironmentFile=/opt/n8n-mcp/.env # Security NoNewPrivileges=true PrivateTmp=true [Install] WantedBy=multi-user.target ``` Enable: ```bash sudo systemctl enable n8n-mcp sudo systemctl start n8n-mcp ``` ## 📡 Monitoring & Maintenance ### Health Checks ```bash # Basic health check curl https://your-server.com/health # Response: { "status": "ok", "mode": "http-fixed", "version": "2.3.2", "uptime": 3600, "memory": { "used": 45, "total": 512, "unit": "MB" } } ``` ### Monitoring with Prometheus ```yaml # prometheus.yml scrape_configs: - job_name: 'n8n-mcp' static_configs: - targets: ['localhost:3000'] metrics_path: '/health' bearer_token: 'your-auth-token' ``` ### Log Management ```bash # Docker logs docker logs -f n8n-mcp --tail 100 # Systemd logs journalctl -u n8n-mcp -f # Log rotation (Docker) docker run -d \ --log-driver json-file \ --log-opt max-size=10m \ --log-opt max-file=3 \ n8n-mcp ``` ## 🔒 Security Best Practices ### 1. Token Management ```bash # Generate strong tokens openssl rand -base64 32 # Rotate tokens regularly AUTH_TOKEN_NEW=$(openssl rand -base64 32) docker exec n8n-mcp env AUTH_TOKEN=$AUTH_TOKEN_NEW ``` ### 2. Network Security - ✅ **Always use HTTPS** in production - ✅ **Firewall rules** to limit access - ✅ **VPN** for internal deployments - ✅ **Rate limiting** at proxy level ### 3. Container Security ```bash # Run as non-root user (already configured) # Read-only filesystem docker run --read-only \ --tmpfs /tmp \ -v n8n-mcp-data:/app/data \ n8n-mcp # Security scanning docker scan ghcr.io/czlonkowski/n8n-mcp:latest ``` ## 🔍 Troubleshooting ### Common Issues **"Stream is not readable" error:** - ✅ Solution: Ensure `USE_FIXED_HTTP=true` is set - This is fixed in v2.3.2 **"TransformStream is not defined" (client-side):** - 🔄 Update Node.js to v18+ on client machine - Or use Docker stdio mode instead **"Why is command 'node' instead of 'docker'?"** - Claude Desktop only supports stdio communication - The bridge script (http-bridge.js or mcp-remote) translates between stdio and HTTP - Docker containers running HTTP servers need this bridge **Bridge script not working:** ```bash # Test the bridge manually export MCP_URL=http://localhost:3000/mcp export AUTH_TOKEN=your-token echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node /path/to/http-bridge.js ``` **Connection refused:** ```bash # Check server is running curl http://localhost:3000/health # Check Docker status docker ps docker logs n8n-mcp # Check firewall sudo ufw status ``` **Authentication failed:** - Verify AUTH_TOKEN matches exactly - Check for extra spaces or quotes - Test with curl first ### Debug Mode ```bash # Enable debug logging LOG_LEVEL=debug docker run ... # Test MCP endpoint directly curl -X POST https://your-server.com/mcp \ -H "Authorization: Bearer $AUTH_TOKEN" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"list_nodes","params":{"limit":5},"id":1}' ``` ## 🚀 Scaling & Performance ### Performance Metrics - Average response time: **~12ms** - Memory usage: **~50-100MB** - Concurrent connections: **100+** - Database queries: **<5ms** with FTS5 ### Horizontal Scaling The server is stateless - scale easily: ```yaml # Docker Swarm example deploy: replicas: 3 update_config: parallelism: 1 delay: 10s restart_policy: condition: on-failure ``` ### Optimization Tips 1. **Use Docker** for consistent performance 2. **Enable HTTP/2** in your reverse proxy 3. **Set up CDN** for static assets 4. **Monitor memory** usage over time ## 👥 Multi-User Service Considerations While n8n-MCP is designed for single-user deployments, you can build a multi-user service: 1. **Use this as a core engine** with your own auth layer 2. **Deploy multiple instances** with different tokens 3. **Add user management** in your proxy layer 4. **Implement rate limiting** per user See [Architecture Guide](./ARCHITECTURE.md) for building multi-user services. ## 🔧 Using n8n Management Tools When n8n API is configured, Claude can manage workflows directly: ### Example: Create a Workflow via Claude ```bash # Test n8n connectivity first curl -X POST https://your-server.com/mcp \ -H "Authorization: Bearer $AUTH_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "n8n_health_check", "params": {}, "id": 1 }' ``` ### Common Use Cases 1. **Workflow Automation**: Claude can create, update, and manage workflows 2. **CI/CD Integration**: Deploy workflows from version control 3. **Workflow Templates**: Claude can apply templates to new workflows 4. **Monitoring**: Track execution status and debug failures 5. **Incremental Updates**: Use diff-based updates for efficient changes ### Security Best Practices for n8n API - 🔐 Use separate API keys for different environments - 🔄 Rotate API keys regularly - 📝 Audit workflow changes via n8n's audit log - 🚫 Never expose n8n API directly to the internet - ✅ Use MCP server as a security layer ## 📦 Updates & Maintenance ```bash # Update to latest version docker pull ghcr.io/czlonkowski/n8n-mcp:latest docker compose up -d # Backup database docker cp n8n-mcp:/app/data/nodes.db ./backup-$(date +%Y%m%d).db # Restore database docker cp ./backup.db n8n-mcp:/app/data/nodes.db docker restart n8n-mcp ``` ## 🆘 Getting Help - 📚 [Full Documentation](https://github.com/czlonkowski/n8n-mcp) - 🐛 [Report Issues](https://github.com/czlonkowski/n8n-mcp/issues) - 💬 [Discussions](https://github.com/czlonkowski/n8n-mcp/discussions)