diff --git a/README.md b/README.md index e1f0e97..90da562 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![GitHub stars](https://img.shields.io/github/stars/czlonkowski/n8n-mcp?style=social)](https://github.com/czlonkowski/n8n-mcp) -[![Version](https://img.shields.io/badge/version-2.8.3-blue.svg)](https://github.com/czlonkowski/n8n-mcp) +[![Version](https://img.shields.io/badge/version-2.9.0-blue.svg)](https://github.com/czlonkowski/n8n-mcp) [![npm version](https://img.shields.io/npm/v/n8n-mcp.svg)](https://www.npmjs.com/package/n8n-mcp) [![codecov](https://codecov.io/gh/czlonkowski/n8n-mcp/graph/badge.svg?token=YOUR_TOKEN)](https://codecov.io/gh/czlonkowski/n8n-mcp) [![Tests](https://img.shields.io/badge/tests-1356%20passing-brightgreen.svg)](https://github.com/czlonkowski/n8n-mcp/actions) @@ -322,6 +322,14 @@ Deploy n8n-MCP to Railway's cloud platform with zero configuration: **Restart Claude Desktop after updating configuration** - That's it! 🎉 +## 🔧 n8n Integration + +Want to use n8n-MCP with your n8n instance? Check out our comprehensive [n8n Deployment Guide](./docs/N8N_DEPLOYMENT.md) for: +- Local testing with the MCP Client Tool node +- Production deployment with Docker Compose +- Cloud deployment on Hetzner, AWS, and other providers +- Troubleshooting and security best practices + ## 💻 Connect your IDE n8n-MCP works with multiple AI-powered IDEs and tools. Choose your preferred development environment: diff --git a/data/nodes.db b/data/nodes.db index 5340be9..dba4d98 100644 Binary files a/data/nodes.db and b/data/nodes.db differ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 5edc700..c6aaa66 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -5,6 +5,73 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.9.0] - 2025-08-01 + +### Added +- **n8n Integration with MCP Client Tool Support**: Complete n8n integration enabling n8n-mcp to run as MCP server within n8n workflows + - Full compatibility with n8n's MCP Client Tool node + - Dedicated n8n mode (`N8N_MODE=true`) for optimized operation + - Workflow examples and n8n-friendly tool descriptions + - Quick deployment script (`deploy/quick-deploy-n8n.sh`) for easy setup + - Docker configuration specifically for n8n deployment (`Dockerfile.n8n`, `docker-compose.n8n.yml`) + - Test scripts for n8n integration (`test-n8n-integration.sh`, `test-n8n-mode.sh`) +- **n8n Deployment Documentation**: Comprehensive guide for deploying n8n-MCP with n8n (`docs/N8N_DEPLOYMENT.md`) + - Local testing instructions using `/scripts/test-n8n-mode.sh` + - Production deployment with Docker Compose + - Cloud deployment guide for Hetzner, AWS, and other providers + - n8n MCP Client Tool setup and configuration + - Troubleshooting section with common issues and solutions +- **Protocol Version Negotiation**: Intelligent client detection for n8n compatibility + - Automatically detects n8n clients and uses protocol version 2024-11-05 + - Standard MCP clients get the latest version (2025-03-26) + - Improves compatibility with n8n's MCP Client Tool node + - Comprehensive protocol negotiation test suite +- **Comprehensive Parameter Validation**: Enhanced validation for all MCP tools + - Clear, user-friendly error messages for invalid parameters + - Numeric parameter conversion and edge case handling + - 52 new parameter validation tests + - Consistent error format across all tools +- **Session Management**: Improved session handling with comprehensive test coverage + - Fixed memory leak potential with async cleanup + - Better connection close handling + - Enhanced session management tests +- **Dynamic README Version Badge**: Made version badge update automatically from package.json + - Added `update-readme-version.js` script + - Enhanced `sync-runtime-version.js` to update README badges + - Version badge now stays in sync during publish workflow + +### Fixed +- **Docker Build Optimization**: Fixed Dockerfile.n8n using wrong dependencies + - Now uses `package.runtime.json` instead of full `package.json` + - Reduces build time from 13+ minutes to 1-2 minutes + - Fixes ARM64 build failures due to network timeouts + - Reduces image size from ~1.5GB to ~280MB +- **CI Test Failures**: Resolved Docker entrypoint permission issues + - Updated tests to accept dynamic UID range (10000-59999) + - Enhanced lock file creation with better error recovery + - Fixed TypeScript lint errors in test files + - Fixed flaky performance tests with deterministic versions +- **Schema Validation Issues**: Fixed n8n nested output format compatibility + - Added validation for n8n's nested output workaround + - Fixed schema validation errors with n8n MCP Client Tool + - Enhanced error sanitization for production environments + +### Changed +- **Memory Management**: Improved session cleanup to prevent memory leaks +- **Error Handling**: Enhanced error sanitization for production environments +- **Docker Security**: Using unpredictable UIDs/GIDs (10000-59999 range) for better security +- **CI/CD Configuration**: Made codecov patch coverage informational to prevent CI failures on infrastructure code +- **Test Scripts**: Enhanced with Docker auto-installation and better user experience + - Added colored output and progress indicators + - Automatic Docker installation for multiple operating systems + - n8n API key flow for management tools + +### Security +- **Enhanced Docker Security**: Dynamic UID/GID generation for containers +- **Error Sanitization**: Improved error messages to prevent information leakage +- **Permission Handling**: Better permission management for mounted volumes +- **Input Validation**: Comprehensive parameter validation prevents injection attacks + ## [2.8.3] - 2025-07-31 ### Fixed diff --git a/docs/N8N_DEPLOYMENT.md b/docs/N8N_DEPLOYMENT.md new file mode 100644 index 0000000..764e046 --- /dev/null +++ b/docs/N8N_DEPLOYMENT.md @@ -0,0 +1,407 @@ +# n8n-MCP Deployment Guide + +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. + +## Table of Contents +- [Overview](#overview) +- [Local Testing](#local-testing) +- [Production Deployment](#production-deployment) + - [Same Server as n8n](#same-server-as-n8n) + - [Different Server (Cloud Deployment)](#different-server-cloud-deployment) +- [Connecting n8n to n8n-MCP](#connecting-n8n-to-n8n-mcp) +- [Security & Best Practices](#security--best-practices) +- [Troubleshooting](#troubleshooting) + +## Overview + +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: +- AI-powered workflow creation and validation +- Access to documentation for 500+ n8n nodes +- Workflow management through the n8n API +- Real-time configuration validation + +## Local Testing + +### Quick Test Script + +Test n8n-MCP locally with the provided test script: + +```bash +# 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 test script +./scripts/test-n8n-mode.sh +``` + +This script will: +1. Start n8n-MCP in n8n mode on port 3001 +2. Enable debug logging for troubleshooting +3. Run comprehensive protocol tests +4. Display results and any issues found + +### Manual Local Setup + +For development or custom testing: + +1. **Prerequisites**: + - n8n instance running (local or remote) + - n8n API key (from n8n Settings → API) + +2. **Start n8n-MCP**: +```bash +# Set environment variables +export N8N_MODE=true +export N8N_API_URL=http://localhost:5678 # Your n8n instance URL +export N8N_API_KEY=your-api-key-here # Your n8n API key +export MCP_AUTH_TOKEN=test-token-minimum-32-chars-long +export PORT=3001 + +# Start the server +npm start +``` + +3. **Verify it's running**: +```bash +# Check health +curl http://localhost:3001/health + +# Check MCP protocol endpoint +curl http://localhost:3001/mcp +# Should return: {"protocolVersion":"2024-11-05"} for n8n compatibility +``` + +## Production Deployment + +### Same Server as n8n + +If you're running n8n-MCP on the same server as your n8n instance: + +1. **Using Docker** (Recommended): +```bash +# 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 N8N_API_URL=http://n8n:5678 \ + -e N8N_API_KEY=your-n8n-api-key \ + -e MCP_AUTH_TOKEN=$(openssl rand -hex 32) \ + -e LOG_LEVEL=info \ + --restart unless-stopped \ + ghcr.io/czlonkowski/n8n-mcp:latest +``` + +2. **Using systemd** (for native installation): +```bash +# 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="N8N_API_URL=http://localhost:5678" +Environment="N8N_API_KEY=your-n8n-api-key" +Environment="MCP_AUTH_TOKEN=your-secure-token" +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 +``` + +### Different Server (Cloud Deployment) + +Deploy n8n-MCP on a separate server from your n8n instance: + +#### Quick Docker Deployment + +```bash +# On your cloud server (Hetzner, AWS, DigitalOcean, etc.) +docker run -d \ + --name n8n-mcp \ + -p 3000:3000 \ + -e N8N_MODE=true \ + -e N8N_API_URL=https://your-n8n-instance.com \ + -e N8N_API_KEY=your-n8n-api-key \ + -e MCP_AUTH_TOKEN=$(openssl rand -hex 32) \ + -e LOG_LEVEL=info \ + --restart unless-stopped \ + ghcr.io/czlonkowski/n8n-mcp:latest + +# Save the MCP_AUTH_TOKEN for later use! +``` + +#### Full Production Setup (Hetzner/AWS/DigitalOcean) + +1. **Server Requirements**: + - **Minimal**: 1 vCPU, 1GB RAM (CX11 on Hetzner) + - **Recommended**: 2 vCPU, 2GB RAM + - **OS**: Ubuntu 22.04 LTS + +2. **Initial Setup**: +```bash +# 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 +``` + +3. **Deploy n8n-MCP with SSL** (using Caddy for automatic HTTPS): +```bash +# Create docker-compose.yml +cat > docker-compose.yml << 'EOF' +version: '3.8' + +services: + n8n-mcp: + image: ghcr.io/czlonkowski/n8n-mcp:latest + container_name: n8n-mcp + restart: unless-stopped + environment: + - N8N_MODE=true + - N8N_API_URL=${N8N_API_URL} + - N8N_API_KEY=${N8N_API_KEY} + - MCP_AUTH_TOKEN=${MCP_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 + +# Create Caddyfile +cat > Caddyfile << 'EOF' +mcp.yourdomain.com { + reverse_proxy n8n-mcp:3000 +} +EOF + +# Create .env file +cat > .env << EOF +N8N_API_URL=https://your-n8n-instance.com +N8N_API_KEY=your-n8n-api-key-here +MCP_AUTH_TOKEN=$(openssl rand -hex 32) +EOF + +# Save the MCP_AUTH_TOKEN! +echo "Your MCP_AUTH_TOKEN is:" +grep MCP_AUTH_TOKEN .env + +# Start services +docker compose up -d +``` + +#### Cloud Provider Tips + +**AWS EC2**: +- Security Group: Open port 3000 (or 443 with HTTPS) +- Instance Type: t3.micro is sufficient +- Use Elastic IP for stable addressing + +**DigitalOcean**: +- Droplet: Basic ($6/month) is enough +- Enable backups for production use + +**Google Cloud**: +- Machine Type: e2-micro (free tier eligible) +- Use Cloud Load Balancer for SSL + +## Connecting n8n to n8n-MCP + +### Configure n8n MCP Client Tool + +1. **In your n8n workflow**, add the **MCP Client Tool** node + +2. **Configure the connection**: + ``` + Server URL: + - Same server: http://localhost:3000 + - Docker network: http://n8n-mcp:3000 + - Different server: https://mcp.yourdomain.com + + Auth Token: [Your MCP_AUTH_TOKEN] + + Transport: HTTP Streamable (SSE) + ``` + +3. **Test the connection** by selecting a simple tool like `list_nodes` + +### Available Tools + +Once connected, you can use these MCP tools in n8n: + +**Documentation Tools** (No API key required): +- `list_nodes` - List all n8n nodes with filtering +- `search_nodes` - Search nodes by keyword +- `get_node_info` - Get detailed node information +- `get_node_essentials` - Get only essential properties +- `validate_workflow` - Validate workflow configurations +- `get_node_documentation` - Get human-readable docs + +**Management Tools** (Requires n8n API key): +- `n8n_create_workflow` - Create new workflows +- `n8n_update_workflow` - Update existing workflows +- `n8n_get_workflow` - Retrieve workflow details +- `n8n_list_workflows` - List all workflows +- `n8n_trigger_webhook_workflow` - Trigger webhook workflows + +### Using with AI Agents + +Connect n8n-MCP to AI Agent nodes for intelligent automation: + +1. **Add an AI Agent node** (e.g., OpenAI, Anthropic) +2. **Connect MCP Client Tool** to the Agent's tool input +3. **Configure prompts** for workflow creation: + +``` +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 +``` + +## Security & Best Practices + +### Authentication +- **MCP_AUTH_TOKEN**: Always use a strong, random token (32+ characters) +- **N8N_API_KEY**: Only required for workflow management features +- Store tokens in environment variables or secure vaults + +### Network Security +- **Use HTTPS** in production (Caddy/Nginx/Traefik) +- **Firewall**: Only expose necessary ports (3000 or 443) +- **IP Whitelisting**: Consider restricting access to known n8n instances + +### Docker Security +- Run containers with `--read-only` flag if possible +- Use specific image versions instead of `:latest` in production +- Regular updates: `docker pull ghcr.io/czlonkowski/n8n-mcp:latest` + +## Troubleshooting + +### Connection Issues + +**"Connection refused" in n8n MCP Client Tool** +- Check n8n-MCP is running: `docker ps` or `systemctl status n8n-mcp` +- Verify port is accessible: `curl http://your-server:3000/health` +- Check firewall rules allow port 3000 + +**"Invalid auth token"** +- Ensure MCP_AUTH_TOKEN matches exactly (no extra spaces) +- Token must be at least 32 characters long +- Check for special characters that might need escaping + +**"Cannot connect to n8n API"** +- Verify N8N_API_URL is correct (include http:// or https://) +- Check n8n API key is valid and has necessary permissions +- Ensure n8n instance is accessible from n8n-MCP server + +### Protocol Issues + +**"Protocol version mismatch"** +- n8n-MCP automatically uses version 2024-11-05 for n8n +- Update to latest n8n-MCP version if issues persist +- Check `/mcp` endpoint returns correct version + +**"Schema validation errors"** +- Known issue with n8n's nested output handling +- n8n-MCP includes workarounds +- Enable debug mode to see detailed errors + +### Debugging + +1. **Enable debug mode**: +```bash +docker run -d \ + --name n8n-mcp \ + -e DEBUG_MCP=true \ + -e LOG_LEVEL=debug \ + # ... other settings +``` + +2. **Check logs**: +```bash +# Docker +docker logs n8n-mcp -f --tail 100 + +# Systemd +journalctl -u n8n-mcp -f +``` + +3. **Test endpoints**: +```bash +# Health check +curl http://localhost:3000/health + +# Protocol version +curl http://localhost:3000/mcp + +# List tools (requires auth) +curl -X POST http://localhost:3000 \ + -H "Authorization: Bearer YOUR_MCP_AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"tools/list","id":1}' +``` + +## Performance Tips + +- **Minimal deployment**: 1 vCPU, 1GB RAM is sufficient +- **Database**: Pre-built SQLite database (~15MB) loads quickly +- **Response time**: Average 12ms for queries +- **Caching**: Built-in 15-minute cache for repeated queries + +## Next Steps + +- Test your setup with the [MCP Client Tool in n8n](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-langchain.mcpclienttool/) +- Explore [available MCP tools](../README.md#-available-mcp-tools) +- Build AI-powered workflows with [AI Agent nodes](https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmagent/) +- Join the [n8n Community](https://community.n8n.io) for ideas and support + +--- + +Need help? Open an issue on [GitHub](https://github.com/czlonkowski/n8n-mcp/issues) or check the [n8n forums](https://community.n8n.io). \ No newline at end of file diff --git a/package.json b/package.json index 860ef74..193db58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp", - "version": "2.8.3", + "version": "2.9.0", "description": "Integration between n8n workflow automation and Model Context Protocol (MCP)", "main": "dist/index.js", "bin": { @@ -75,6 +75,7 @@ "db:init": "node -e \"new (require('./dist/services/sqlite-storage-service').SQLiteStorageService)(); console.log('Database initialized')\"", "docs:rebuild": "ts-node src/scripts/rebuild-database.ts", "sync:runtime-version": "node scripts/sync-runtime-version.js", + "update:readme-version": "node scripts/update-readme-version.js", "prepare:publish": "./scripts/publish-npm.sh", "update:all": "./scripts/update-and-publish-prep.sh" }, diff --git a/package.runtime.json b/package.runtime.json index 944870b..2c7c16e 100644 --- a/package.runtime.json +++ b/package.runtime.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp-runtime", - "version": "2.8.3", + "version": "2.9.0", "description": "n8n MCP Server Runtime Dependencies Only", "private": true, "dependencies": { diff --git a/scripts/sync-runtime-version.js b/scripts/sync-runtime-version.js index 8404c57..27b79b9 100755 --- a/scripts/sync-runtime-version.js +++ b/scripts/sync-runtime-version.js @@ -1,8 +1,8 @@ #!/usr/bin/env node /** - * Sync version from package.json to package.runtime.json - * This ensures both files always have the same version + * Sync version from package.json to package.runtime.json and README.md + * This ensures all files always have the same version */ const fs = require('fs'); @@ -10,6 +10,7 @@ const path = require('path'); const packageJsonPath = path.join(__dirname, '..', 'package.json'); const packageRuntimePath = path.join(__dirname, '..', 'package.runtime.json'); +const readmePath = path.join(__dirname, '..', 'README.md'); try { // Read package.json @@ -34,6 +35,19 @@ try { } else { console.log(`✓ package.runtime.json already at version ${version}`); } + + // Update README.md version badge + let readmeContent = fs.readFileSync(readmePath, 'utf-8'); + const versionBadgeRegex = /(\[!\[Version\]\(https:\/\/img\.shields\.io\/badge\/version-)[^-]+(-.+?\)\])/; + const newVersionBadge = `$1${version}$2`; + const updatedReadmeContent = readmeContent.replace(versionBadgeRegex, newVersionBadge); + + if (updatedReadmeContent !== readmeContent) { + fs.writeFileSync(readmePath, updatedReadmeContent); + console.log(`✅ Updated README.md version badge to ${version}`); + } else { + console.log(`✓ README.md already has version badge ${version}`); + } } catch (error) { console.error('❌ Error syncing version:', error.message); process.exit(1); diff --git a/scripts/update-and-publish-prep.sh b/scripts/update-and-publish-prep.sh index a983925..1679ac4 100755 --- a/scripts/update-and-publish-prep.sh +++ b/scripts/update-and-publish-prep.sh @@ -90,15 +90,14 @@ npm version patch --no-git-tag-version # Get new project version NEW_PROJECT=$(node -e "console.log(require('./package.json').version)") -# 10. Update version badge in README +# 10. Update n8n version badge in README echo "" -echo -e "${BLUE}📝 Updating README badges...${NC}" -sed -i.bak "s/version-[0-9.]*/version-$NEW_PROJECT/" README.md && rm README.md.bak +echo -e "${BLUE}📝 Updating n8n version badge...${NC}" sed -i.bak "s/n8n-v[0-9.]*/n8n-$NEW_N8N/" README.md && rm README.md.bak -# 11. Sync runtime version +# 11. Sync runtime version (this also updates the version badge in README) echo "" -echo -e "${BLUE}🔄 Syncing runtime version...${NC}" +echo -e "${BLUE}🔄 Syncing runtime version and updating version badge...${NC}" npm run sync:runtime-version # 12. Get update details for commit message diff --git a/scripts/update-readme-version.js b/scripts/update-readme-version.js new file mode 100755 index 0000000..9edb512 --- /dev/null +++ b/scripts/update-readme-version.js @@ -0,0 +1,25 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +// Read package.json +const packageJsonPath = path.join(__dirname, '..', 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); +const version = packageJson.version; + +// Read README.md +const readmePath = path.join(__dirname, '..', 'README.md'); +let readmeContent = fs.readFileSync(readmePath, 'utf8'); + +// Update the version badge on line 5 +// The pattern matches: [![Version](https://img.shields.io/badge/version-X.X.X-blue.svg)] +const versionBadgeRegex = /(\[!\[Version\]\(https:\/\/img\.shields\.io\/badge\/version-)[^-]+(-.+?\)\])/; +const newVersionBadge = `$1${version}$2`; + +readmeContent = readmeContent.replace(versionBadgeRegex, newVersionBadge); + +// Write back to README.md +fs.writeFileSync(readmePath, readmeContent); + +console.log(`✅ Updated README.md version badge to v${version}`); \ No newline at end of file