Add production deployment scripts and quickstart guide
- Add deploy-to-vm.sh script for easy VM deployment - Add systemd service file template - Add Nginx configuration with SSL and rate limiting - Add DEPLOYMENT_QUICKSTART.md for n8ndocumentation.aiservices.pl - Update REMOTE_DEPLOYMENT.md to reference quickstart The deployment process is now streamlined: 1. Copy .env.example to .env 2. Configure for production (domain, auth token) 3. Run ./scripts/deploy-to-vm.sh Tested locally with production configuration - all endpoints working correctly with authentication. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
175
docs/DEPLOYMENT_QUICKSTART.md
Normal file
175
docs/DEPLOYMENT_QUICKSTART.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# Quick Deployment Guide for n8ndocumentation.aiservices.pl
|
||||||
|
|
||||||
|
This guide walks through deploying the n8n Documentation MCP Server to a VM.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Ubuntu 20.04+ VM with root access
|
||||||
|
- Domain pointing to your VM (e.g., n8ndocumentation.aiservices.pl)
|
||||||
|
- Node.js 18+ installed on your local machine
|
||||||
|
- Git installed locally
|
||||||
|
|
||||||
|
## Step 1: Prepare Local Environment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone https://github.com/yourusername/n8n-mcp.git
|
||||||
|
cd n8n-mcp
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Copy and configure environment
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 2: Configure for Production
|
||||||
|
|
||||||
|
Edit `.env` file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Change these values:
|
||||||
|
NODE_ENV=production
|
||||||
|
MCP_DOMAIN=n8ndocumentation.aiservices.pl
|
||||||
|
MCP_CORS=true
|
||||||
|
|
||||||
|
# Generate and set auth token:
|
||||||
|
openssl rand -hex 32
|
||||||
|
# Copy the output and set:
|
||||||
|
MCP_AUTH_TOKEN=your-generated-token-here
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 3: Build and Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build the project
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Run the deployment script
|
||||||
|
./scripts/deploy-to-vm.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
If you don't have SSH key authentication set up, you'll be prompted for the server password.
|
||||||
|
|
||||||
|
## Step 4: Server Setup (First Time Only)
|
||||||
|
|
||||||
|
SSH into your server and run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install Node.js 18+
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||||
|
sudo apt install -y nodejs
|
||||||
|
|
||||||
|
# Install PM2
|
||||||
|
sudo npm install -g pm2
|
||||||
|
|
||||||
|
# Install Nginx
|
||||||
|
sudo apt install -y nginx
|
||||||
|
|
||||||
|
# Copy Nginx configuration
|
||||||
|
sudo cp /opt/n8n-mcp/scripts/nginx-n8n-mcp.conf /etc/nginx/sites-available/n8n-mcp
|
||||||
|
sudo ln -s /etc/nginx/sites-available/n8n-mcp /etc/nginx/sites-enabled/
|
||||||
|
sudo nginx -t
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
|
||||||
|
# Get SSL certificate
|
||||||
|
sudo apt install -y certbot python3-certbot-nginx
|
||||||
|
sudo certbot --nginx -d n8ndocumentation.aiservices.pl
|
||||||
|
|
||||||
|
# Setup PM2 startup
|
||||||
|
pm2 startup
|
||||||
|
# Follow the instructions it provides
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 5: Configure Claude Desktop
|
||||||
|
|
||||||
|
Add to your Claude Desktop configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"n8n-nodes-remote": {
|
||||||
|
"command": "npx",
|
||||||
|
"args": [
|
||||||
|
"-y",
|
||||||
|
"@modelcontextprotocol/client-http",
|
||||||
|
"https://n8ndocumentation.aiservices.pl/mcp"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"MCP_AUTH_TOKEN": "your-auth-token-from-env-file"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verify Deployment
|
||||||
|
|
||||||
|
Test the endpoints:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Health check
|
||||||
|
curl https://n8ndocumentation.aiservices.pl/health
|
||||||
|
|
||||||
|
# Statistics (public)
|
||||||
|
curl https://n8ndocumentation.aiservices.pl/stats
|
||||||
|
|
||||||
|
# MCP endpoint (requires auth)
|
||||||
|
curl -X POST https://n8ndocumentation.aiservices.pl/mcp \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer your-auth-token" \
|
||||||
|
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Management Commands
|
||||||
|
|
||||||
|
On the server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View logs
|
||||||
|
pm2 logs n8n-docs-mcp
|
||||||
|
|
||||||
|
# Restart service
|
||||||
|
pm2 restart n8n-docs-mcp
|
||||||
|
|
||||||
|
# View status
|
||||||
|
pm2 status
|
||||||
|
|
||||||
|
# Rebuild database
|
||||||
|
cd /opt/n8n-mcp
|
||||||
|
npm run db:rebuild:v2
|
||||||
|
pm2 restart n8n-docs-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Service won't start
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
pm2 logs n8n-docs-mcp --lines 50
|
||||||
|
|
||||||
|
# Check if port is in use
|
||||||
|
sudo lsof -i :3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### SSL issues
|
||||||
|
```bash
|
||||||
|
# Renew certificate
|
||||||
|
sudo certbot renew
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database issues
|
||||||
|
```bash
|
||||||
|
# Rebuild database
|
||||||
|
cd /opt/n8n-mcp
|
||||||
|
rm data/nodes-v2.db
|
||||||
|
npm run db:rebuild:v2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
1. Keep your `MCP_AUTH_TOKEN` secret
|
||||||
|
2. Regularly update dependencies: `npm update`
|
||||||
|
3. Monitor logs for suspicious activity
|
||||||
|
4. Use fail2ban to prevent brute force attacks
|
||||||
|
5. Keep your VM updated: `sudo apt update && sudo apt upgrade`
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
This guide explains how to deploy the n8n Documentation MCP Server to a remote VM (such as Hetzner) and connect to it from Claude Desktop.
|
This guide explains how to deploy the n8n Documentation MCP Server to a remote VM (such as Hetzner) and connect to it from Claude Desktop.
|
||||||
|
|
||||||
|
**Quick Start**: For a streamlined deployment to n8ndocumentation.aiservices.pl, see [DEPLOYMENT_QUICKSTART.md](./DEPLOYMENT_QUICKSTART.md).
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The n8n Documentation MCP Server can be deployed as a remote HTTP service, allowing Claude Desktop to access n8n node documentation over the internet. This is useful for:
|
The n8n Documentation MCP Server can be deployed as a remote HTTP service, allowing Claude Desktop to access n8n node documentation over the internet. This is useful for:
|
||||||
|
|||||||
151
scripts/deploy-to-vm.sh
Executable file
151
scripts/deploy-to-vm.sh
Executable file
@@ -0,0 +1,151 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Deployment script for n8n Documentation MCP Server
|
||||||
|
# Target: n8ndocumentation.aiservices.pl
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 n8n Documentation MCP Server - VM Deployment"
|
||||||
|
echo "=============================================="
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
SERVER_USER=${SERVER_USER:-root}
|
||||||
|
SERVER_HOST=${SERVER_HOST:-n8ndocumentation.aiservices.pl}
|
||||||
|
APP_DIR="/opt/n8n-mcp"
|
||||||
|
SERVICE_NAME="n8n-docs-mcp"
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Check if .env exists
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
echo -e "${RED}❌ .env file not found. Please create it from .env.example${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check required environment variables
|
||||||
|
source .env
|
||||||
|
if [ "$MCP_DOMAIN" != "n8ndocumentation.aiservices.pl" ]; then
|
||||||
|
echo -e "${YELLOW}⚠️ Warning: MCP_DOMAIN is not set to n8ndocumentation.aiservices.pl${NC}"
|
||||||
|
read -p "Continue anyway? (y/N) " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$MCP_AUTH_TOKEN" ] || [ "$MCP_AUTH_TOKEN" == "your-secure-auth-token-here" ]; then
|
||||||
|
echo -e "${RED}❌ MCP_AUTH_TOKEN not set or using default value${NC}"
|
||||||
|
echo "Generate a secure token with: openssl rand -hex 32"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ Configuration validated${NC}"
|
||||||
|
|
||||||
|
# Build the project locally
|
||||||
|
echo -e "\n${YELLOW}Building project...${NC}"
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Create deployment package
|
||||||
|
echo -e "\n${YELLOW}Creating deployment package...${NC}"
|
||||||
|
rm -rf deploy-package
|
||||||
|
mkdir -p deploy-package
|
||||||
|
|
||||||
|
# Copy necessary files
|
||||||
|
cp -r dist deploy-package/
|
||||||
|
cp -r data deploy-package/
|
||||||
|
cp package*.json deploy-package/
|
||||||
|
cp .env deploy-package/
|
||||||
|
cp ecosystem.config.js deploy-package/ 2>/dev/null || true
|
||||||
|
|
||||||
|
# Create tarball
|
||||||
|
tar -czf deploy-package.tar.gz deploy-package
|
||||||
|
|
||||||
|
echo -e "${GREEN}✅ Deployment package created${NC}"
|
||||||
|
|
||||||
|
# Upload to server
|
||||||
|
echo -e "\n${YELLOW}Uploading to server...${NC}"
|
||||||
|
scp deploy-package.tar.gz $SERVER_USER@$SERVER_HOST:/tmp/
|
||||||
|
|
||||||
|
# Deploy on server
|
||||||
|
echo -e "\n${YELLOW}Deploying on server...${NC}"
|
||||||
|
ssh $SERVER_USER@$SERVER_HOST << 'ENDSSH'
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Create app directory
|
||||||
|
mkdir -p /opt/n8n-mcp
|
||||||
|
cd /opt/n8n-mcp
|
||||||
|
|
||||||
|
# Stop existing service if running
|
||||||
|
pm2 stop n8n-docs-mcp 2>/dev/null || true
|
||||||
|
|
||||||
|
# Extract deployment package
|
||||||
|
tar -xzf /tmp/deploy-package.tar.gz --strip-components=1
|
||||||
|
rm /tmp/deploy-package.tar.gz
|
||||||
|
|
||||||
|
# Install production dependencies
|
||||||
|
npm ci --only=production
|
||||||
|
|
||||||
|
# Create PM2 ecosystem file if not exists
|
||||||
|
if [ ! -f ecosystem.config.js ]; then
|
||||||
|
cat > ecosystem.config.js << 'EOF'
|
||||||
|
module.exports = {
|
||||||
|
apps: [{
|
||||||
|
name: 'n8n-docs-mcp',
|
||||||
|
script: './dist/index-http.js',
|
||||||
|
instances: 1,
|
||||||
|
autorestart: true,
|
||||||
|
watch: false,
|
||||||
|
max_memory_restart: '1G',
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'production'
|
||||||
|
},
|
||||||
|
error_file: './logs/error.log',
|
||||||
|
out_file: './logs/out.log',
|
||||||
|
log_file: './logs/combined.log',
|
||||||
|
time: true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create logs directory
|
||||||
|
mkdir -p logs
|
||||||
|
|
||||||
|
# Start with PM2
|
||||||
|
pm2 start ecosystem.config.js
|
||||||
|
pm2 save
|
||||||
|
|
||||||
|
echo "✅ Deployment complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Service status:"
|
||||||
|
pm2 status n8n-docs-mcp
|
||||||
|
ENDSSH
|
||||||
|
|
||||||
|
# Clean up local files
|
||||||
|
rm -rf deploy-package deploy-package.tar.gz
|
||||||
|
|
||||||
|
echo -e "\n${GREEN}🎉 Deployment successful!${NC}"
|
||||||
|
echo -e "\nServer endpoints:"
|
||||||
|
echo -e " Health: https://$SERVER_HOST/health"
|
||||||
|
echo -e " Stats: https://$SERVER_HOST/stats"
|
||||||
|
echo -e " MCP: https://$SERVER_HOST/mcp"
|
||||||
|
echo -e "\nClaude Desktop configuration:"
|
||||||
|
echo -e " {
|
||||||
|
\"mcpServers\": {
|
||||||
|
\"n8n-nodes-remote\": {
|
||||||
|
\"command\": \"npx\",
|
||||||
|
\"args\": [
|
||||||
|
\"-y\",
|
||||||
|
\"@modelcontextprotocol/client-http\",
|
||||||
|
\"https://$SERVER_HOST/mcp\"
|
||||||
|
],
|
||||||
|
\"env\": {
|
||||||
|
\"MCP_AUTH_TOKEN\": \"$MCP_AUTH_TOKEN\"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"
|
||||||
29
scripts/n8n-docs-mcp.service
Normal file
29
scripts/n8n-docs-mcp.service
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=n8n Documentation MCP Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=nodejs
|
||||||
|
WorkingDirectory=/opt/n8n-mcp
|
||||||
|
ExecStart=/usr/bin/node /opt/n8n-mcp/dist/index-http.js
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
Environment="NODE_ENV=production"
|
||||||
|
EnvironmentFile=/opt/n8n-mcp/.env
|
||||||
|
|
||||||
|
# Security
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
ReadWritePaths=/opt/n8n-mcp/data /opt/n8n-mcp/logs /opt/n8n-mcp/temp
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
StandardOutput=append:/opt/n8n-mcp/logs/service.log
|
||||||
|
StandardError=append:/opt/n8n-mcp/logs/service-error.log
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
75
scripts/nginx-n8n-mcp.conf
Normal file
75
scripts/nginx-n8n-mcp.conf
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name n8ndocumentation.aiservices.pl;
|
||||||
|
|
||||||
|
# Redirect HTTP to HTTPS
|
||||||
|
location / {
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name n8ndocumentation.aiservices.pl;
|
||||||
|
|
||||||
|
# SSL configuration (managed by Certbot)
|
||||||
|
ssl_certificate /etc/letsencrypt/live/n8ndocumentation.aiservices.pl/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/n8ndocumentation.aiservices.pl/privkey.pem;
|
||||||
|
|
||||||
|
# SSL security settings
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
add_header X-Frame-Options DENY;
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
access_log /var/log/nginx/n8n-mcp-access.log;
|
||||||
|
error_log /var/log/nginx/n8n-mcp-error.log;
|
||||||
|
|
||||||
|
# Proxy settings
|
||||||
|
location / {
|
||||||
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
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_cache_bypass $http_upgrade;
|
||||||
|
|
||||||
|
# Timeouts for MCP operations
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# Increase buffer sizes for large responses
|
||||||
|
proxy_buffer_size 16k;
|
||||||
|
proxy_buffers 8 16k;
|
||||||
|
proxy_busy_buffers_size 32k;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting for API endpoints
|
||||||
|
location /mcp {
|
||||||
|
limit_req zone=mcp_limit burst=10 nodelay;
|
||||||
|
proxy_pass http://localhost:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# Larger timeouts for MCP
|
||||||
|
proxy_connect_timeout 120s;
|
||||||
|
proxy_send_timeout 120s;
|
||||||
|
proxy_read_timeout 120s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rate limiting zone
|
||||||
|
limit_req_zone $binary_remote_addr zone=mcp_limit:10m rate=10r/s;
|
||||||
Reference in New Issue
Block a user