chore: bump version to 2.7.2 and update HTTP deployment documentation
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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": {
|
||||
|
||||
104
scripts/http-bridge.js
Executable file
104
scripts/http-bridge.js
Executable file
@@ -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);
|
||||
});
|
||||
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user