From 9e7b733f84a2190f38a3cc27ba3ddda6e1f4cbca Mon Sep 17 00:00:00 2001 From: czlonkowski <56956555+czlonkowski@users.noreply.github.com> Date: Tue, 1 Jul 2025 11:50:04 +0200 Subject: [PATCH] chore: bump version to 2.7.2 and update HTTP deployment documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added warning about experimental remote server deployment - Clarified HTTP bridge architecture in documentation - Added deployment scenarios section explaining local vs remote options - Enhanced troubleshooting with bridge-specific issues - Created http-bridge.js for local HTTP testing - Fixed HTTP server to include management tools in tools/list The documentation now clearly explains: - Why "node" command is used instead of "docker" (stdio bridge requirement) - Three deployment scenarios with pros/cons - How to test locally with Docker - Bridge architecture (Claude Desktop → bridge → HTTP server) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docs/HTTP_DEPLOYMENT.md | 130 ++++++++++++++++++++++++++++++++++++++-- package.json | 2 +- scripts/http-bridge.js | 104 ++++++++++++++++++++++++++++++++ src/http-server.ts | 12 +++- 4 files changed, 242 insertions(+), 6 deletions(-) create mode 100755 scripts/http-bridge.js diff --git a/docs/HTTP_DEPLOYMENT.md b/docs/HTTP_DEPLOYMENT.md index 9d02787..71a0e0d 100644 --- a/docs/HTTP_DEPLOYMENT.md +++ b/docs/HTTP_DEPLOYMENT.md @@ -2,7 +2,7 @@ Deploy n8n-MCP as a remote HTTP server to provide n8n knowledge to Claude from anywhere. -📌 **Latest Version**: v2.7.1 (includes fix for n8n management tools in Docker) +📌 **Latest Version**: v2.7.2 (includes fix for n8n management tools in Docker, updated documentation) ## 🎯 Overview @@ -14,6 +14,40 @@ n8n-MCP HTTP mode enables: - 🔧 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:** @@ -29,7 +63,7 @@ n8n-MCP HTTP mode enables: ## 🚀 Quick Start -### Option 1: Docker Deployment (Recommended) +### Option 1: Docker Deployment (Recommended for Production) ```bash # 1. Create environment file @@ -55,7 +89,7 @@ docker run -d \ curl http://localhost:3000/health ``` -### Option 2: Manual Installation +### Option 2: Local Development (Without Docker) ```bash # 1. Clone and setup @@ -75,6 +109,27 @@ export PORT=3000 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 @@ -183,7 +238,19 @@ your-domain.com { ## 💻 Client Configuration -### For All Claude Desktop Users +### 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 @@ -207,6 +274,48 @@ your-domain.com { } ``` +### 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: @@ -391,6 +500,19 @@ docker scan ghcr.io/czlonkowski/n8n-mcp:latest - 🔄 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 diff --git a/package.json b/package.json index 69bce83..6dd3931 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "n8n-mcp", - "version": "2.7.1", + "version": "2.7.2", "description": "Integration between n8n workflow automation and Model Context Protocol (MCP)", "main": "dist/index.js", "scripts": { diff --git a/scripts/http-bridge.js b/scripts/http-bridge.js new file mode 100755 index 0000000..6109d51 --- /dev/null +++ b/scripts/http-bridge.js @@ -0,0 +1,104 @@ +#!/usr/bin/env node + +/** + * HTTP-to-stdio bridge for n8n-MCP + * Connects to n8n-MCP HTTP server and bridges stdio communication + */ + +const http = require('http'); +const readline = require('readline'); + +const MCP_URL = process.env.MCP_URL || 'http://localhost:3000/mcp'; +const AUTH_TOKEN = process.env.AUTH_TOKEN || process.argv[2]; + +if (!AUTH_TOKEN) { + console.error('Error: AUTH_TOKEN environment variable or first argument required'); + process.exit(1); +} + +// Parse URL +const url = new URL(MCP_URL); + +// Create readline interface for stdio +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false +}); + +// Buffer for incomplete JSON messages +let buffer = ''; + +// Handle incoming stdio messages +rl.on('line', async (line) => { + try { + const message = JSON.parse(line); + + // Forward to HTTP server + const options = { + hostname: url.hostname, + port: url.port || 80, + path: url.pathname, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${AUTH_TOKEN}`, + 'Accept': 'application/json, text/event-stream' + } + }; + + const req = http.request(options, (res) => { + let responseData = ''; + + res.on('data', (chunk) => { + responseData += chunk; + }); + + res.on('end', () => { + try { + // Try to parse as JSON + const response = JSON.parse(responseData); + console.log(JSON.stringify(response)); + } catch (e) { + // Handle SSE format + const lines = responseData.split('\n'); + for (const line of lines) { + if (line.startsWith('data: ')) { + try { + const data = JSON.parse(line.substring(6)); + console.log(JSON.stringify(data)); + } catch (e) { + // Ignore parse errors + } + } + } + } + }); + }); + + req.on('error', (error) => { + console.error(JSON.stringify({ + jsonrpc: '2.0', + error: { + code: -32000, + message: `HTTP request failed: ${error.message}` + }, + id: message.id || null + })); + }); + + req.write(JSON.stringify(message)); + req.end(); + } catch (error) { + // Not valid JSON, ignore + } +}); + +// Handle process termination +process.on('SIGTERM', () => { + process.exit(0); +}); + +process.on('SIGINT', () => { + process.exit(0); +}); \ No newline at end of file diff --git a/src/http-server.ts b/src/http-server.ts index e27a79e..a151603 100644 --- a/src/http-server.ts +++ b/src/http-server.ts @@ -6,9 +6,11 @@ import express from 'express'; import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { n8nDocumentationToolsFinal } from './mcp/tools'; +import { n8nManagementTools } from './mcp/tools-n8n-manager'; import { N8NDocumentationMCPServer } from './mcp/server'; import { logger } from './utils/logger'; import { PROJECT_VERSION } from './utils/version'; +import { isN8nApiConfigured } from './config/n8n-api'; import dotenv from 'dotenv'; dotenv.config(); @@ -203,10 +205,18 @@ export async function startFixedHTTPServer() { break; case 'tools/list': + // Use the proper tool list that includes management tools when configured + const tools = [...n8nDocumentationToolsFinal]; + + // Add management tools if n8n API is configured + if (isN8nApiConfigured()) { + tools.push(...n8nManagementTools); + } + response = { jsonrpc: '2.0', result: { - tools: n8nDocumentationToolsFinal + tools }, id: jsonRpcRequest.id };