docs: reorganize documentation files and update Docker build process

This commit is contained in:
czlonkowski
2025-06-13 17:20:31 +02:00
parent 12bef3d98e
commit d6f38dc1c4
18 changed files with 1201 additions and 2480 deletions

View File

@@ -35,6 +35,7 @@ jobs:
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}

View File

@@ -13,8 +13,6 @@ COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Build TypeScript
RUN npm run build
# Pre-initialize database during build
RUN mkdir -p /app/data && npm run rebuild || echo "Database will be initialized at runtime"
# Stage 3: Simple Runtime
FROM node:20-alpine AS runtime
@@ -32,8 +30,8 @@ RUN npm ci --only=production && \
# Copy built application
COPY --from=builder /app/dist ./dist
# Copy pre-built database if it exists
COPY --from=builder /app/data/nodes.db ./data/nodes.db 2>/dev/null || true
# Create data directory
RUN mkdir -p /app/data
# Copy necessary source files for database initialization
COPY src/database/schema.sql ./src/database/

View File

@@ -1,792 +0,0 @@
# HTTP Implementation Technical Guide
## Deep Technical Analysis
### Current MCP Transport Mechanism
The current implementation uses `StdioServerTransport` which:
1. Reads JSON-RPC messages from stdin
2. Writes responses to stdout
3. Maintains a single, persistent connection
4. Has implicit trust (local execution)
### Target HTTP Transport Mechanism
The `StreamableHTTPServerTransport`:
1. Accepts HTTP POST requests with JSON-RPC payloads
2. Can upgrade to Server-Sent Events (SSE) for server-initiated messages
3. Requires session management for state persistence
4. Needs explicit authentication
## Detailed Implementation Steps
### Step 1: Install Required Dependencies
```bash
npm install express cors helmet compression dotenv
npm install --save-dev @types/express @types/cors
```
### Step 2: Create HTTP Server Structure
```typescript
// src/mcp/transports/http-transport.ts
import express, { Request, Response, NextFunction } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import { randomUUID } from 'crypto';
import {
StreamableHTTPServerTransport,
StreamableHTTPServerTransportOptions
} from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { logger } from '../../utils/logger';
export interface HTTPServerConfig {
port: number;
host: string;
authToken?: string;
corsOrigins?: string[];
sessionTimeout?: number; // in milliseconds
maxSessions?: number;
}
export interface MCPSession {
id: string;
transport: StreamableHTTPServerTransport;
server: any; // Your MCP server instance
createdAt: Date;
lastActivity: Date;
metadata?: Record<string, any>;
}
export class HTTPTransportServer {
private app: express.Application;
private sessions: Map<string, MCPSession> = new Map();
private config: HTTPServerConfig;
private cleanupInterval?: NodeJS.Timeout;
constructor(config: HTTPServerConfig) {
this.config = {
sessionTimeout: 30 * 60 * 1000, // 30 minutes default
maxSessions: 100,
...config
};
this.app = express();
this.setupMiddleware();
this.setupRoutes();
this.startSessionCleanup();
}
private setupMiddleware(): void {
// Security headers
this.app.use(helmet());
// CORS configuration
this.app.use(cors({
origin: this.config.corsOrigins || true,
credentials: true,
methods: ['POST', 'GET', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'MCP-Session-ID']
}));
// Compression
this.app.use(compression());
// JSON parsing with size limit
this.app.use(express.json({ limit: '10mb' }));
// Request logging
this.app.use((req, res, next) => {
logger.info(`${req.method} ${req.path}`, {
sessionId: req.headers['mcp-session-id'],
ip: req.ip
});
next();
});
}
private setupRoutes(): void {
// Health check endpoint
this.app.get('/health', (req, res) => {
res.json({
status: 'ok',
sessions: this.sessions.size,
uptime: process.uptime()
});
});
// Main MCP endpoint
this.app.post('/mcp',
this.authenticateRequest.bind(this),
this.handleMCPRequest.bind(this)
);
// Session management endpoint
this.app.get('/sessions',
this.authenticateRequest.bind(this),
(req, res) => {
const sessionInfo = Array.from(this.sessions.entries()).map(([id, session]) => ({
id,
createdAt: session.createdAt,
lastActivity: session.lastActivity,
metadata: session.metadata
}));
res.json({ sessions: sessionInfo });
}
);
}
private authenticateRequest(req: Request, res: Response, next: NextFunction): void {
if (!this.config.authToken) {
return next();
}
const authHeader = req.headers.authorization;
const token = authHeader?.startsWith('Bearer ')
? authHeader.slice(7)
: authHeader;
if (token !== this.config.authToken) {
logger.warn('Authentication failed', { ip: req.ip });
return res.status(401).json({ error: 'Unauthorized' });
}
next();
}
private async handleMCPRequest(req: Request, res: Response): Promise<void> {
try {
const sessionId = req.headers['mcp-session-id'] as string;
let session = sessionId ? this.sessions.get(sessionId) : null;
// Create new session if needed
if (!session) {
if (this.sessions.size >= this.config.maxSessions!) {
return res.status(503).json({ error: 'Server at capacity' });
}
session = await this.createSession();
res.setHeader('MCP-Session-ID', session.id);
}
// Update last activity
session.lastActivity = new Date();
// Handle the request through the transport
await session.transport.handleRequest(req, res);
} catch (error) {
logger.error('Error handling MCP request', error);
res.status(500).json({
error: 'Internal server error',
message: error instanceof Error ? error.message : 'Unknown error'
});
}
}
private async createSession(): Promise<MCPSession> {
const id = randomUUID();
const transport = new StreamableHTTPServerTransport();
// Create your MCP server instance here
const { N8NDocumentationMCPServer } = await import('../server-update');
const server = new N8NDocumentationMCPServer();
// Connect transport to server
await server.connect(transport);
const session: MCPSession = {
id,
transport,
server,
createdAt: new Date(),
lastActivity: new Date()
};
this.sessions.set(id, session);
logger.info('Created new session', { sessionId: id });
return session;
}
private startSessionCleanup(): void {
this.cleanupInterval = setInterval(() => {
const now = Date.now();
const timeout = this.config.sessionTimeout!;
for (const [id, session] of this.sessions.entries()) {
if (now - session.lastActivity.getTime() > timeout) {
this.destroySession(id);
}
}
}, 60000); // Check every minute
}
private destroySession(id: string): void {
const session = this.sessions.get(id);
if (session) {
// Cleanup server resources
if (session.server && typeof session.server.close === 'function') {
session.server.close();
}
this.sessions.delete(id);
logger.info('Destroyed session', { sessionId: id });
}
}
public start(): void {
this.app.listen(this.config.port, this.config.host, () => {
logger.info(`HTTP MCP Server listening on ${this.config.host}:${this.config.port}`);
});
}
public stop(): void {
if (this.cleanupInterval) {
clearInterval(this.cleanupInterval);
}
// Cleanup all sessions
for (const id of this.sessions.keys()) {
this.destroySession(id);
}
}
}
```
### Step 3: Modify MCP Server for Transport Flexibility
```typescript
// src/mcp/server-update.ts modifications
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { Transport } from '@modelcontextprotocol/sdk/types.js';
export class N8NDocumentationMCPServer {
private server: Server;
// ... existing code ...
// Add connect method to accept any transport
async connect(transport: Transport): Promise<void> {
await this.ensureInitialized();
await this.server.connect(transport);
logger.info('MCP Server connected with transport', {
transportType: transport.constructor.name
});
}
// Modify run method to be transport-agnostic
async run(transport?: Transport): Promise<void> {
await this.ensureInitialized();
if (!transport) {
// Default to stdio for backward compatibility
transport = new StdioServerTransport();
}
await this.connect(transport);
logger.info('n8n Documentation MCP Server running');
}
}
```
### Step 4: Create Unified Entry Point
```typescript
// src/mcp/index-universal.ts
#!/usr/bin/env node
import { N8NDocumentationMCPServer } from './server-update';
import { HTTPTransportServer } from './transports/http-transport';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { logger } from '../utils/logger';
import dotenv from 'dotenv';
// Load environment variables
dotenv.config();
interface CLIArgs {
mode: 'stdio' | 'http';
port?: number;
host?: string;
authToken?: string;
}
function parseArgs(): CLIArgs {
const args = process.argv.slice(2);
const config: CLIArgs = {
mode: 'stdio' // default
};
for (let i = 0; i < args.length; i++) {
switch (args[i]) {
case '--mode':
config.mode = args[++i] as 'stdio' | 'http';
break;
case '--port':
config.port = parseInt(args[++i]);
break;
case '--host':
config.host = args[++i];
break;
case '--auth-token':
config.authToken = args[++i];
break;
}
}
// Allow environment variables to override
config.mode = (process.env.MCP_MODE as any) || config.mode;
config.port = parseInt(process.env.MCP_PORT || '') || config.port || 3000;
config.host = process.env.MCP_HOST || config.host || '0.0.0.0';
config.authToken = process.env.MCP_AUTH_TOKEN || config.authToken;
return config;
}
async function main() {
try {
const config = parseArgs();
logger.info('Starting MCP server', config);
if (config.mode === 'http') {
// HTTP mode - server manages its own lifecycle
const httpServer = new HTTPTransportServer({
port: config.port!,
host: config.host!,
authToken: config.authToken,
corsOrigins: process.env.MCP_CORS_ORIGINS?.split(','),
sessionTimeout: parseInt(process.env.MCP_SESSION_TIMEOUT || '') || undefined,
maxSessions: parseInt(process.env.MCP_MAX_SESSIONS || '') || undefined
});
httpServer.start();
// Graceful shutdown
process.on('SIGINT', () => {
logger.info('Shutting down HTTP server...');
httpServer.stop();
process.exit(0);
});
} else {
// Stdio mode - traditional single instance
const server = new N8NDocumentationMCPServer();
await server.run(); // Uses stdio by default
}
} catch (error) {
logger.error('Failed to start MCP server', error);
process.exit(1);
}
}
if (require.main === module) {
main();
}
```
### Step 5: Environment Configuration
```bash
# .env.example
# Server mode: stdio or http
MCP_MODE=http
# HTTP server configuration
MCP_PORT=3000
MCP_HOST=0.0.0.0
MCP_AUTH_TOKEN=your-secure-token-here
# CORS origins (comma-separated)
MCP_CORS_ORIGINS=https://claude.ai,http://localhost:3000
# Session management
MCP_SESSION_TIMEOUT=1800000 # 30 minutes in milliseconds
MCP_MAX_SESSIONS=100
# Existing configuration
NODE_ENV=production
LOG_LEVEL=info
```
### Step 6: Docker Configuration for Remote Deployment
```dockerfile
# Dockerfile.http
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci
# Copy source code
COPY . .
# Build the application
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
# Install production dependencies only
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# Copy built application
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/data ./data
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# Change ownership
RUN chown -R nodejs:nodejs /app
USER nodejs
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1); })"
# Start the server
CMD ["node", "dist/mcp/index-universal.js", "--mode", "http"]
```
### Step 7: Production Deployment Script
```bash
#!/bin/bash
# deploy.sh
# Configuration
DOMAIN="mcp.your-domain.com"
EMAIL="your-email@example.com"
AUTH_TOKEN=$(openssl rand -base64 32)
# Update system
sudo apt update && sudo apt upgrade -y
# Install dependencies
sudo apt install -y docker.io docker-compose nginx certbot python3-certbot-nginx
# Clone repository
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
# Create .env file
cat > .env << EOF
MCP_MODE=http
MCP_PORT=3000
MCP_HOST=0.0.0.0
MCP_AUTH_TOKEN=$AUTH_TOKEN
MCP_CORS_ORIGINS=https://claude.ai
NODE_ENV=production
LOG_LEVEL=info
EOF
# Build and run with Docker
docker build -f Dockerfile.http -t n8n-mcp-http .
docker run -d \
--name n8n-mcp \
--restart always \
-p 127.0.0.1:3000:3000 \
--env-file .env \
n8n-mcp-http
# Configure Nginx
sudo tee /etc/nginx/sites-available/mcp << EOF
server {
listen 80;
server_name $DOMAIN;
return 301 https://\$server_name\$request_uri;
}
server {
listen 443 ssl http2;
server_name $DOMAIN;
# SSL will be configured by certbot
location /mcp {
proxy_pass http://127.0.0.1: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 long-running requests
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
location /health {
proxy_pass http://127.0.0.1:3000;
}
}
EOF
# Enable site
sudo ln -s /etc/nginx/sites-available/mcp /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# Get SSL certificate
sudo certbot --nginx -d $DOMAIN --email $EMAIL --agree-tos --non-interactive
echo "Deployment complete!"
echo "Your MCP server is available at: https://$DOMAIN/mcp"
echo "Auth token: $AUTH_TOKEN"
echo "Save this token - you'll need it for client configuration"
```
### Step 8: Client Configuration with mcp-remote
```json
// claude_desktop_config.json for remote server
{
"mcpServers": {
"n8n-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"connect",
"https://mcp.your-domain.com/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-auth-token-here"
}
}
}
}
```
### Step 9: Monitoring and Logging
```typescript
// src/utils/monitoring.ts
import { Request, Response, NextFunction } from 'express';
export interface RequestMetrics {
path: string;
method: string;
statusCode: number;
duration: number;
sessionId?: string;
timestamp: Date;
}
export class MonitoringService {
private metrics: RequestMetrics[] = [];
public middleware() {
return (req: Request, res: Response, next: NextFunction) => {
const start = Date.now();
res.on('finish', () => {
const metric: RequestMetrics = {
path: req.path,
method: req.method,
statusCode: res.statusCode,
duration: Date.now() - start,
sessionId: req.headers['mcp-session-id'] as string,
timestamp: new Date()
};
this.metrics.push(metric);
// Keep only last 1000 metrics in memory
if (this.metrics.length > 1000) {
this.metrics.shift();
}
});
next();
};
}
public getMetrics() {
return {
requests: this.metrics.length,
avgDuration: this.calculateAverage('duration'),
errorRate: this.calculateErrorRate(),
activeSessions: new Set(this.metrics.map(m => m.sessionId)).size
};
}
private calculateAverage(field: keyof RequestMetrics): number {
if (this.metrics.length === 0) return 0;
const sum = this.metrics.reduce((acc, m) => acc + (m[field] as number || 0), 0);
return sum / this.metrics.length;
}
private calculateErrorRate(): number {
if (this.metrics.length === 0) return 0;
const errors = this.metrics.filter(m => m.statusCode >= 400).length;
return errors / this.metrics.length;
}
}
```
## Security Considerations
### 1. Authentication Token Management
- Use strong, random tokens (minimum 32 characters)
- Rotate tokens regularly
- Never commit tokens to version control
- Use environment variables or secret management systems
### 2. Rate Limiting
```typescript
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});
app.use('/mcp', limiter);
```
### 3. Input Validation
- Validate JSON-RPC structure
- Limit request body size
- Sanitize any user inputs
- Use schema validation for MCP tool parameters
### 4. HTTPS/TLS
- Always use HTTPS in production
- Use strong TLS configurations
- Enable HSTS headers
- Consider certificate pinning for high-security deployments
## Performance Optimization
### 1. Database Connection Pooling
Since we're using SQLite through our adapter, consider:
- Read-only replicas for query operations
- In-memory caching for frequently accessed nodes
- Connection pooling if switching to PostgreSQL
### 2. Response Caching
```typescript
const nodeCache = new NodeCache({ stdTTL: 600 }); // 10 minute cache
// In your tool handlers
const cachedResult = nodeCache.get(cacheKey);
if (cachedResult) {
return cachedResult;
}
```
### 3. Compression
- Already implemented with compression middleware
- Consider additional optimizations for large responses
### 4. CDN Integration
- Serve static assets through CDN
- Cache API responses where appropriate
- Use geographic distribution for global access
## Testing Strategy
### 1. Unit Tests
```typescript
// src/test/http-transport.test.ts
describe('HTTPTransportServer', () => {
it('should create new session on first request', async () => {
// Test implementation
});
it('should reuse existing session', async () => {
// Test implementation
});
it('should cleanup expired sessions', async () => {
// Test implementation
});
});
```
### 2. Integration Tests
- Test full request/response cycle
- Verify authentication
- Test session persistence
- Validate error handling
### 3. Load Testing
```bash
# Using Apache Bench
ab -n 1000 -c 10 -H "Authorization: Bearer your-token" https://your-server/mcp
# Using k6
k6 run load-test.js
```
## Troubleshooting Guide
### Common Issues
1. **Connection Refused**
- Check firewall rules
- Verify nginx configuration
- Ensure Docker container is running
2. **Authentication Failures**
- Verify token format (Bearer prefix)
- Check environment variables
- Ensure token matches server configuration
3. **Session Timeout**
- Adjust MCP_SESSION_TIMEOUT
- Check client keep-alive settings
- Monitor server resources
4. **Performance Issues**
- Enable monitoring
- Check database query performance
- Review nginx access logs
- Monitor Docker container resources
## Future Enhancements
1. **WebSocket Support**
- Implement full duplex communication
- Reduce latency for real-time updates
- Better support for server-initiated messages
2. **OAuth2 Integration**
- Support for third-party authentication
- User-specific access controls
- Integration with enterprise SSO
3. **Multi-tenancy**
- Separate databases per organization
- Role-based access control
- Usage tracking and quotas
4. **Horizontal Scaling**
- Redis for session storage
- Load balancer configuration
- Distributed caching
## Conclusion
This implementation provides a robust foundation for running n8n-MCP as a remote HTTP service. The dual-mode support ensures backward compatibility while enabling new deployment scenarios. With proper security measures and monitoring in place, this solution can scale from single-user deployments to enterprise-wide installations.

View File

@@ -1,371 +0,0 @@
# HTTP Implementation Roadmap
## Quick Reference Architecture
```
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Claude Desktop │ stdio │ mcp-remote │ HTTP │ n8n-MCP HTTP │
│ ├────────>│ adapter ├────────>│ Server │
└─────────────────┘ └──────────────┘ └─────────────────┘
│ │
│ Auth Token │
└──────────────────────────┘
```
## Implementation Checklist
### Prerequisites
- [ ] Understand StreamableHTTPServerTransport API
- [ ] Review mcp-remote documentation
- [ ] Set up test environment with Express.js
- [ ] Plan session management strategy
### Phase 1: Core HTTP Server (Days 1-3)
#### Day 1: Basic HTTP Server
- [ ] Install dependencies: `express`, `cors`, `helmet`, `compression`
- [ ] Create `src/mcp/transports/http-transport.ts`
- [ ] Implement basic Express server structure
- [ ] Add health check endpoint `/health`
- [ ] Add MCP endpoint `/mcp` (placeholder)
#### Day 2: MCP Integration
- [ ] Import StreamableHTTPServerTransport
- [ ] Implement session management (in-memory)
- [ ] Connect transport to MCP server
- [ ] Handle JSON-RPC requests
- [ ] Test with simple curl commands
#### Day 3: Authentication & Security
- [ ] Implement Bearer token authentication
- [ ] Add rate limiting
- [ ] Configure CORS properly
- [ ] Add request logging
- [ ] Basic error handling
### Phase 2: Server Modifications (Days 4-6)
#### Day 4: Refactor Server Class
- [ ] Modify `N8NDocumentationMCPServer` to accept any transport
- [ ] Add `connect(transport)` method
- [ ] Update `run()` method for backward compatibility
- [ ] Test stdio mode still works
#### Day 5: Configuration System
- [ ] Create configuration interface
- [ ] Add environment variable support
- [ ] Implement CLI argument parsing
- [ ] Create `.env.example` file
- [ ] Document all configuration options
#### Day 6: Unified Entry Point
- [ ] Create `index-universal.ts`
- [ ] Implement mode detection (stdio vs http)
- [ ] Handle graceful shutdown
- [ ] Test both modes work correctly
### Phase 3: Production Readiness (Days 7-9)
#### Day 7: Docker & Deployment
- [ ] Create `Dockerfile.http`
- [ ] Add health checks to Docker
- [ ] Create `docker-compose.yml`
- [ ] Write deployment script
- [ ] Test container locally
#### Day 8: Monitoring & Logging
- [ ] Enhance logging with correlation IDs
- [ ] Add metrics collection
- [ ] Implement `/metrics` endpoint
- [ ] Add session analytics
- [ ] Create monitoring dashboard
#### Day 9: Documentation
- [ ] Write user setup guide
- [ ] Create troubleshooting guide
- [ ] Document API endpoints
- [ ] Add architecture diagrams
- [ ] Create video tutorial
### Phase 4: Testing & Launch (Days 10-14)
#### Day 10: Testing Suite
- [ ] Unit tests for HTTP transport
- [ ] Integration tests for full flow
- [ ] Load testing with Apache Bench
- [ ] Security testing (auth, injection)
- [ ] Cross-platform client testing
#### Day 11: Beta Deployment
- [ ] Deploy to test server
- [ ] Configure nginx + SSL
- [ ] Test with mcp-remote
- [ ] Monitor performance
- [ ] Gather initial feedback
#### Day 12: Performance Optimization
- [ ] Implement response caching
- [ ] Optimize database queries
- [ ] Add connection pooling
- [ ] Profile memory usage
- [ ] Fine-tune nginx config
#### Day 13: Security Hardening
- [ ] Security audit
- [ ] Implement CSP headers
- [ ] Add request validation
- [ ] Set up fail2ban
- [ ] Configure firewall rules
#### Day 14: Production Launch
- [ ] Final deployment
- [ ] Update documentation
- [ ] Announce to community
- [ ] Monitor closely
- [ ] Respond to feedback
## Code Templates
### 1. Minimal Express Server Test
```typescript
// test-server.ts - Quick test to verify concept
import express from 'express';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
const app = express();
app.use(express.json());
const transport = new StreamableHTTPServerTransport();
app.post('/mcp', async (req, res) => {
await transport.handleRequest(req, res);
});
app.listen(3000, () => {
console.log('Test server running on http://localhost:3000');
});
```
### 2. Environment Variables
```bash
# .env
MCP_MODE=http
MCP_PORT=3000
MCP_HOST=0.0.0.0
MCP_AUTH_TOKEN=development-token-change-in-production
MCP_SESSION_TIMEOUT=1800000
MCP_MAX_SESSIONS=50
MCP_CORS_ORIGINS=http://localhost:3000,https://claude.ai
NODE_ENV=development
LOG_LEVEL=debug
```
### 3. Test Script
```bash
#!/bin/bash
# test-http.sh - Test HTTP endpoint
TOKEN="development-token-change-in-production"
URL="http://localhost:3000/mcp"
# Test health check
curl -s http://localhost:3000/health | jq .
# Test MCP endpoint
curl -s -X POST $URL \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}' | jq .
```
### 4. nginx Configuration
```nginx
# /etc/nginx/sites-available/n8n-mcp
server {
listen 80;
server_name mcp.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name mcp.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/mcp.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mcp.yourdomain.com/privkey.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
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;
}
}
```
### 5. Claude Desktop Config
```json
{
"mcpServers": {
"n8n-docs-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"connect",
"https://mcp.yourdomain.com/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-secure-token"
}
}
}
}
```
## Testing Scenarios
### Scenario 1: Basic Connectivity
1. Start HTTP server locally
2. Use curl to test endpoints
3. Verify authentication works
4. Check session creation
### Scenario 2: mcp-remote Integration
1. Install mcp-remote globally
2. Configure with local server
3. Test all MCP tools work
4. Verify session persistence
### Scenario 3: Load Testing
```bash
# Test 100 concurrent users
ab -n 1000 -c 100 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-p request.json \
http://localhost:3000/mcp
```
### Scenario 4: Security Testing
1. Test without auth token (should fail)
2. Test with invalid token (should fail)
3. Test SQL injection attempts
4. Test large payload handling
5. Test rate limiting
## Deployment Commands
### Local Development
```bash
# Start in development mode
npm run dev:http
# Watch logs
tail -f logs/mcp-http.log
```
### Production Deployment
```bash
# Build and deploy
npm run build
docker build -f Dockerfile.http -t n8n-mcp-http .
docker run -d --name n8n-mcp-http \
-p 3000:3000 \
--env-file .env.production \
--restart unless-stopped \
n8n-mcp-http
# Check status
docker logs n8n-mcp-http
curl https://mcp.yourdomain.com/health
```
## Monitoring Checklist
### Application Metrics
- [ ] Request rate
- [ ] Response times
- [ ] Error rates
- [ ] Active sessions
- [ ] Memory usage
- [ ] CPU usage
### Business Metrics
- [ ] Unique users
- [ ] Most used tools
- [ ] Peak usage times
- [ ] Geographic distribution
### Alerts to Configure
- [ ] Server down
- [ ] High error rate (> 5%)
- [ ] Slow response times (> 1s)
- [ ] Memory usage > 80%
- [ ] Disk space < 20%
- [ ] SSL certificate expiring
## Rollback Plan
If issues arise:
1. **Immediate**: Switch DNS back to maintenance page
2. **Quick Fix**: Rollback Docker container to previous version
3. **Investigate**: Check logs and metrics
4. **Fix Forward**: Deploy hotfix if simple
5. **Full Rollback**: Restore previous version if complex
## Success Criteria
### Week 1
- [ ] HTTP server running locally
- [ ] All MCP tools working via HTTP
- [ ] Basic authentication working
- [ ] Session management functional
### Week 2
- [ ] Deployed to test environment
- [ ] SSL/HTTPS working
- [ ] mcp-remote integration tested
- [ ] Documentation complete
### Week 3
- [ ] Beta users testing
- [ ] Performance acceptable
- [ ] No security issues found
- [ ] Monitoring in place
### Week 4
- [ ] Production deployment
- [ ] Public announcement
- [ ] User adoption beginning
- [ ] Positive feedback
## Future Enhancements
After successful launch, consider:
1. **WebSocket Support** - Real-time bidirectional communication
2. **OAuth2/SSO** - Enterprise authentication
3. **Multi-tenancy** - Separate instances per organization
4. **Usage Analytics** - Detailed usage tracking
5. **API Keys** - Per-user authentication
6. **Webhooks** - Event notifications
7. **Clustering** - Horizontal scaling
8. **GraphQL API** - Alternative query interface
This roadmap provides a clear, actionable path to implementing HTTP support in n8n-MCP. Each phase builds on the previous one, ensuring a stable and well-tested deployment.

View File

@@ -1,286 +0,0 @@
# HTTP Remote Deployment Plan for n8n-MCP
## Executive Summary
This document outlines the comprehensive plan to transform the n8n-MCP server from a local stdio-based implementation to a remote HTTP-accessible service that can be deployed on the internet and accessed by Claude Desktop users from anywhere.
## Current State Analysis
### Current Architecture
- **Transport**: StdioServerTransport (requires local execution)
- **Communication**: stdin/stdout between Claude Desktop and the MCP server
- **Deployment**: Must run on the same machine as Claude Desktop
- **Authentication**: None (implicit trust from local execution)
- **State Management**: Single instance per process
### Limitations
1. Users must install and maintain the server locally
2. No centralized updates or management
3. Limited to single-user scenarios
4. Requires Node.js and dependencies on client machine
## Target Architecture
### Goals
1. Deploy n8n-MCP server on remote infrastructure (VPS, cloud, etc.)
2. Enable multiple Claude Desktop users to connect to a single server instance
3. Maintain security through authentication and encryption
4. Support both local (stdio) and remote (HTTP) modes for flexibility
### Technical Requirements
#### 1. HTTP Transport Implementation
- Use `StreamableHTTPServerTransport` from `@modelcontextprotocol/sdk`
- Implement session management for stateful connections
- Support JSON-RPC 2.0 protocol over HTTP
- Handle both request/response and server-sent events
#### 2. Authentication & Security
- Implement Bearer token authentication
- Use HTTPS/TLS for all communications
- Consider OAuth2 for advanced scenarios
- Rate limiting and DDoS protection
#### 3. Infrastructure Requirements
- HTTP server (Express.js recommended)
- SSL certificates (Let's Encrypt)
- Reverse proxy (nginx/Caddy)
- Process manager (PM2)
- Domain name for stable endpoint
## Implementation Plan
### Phase 1: Core HTTP Server Implementation
#### 1.1 Create HTTP Server Module
```typescript
// src/mcp/http-server.ts
import express from 'express';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { N8NDocumentationMCPServer } from './server-update';
interface Session {
id: string;
transport: StreamableHTTPServerTransport;
server: N8NDocumentationMCPServer;
lastActivity: Date;
}
```
#### 1.2 Session Management
- Implement session creation and cleanup
- Handle concurrent sessions
- Add session timeout (e.g., 30 minutes)
- Store session state in memory (consider Redis for production)
#### 1.3 Authentication Middleware
```typescript
const authenticateToken = (req: Request, res: Response, next: NextFunction) => {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token || token !== process.env.AUTH_TOKEN) {
return res.sendStatus(401);
}
next();
};
```
### Phase 2: Dual-Mode Support
#### 2.1 Configuration System
```typescript
interface ServerConfig {
mode: 'stdio' | 'http';
http?: {
port: number;
host: string;
authToken: string;
ssl?: {
cert: string;
key: string;
};
};
}
```
#### 2.2 Entry Point Refactoring
- Create unified entry point that can start either stdio or HTTP server
- Use environment variables or CLI arguments for mode selection
- Maintain backward compatibility with existing stdio mode
### Phase 3: Client Adapter Implementation
#### 3.1 mcp-remote Integration
Since Claude Desktop doesn't natively support HTTP transport yet, we need to:
1. Document how to use `mcp-remote` adapter
2. Create wrapper scripts for easy setup
3. Provide configuration examples
#### 3.2 Claude Desktop Configuration
```json
{
"mcpServers": {
"n8n-documentation-remote": {
"command": "npx",
"args": [
"mcp-remote",
"https://your-server.com/mcp",
"--auth-token", "your-auth-token"
]
}
}
}
```
### Phase 4: Deployment Infrastructure
#### 4.1 Docker Container
```dockerfile
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci --only=production
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start:http"]
```
#### 4.2 Nginx Configuration
```nginx
server {
listen 443 ssl http2;
server_name mcp.your-domain.com;
ssl_certificate /etc/letsencrypt/live/mcp.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mcp.your-domain.com/privkey.pem;
location /mcp {
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_cache_bypass $http_upgrade;
}
}
```
#### 4.3 PM2 Configuration
```json
{
"apps": [{
"name": "n8n-mcp-server",
"script": "./dist/mcp/http-server.js",
"env": {
"NODE_ENV": "production",
"PORT": 3000,
"AUTH_TOKEN": "your-secure-token"
}
}]
}
```
## Technical Challenges & Solutions
### 1. State Management
**Challenge**: MCP servers can be stateful, but HTTP is stateless by nature.
**Solution**: Implement session management with unique session IDs in headers.
### 2. Authentication with mcp-remote
**Challenge**: mcp-remote needs to pass authentication to the remote server.
**Solution**: Use environment variables or command-line arguments for auth tokens.
### 3. Database Access
**Challenge**: Multiple concurrent sessions accessing SQLite database.
**Solution**: Our database adapter already handles this; sql.js runs in-memory with persistence.
### 4. Performance & Scaling
**Challenge**: Single server instance handling multiple clients.
**Solution**:
- Implement connection pooling
- Add caching layer for frequently accessed data
- Consider horizontal scaling with load balancer
### 5. Security
**Challenge**: Exposing MCP server to the internet.
**Solution**:
- Mandatory HTTPS
- Strong authentication tokens
- Rate limiting
- Input validation
- Regular security audits
## Implementation Timeline
### Week 1: Core HTTP Server
- [ ] Implement basic HTTP server with Express
- [ ] Integrate StreamableHTTPServerTransport
- [ ] Add session management
- [ ] Implement authentication
### Week 2: Dual-Mode Support
- [ ] Refactor entry points
- [ ] Add configuration system
- [ ] Test both stdio and HTTP modes
- [ ] Update documentation
### Week 3: Client Integration
- [ ] Test with mcp-remote adapter
- [ ] Create setup scripts
- [ ] Document Claude Desktop configuration
- [ ] Create troubleshooting guide
### Week 4: Deployment
- [ ] Create Docker container
- [ ] Set up test deployment
- [ ] Configure nginx/SSL
- [ ] Performance testing
- [ ] Security hardening
## Alternative Approaches
### 1. Cloudflare Workers
- **Pros**: Global edge deployment, built-in DDoS protection
- **Cons**: Limited execution time, stateless by design
### 2. AWS Lambda
- **Pros**: Serverless, auto-scaling
- **Cons**: Cold starts, complex state management
### 3. Dedicated WebSocket Server
- **Pros**: Real-time bidirectional communication
- **Cons**: More complex implementation, not standard MCP transport
## Success Metrics
1. **Functionality**: All MCP tools work identically in remote mode
2. **Performance**: Response time < 200ms for most operations
3. **Reliability**: 99.9% uptime
4. **Security**: No unauthorized access incidents
5. **Usability**: Clear documentation and easy setup
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|---------|------------|
| Claude Desktop HTTP support delayed | High | Use mcp-remote adapter as bridge |
| Security breach | High | Regular audits, penetration testing |
| Performance degradation | Medium | Caching, CDN, horizontal scaling |
| Database corruption | Medium | Regular backups, read replicas |
| Cost overruns | Low | Start with single VPS, scale as needed |
## Next Steps
1. **Validate Approach**: Test StreamableHTTPServerTransport with simple example
2. **Prototype**: Build minimal HTTP server with single tool
3. **Security Review**: Have security expert review authentication approach
4. **Community Feedback**: Share plan with MCP community for input
5. **Begin Implementation**: Start with Phase 1 core server
## Conclusion
Transitioning n8n-MCP to support remote HTTP deployment will significantly expand its usability and reach. While Claude Desktop doesn't yet natively support HTTP transport, the mcp-remote adapter provides a viable bridge solution. The implementation plan balances immediate functionality with future-proofing for when native HTTP support arrives.
The key to success will be maintaining compatibility with existing stdio users while providing a seamless experience for remote users. With proper security measures and careful implementation, n8n-MCP can become a centrally-hosted service that benefits the entire Claude Desktop community.

View File

@@ -1,251 +0,0 @@
# HTTP Remote Deployment - Executive Summary
## Current Situation
The n8n-MCP server currently only works locally on the same machine as Claude Desktop. This limits its usefulness and prevents centralized deployment, updates, and management.
## Key Finding: Claude Desktop Limitation
**Critical Discovery**: Claude Desktop does NOT currently support remote MCP servers natively. It only supports the stdio (standard input/output) transport protocol, which requires local execution.
## The Solution: mcp-remote Bridge
The MCP community has developed `mcp-remote`, an adapter that bridges the gap:
- Acts as a local stdio server that Claude Desktop can communicate with
- Forwards requests to remote HTTP MCP servers
- Handles authentication and session management
- Provides transparent proxy functionality
## Implementation Overview
### 1. Server-Side Changes
We need to add HTTP transport support to n8n-MCP:
```typescript
// New capabilities to add:
- HTTP endpoint (/mcp) that accepts JSON-RPC requests
- Session management for stateful connections
- Bearer token authentication
- HTTPS/TLS encryption
- Health check endpoints
```
### 2. Dual-Mode Operation
The server will support both modes:
- **stdio mode**: Current local operation (no changes for existing users)
- **http mode**: New remote operation for internet deployment
### 3. Client Configuration
Users will configure Claude Desktop like this:
```json
{
"mcpServers": {
"n8n-remote": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"connect",
"https://your-mcp-server.com/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-secure-token"
}
}
}
}
```
## Technical Architecture
### Components
1. **Express.js HTTP Server**
- Handles incoming HTTP requests
- Manages authentication
- Provides CORS support
2. **StreamableHTTPServerTransport**
- MCP SDK's HTTP transport implementation
- Handles JSON-RPC protocol
- Supports Server-Sent Events for bidirectional communication
3. **Session Manager**
- Creates unique sessions per client
- Maintains state between requests
- Handles cleanup of inactive sessions
4. **Database Adapter**
- Our existing adapter works perfectly
- Handles concurrent access
- No changes needed
## Security Model
1. **Authentication**: Bearer token in Authorization header
2. **Encryption**: HTTPS/TLS required for production
3. **Rate Limiting**: Prevent abuse and DDoS
4. **Input Validation**: Sanitize all inputs
5. **CORS**: Restrict allowed origins
## Deployment Options
### Option 1: VPS/Cloud VM
- Full control over environment
- Can handle many concurrent users
- Requires server management
### Option 2: Docker Container
- Easy deployment and updates
- Consistent environment
- Good for scaling
### Option 3: Managed Platforms
- Cloudflare Workers (with limitations)
- AWS Lambda (stateless challenges)
- Heroku/Railway (simple deployment)
## Implementation Phases
### Phase 1: Core HTTP Server (Week 1)
- Implement Express server with MCP endpoint
- Add StreamableHTTPServerTransport
- Basic authentication
- Session management
### Phase 2: Integration (Week 2)
- Modify existing server for dual-mode
- Add configuration system
- Update entry points
- Maintain backward compatibility
### Phase 3: Deployment (Week 3)
- Create Docker container
- Write deployment scripts
- Set up nginx/SSL
- Document setup process
### Phase 4: Testing & Launch (Week 4)
- Security testing
- Performance testing
- Documentation
- Community release
## Benefits
1. **Centralized Management**
- Single server for multiple users
- Easy updates and maintenance
- Consistent experience
2. **No Local Installation**
- Users don't need Node.js
- No dependency management
- Works on any OS
3. **Enterprise Ready**
- Authentication and access control
- Monitoring and logging
- Scalable architecture
4. **Cost Effective**
- One server serves many users
- Efficient resource usage
- Pay for what you use
## Challenges & Solutions
| Challenge | Solution |
|-----------|----------|
| Claude Desktop doesn't support HTTP | Use mcp-remote adapter |
| Session state management | Implement session manager with timeout |
| Security concerns | Strong auth, HTTPS, rate limiting |
| Database concurrency | Our adapter already handles this |
| Performance at scale | Caching, CDN, horizontal scaling |
## Cost Estimate
### Small Deployment (< 50 users)
- VPS: $10-20/month
- Domain: $10/year
- SSL: Free (Let's Encrypt)
- Total: ~$15/month
### Medium Deployment (50-500 users)
- Better VPS: $40-80/month
- CDN: $20/month
- Monitoring: $10/month
- Total: ~$70/month
### Large Deployment (500+ users)
- Load balanced setup: $200+/month
- Redis for sessions: $30/month
- Advanced monitoring: $50/month
- Total: ~$280/month
## Success Metrics
1. **Technical Success**
- All MCP tools work remotely
- Response time < 200ms
- 99.9% uptime
2. **User Success**
- Easy setup (< 5 minutes)
- Clear documentation
- Positive feedback
3. **Operational Success**
- Low maintenance overhead
- Automated monitoring
- Smooth updates
## Recommended Next Steps
1. **Immediate Actions**
- Review and approve the implementation plan
- Set up development environment
- Begin Phase 1 implementation
2. **Short Term (1-2 weeks)**
- Complete HTTP server implementation
- Test with mcp-remote
- Deploy beta version
3. **Medium Term (3-4 weeks)**
- Production deployment
- Documentation and guides
- Community announcement
4. **Long Term (2-3 months)**
- Gather feedback
- Implement enhancements
- Consider enterprise features
## Conclusion
Adding HTTP remote deployment to n8n-MCP is technically feasible and highly beneficial. While Claude Desktop's current limitations require using the mcp-remote adapter, this is a proven solution already in use by other MCP servers.
The implementation is straightforward, building on our existing robust architecture. The database adapter system we recently implemented will work perfectly in a multi-user environment.
This enhancement will transform n8n-MCP from a local tool to a cloud-ready service, greatly expanding its reach and usefulness to the Claude Desktop community.
## Key Decision Points
1. **Should we proceed with HTTP implementation?**
- Recommendation: Yes, the benefits far outweigh the complexity
2. **Which deployment option should we prioritize?**
- Recommendation: Start with VPS + Docker for flexibility
3. **How should we handle authentication?**
- Recommendation: Start with Bearer tokens, consider OAuth2 later
4. **When should we launch?**
- Recommendation: Beta in 2 weeks, production in 4 weeks
The path forward is clear, and the technical approach is sound. With careful implementation and testing, n8n-MCP can become a premier remote MCP service for the Claude Desktop ecosystem.

View File

@@ -1,650 +0,0 @@
# n8n-MCP Enhancement Implementation Plan v2.1 Final
## Executive Summary
This ultra-focused MVP implementation plan delivers accurate n8n node documentation in 2 weeks by working directly with n8n's architecture. We prioritize simplicity and accuracy over complex features.
## Core MVP Principles
1. **Start with the simplest thing that works**
2. **Test with real nodes early and often**
3. **Don't try to be too clever** - n8n's structure is fine
4. **Focus on accuracy over completeness**
5. **Work WITH n8n's architecture, not against it**
## Key Insight
**We're not trying to understand n8n's nodes, we're just accurately cataloging them.**
## Simplified Architecture
```
n8n-mcp/
├── src/
│ ├── loaders/
│ │ └── node-loader.ts # Simple npm package loader
│ ├── parsers/
│ │ └── simple-parser.ts # Single parser for all nodes
│ ├── mappers/
│ │ └── docs-mapper.ts # Deterministic documentation mapping
│ ├── scripts/
│ │ ├── rebuild.ts # One-command rebuild
│ │ └── validate.ts # Validation script
│ └── mcp/
│ └── server.ts # Enhanced MCP server
└── data/
└── nodes.db # Minimal SQLite database
```
## Implementation Strategy
### Quick Win Approach
Get *something* working end-to-end on Day 1, even if it only loads 5 nodes. This proves the architecture and builds momentum.
### Documentation Strategy
Clone the n8n-docs repo locally for simpler file-based access:
```bash
git clone https://github.com/n8n-io/n8n-docs.git ../n8n-docs
```
### Test-First Development
Build the rebuild script first as a test harness:
```bash
npm run rebuild && sqlite3 data/nodes.db "SELECT node_type, display_name FROM nodes LIMIT 10"
```
## Week 1: Core Implementation
### Day 1-2: Simple Node Loader + Initial Rebuild Script
**Start with the rebuild script to enable quick iteration!**
**File**: `src/scripts/rebuild.ts` (Build this first!)
```typescript
#!/usr/bin/env node
import Database from 'better-sqlite3';
import { N8nNodeLoader } from '../loaders/node-loader';
import { SimpleParser } from '../parsers/simple-parser';
import { DocsMapper } from '../mappers/docs-mapper';
async function rebuild() {
console.log('🔄 Rebuilding n8n node database...\n');
const db = new Database('./data/nodes.db');
const loader = new N8nNodeLoader();
const parser = new SimpleParser();
const mapper = new DocsMapper();
// Initialize database
const schema = require('fs').readFileSync('./src/database/schema.sql', 'utf8');
db.exec(schema);
// Clear existing data
db.exec('DELETE FROM nodes');
console.log('🗑️ Cleared existing data\n');
// Load all nodes
const nodes = await loader.loadAllNodes();
console.log(`📦 Loaded ${nodes.length} nodes from packages\n`);
// Statistics
let successful = 0;
let failed = 0;
let aiTools = 0;
// Process each node
for (const { packageName, nodeName, NodeClass } of nodes) {
try {
// Parse node
const parsed = parser.parse(NodeClass);
// Get documentation
const docs = await mapper.fetchDocumentation(parsed.nodeType);
// Insert into database
db.prepare(`
INSERT INTO nodes (
node_type, package_name, display_name, description,
category, development_style, is_ai_tool, is_trigger,
is_webhook, is_versioned, version, documentation,
properties_schema, operations, credentials_required
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
parsed.nodeType,
packageName,
parsed.displayName,
parsed.description,
parsed.category,
parsed.style,
parsed.isAITool ? 1 : 0,
parsed.isTrigger ? 1 : 0,
parsed.isWebhook ? 1 : 0,
parsed.isVersioned ? 1 : 0,
parsed.version,
docs,
JSON.stringify(parsed.properties),
JSON.stringify(parsed.operations),
JSON.stringify(parsed.credentials)
);
successful++;
if (parsed.isAITool) aiTools++;
console.log(`✅ ${parsed.nodeType}`);
} catch (error) {
failed++;
console.error(`❌ Failed to process ${nodeName}: ${error.message}`);
}
}
// Summary
console.log('\n📊 Summary:');
console.log(` Total nodes: ${nodes.length}`);
console.log(` Successful: ${successful}`);
console.log(` Failed: ${failed}`);
console.log(` AI Tools: ${aiTools}`);
console.log('\n✨ Rebuild complete!');
db.close();
}
// Run if called directly
if (require.main === module) {
rebuild().catch(console.error);
}
```
**File**: `src/loaders/node-loader.ts`
```typescript
export class N8nNodeLoader {
private readonly CORE_PACKAGES = [
'n8n-nodes-base',
'@n8n/n8n-nodes-langchain'
];
async loadAllNodes() {
const results = [];
for (const pkg of this.CORE_PACKAGES) {
try {
// Direct require - no complex path resolution
const packageJson = require(`${pkg}/package.json`);
const nodes = await this.loadPackageNodes(pkg, packageJson);
results.push(...nodes);
} catch (error) {
console.error(`Failed to load ${pkg}:`, error);
}
}
return results;
}
private async loadPackageNodes(packageName: string, packageJson: any) {
const n8nConfig = packageJson.n8n || {};
const nodes = [];
// Load from n8n.nodes configuration
for (const [nodeName, nodePath] of Object.entries(n8nConfig.nodes || {})) {
const fullPath = require.resolve(`${packageName}/${nodePath}`);
const nodeModule = require(fullPath);
// Handle default export
const NodeClass = nodeModule.default || nodeModule[nodeName];
nodes.push({ packageName, nodeName, NodeClass });
}
return nodes;
}
}
```
### Day 3: Simple Parser
**File**: `src/parsers/simple-parser.ts`
```typescript
export interface ParsedNode {
style: 'declarative' | 'programmatic';
nodeType: string;
displayName: string;
description?: string;
category?: string;
properties: any[];
credentials: string[];
isAITool: boolean;
isTrigger: boolean;
isWebhook: boolean;
operations: any[];
version?: string;
isVersioned: boolean;
}
export class SimpleParser {
parse(nodeClass: any): ParsedNode {
const description = nodeClass.description || {};
const isDeclarative = !!description.routing;
return {
style: isDeclarative ? 'declarative' : 'programmatic',
nodeType: description.name,
displayName: description.displayName,
description: description.description,
category: description.group?.[0] || description.categories?.[0],
properties: description.properties || [],
credentials: description.credentials || [],
isAITool: description.usableAsTool === true,
isTrigger: description.polling === true || description.trigger === true,
isWebhook: description.webhooks?.length > 0,
operations: isDeclarative ? this.extractOperations(description.routing) : [],
version: this.extractVersion(nodeClass),
isVersioned: this.isVersionedNode(nodeClass)
};
}
private extractOperations(routing: any): any[] {
// Simple extraction without complex logic
const operations = [];
const resources = routing?.request?.resource?.options || [];
resources.forEach(resource => {
operations.push({
resource: resource.value,
name: resource.name
});
});
return operations;
}
private extractVersion(nodeClass: any): string {
if (nodeClass.baseDescription?.defaultVersion) {
return nodeClass.baseDescription.defaultVersion.toString();
}
return nodeClass.description?.version || '1';
}
private isVersionedNode(nodeClass: any): boolean {
return !!(nodeClass.baseDescription && nodeClass.nodeVersions);
}
}
```
### Day 4: Documentation Mapper
**File**: `src/mappers/docs-mapper.ts`
```typescript
import { promises as fs } from 'fs';
import path from 'path';
export class DocsMapper {
private docsPath = path.join(__dirname, '../../../n8n-docs');
// Known documentation mapping fixes
private readonly KNOWN_FIXES = {
'n8n-nodes-base.httpRequest': 'httprequest',
'n8n-nodes-base.code': 'code',
'n8n-nodes-base.webhook': 'webhook',
'n8n-nodes-base.respondToWebhook': 'respondtowebhook'
};
async fetchDocumentation(nodeType: string): Promise<string | null> {
// Apply known fixes first
const fixedType = this.KNOWN_FIXES[nodeType] || nodeType;
// Extract node name
const nodeName = fixedType.split('.').pop()?.toLowerCase();
if (!nodeName) return null;
// Try different documentation paths
const possiblePaths = [
`docs/integrations/builtin/core-nodes/n8n-nodes-base.${nodeName}.md`,
`docs/integrations/builtin/app-nodes/n8n-nodes-base.${nodeName}.md`,
`docs/integrations/builtin/trigger-nodes/n8n-nodes-base.${nodeName}.md`,
`docs/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.${nodeName}.md`
];
// Try each path
for (const relativePath of possiblePaths) {
try {
const fullPath = path.join(this.docsPath, relativePath);
const content = await fs.readFile(fullPath, 'utf-8');
return content;
} catch (error) {
// File doesn't exist, try next
continue;
}
}
return null;
}
}
```
### Day 5: Database Setup
**File**: `src/database/schema.sql`
```sql
-- Ultra-simple schema for MVP
CREATE TABLE IF NOT EXISTS nodes (
node_type TEXT PRIMARY KEY,
package_name TEXT NOT NULL,
display_name TEXT NOT NULL,
description TEXT,
category TEXT,
development_style TEXT CHECK(development_style IN ('declarative', 'programmatic')),
is_ai_tool INTEGER DEFAULT 0,
is_trigger INTEGER DEFAULT 0,
is_webhook INTEGER DEFAULT 0,
is_versioned INTEGER DEFAULT 0,
version TEXT,
documentation TEXT,
properties_schema TEXT,
operations TEXT,
credentials_required TEXT,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Minimal indexes for performance
CREATE INDEX IF NOT EXISTS idx_package ON nodes(package_name);
CREATE INDEX IF NOT EXISTS idx_ai_tool ON nodes(is_ai_tool);
CREATE INDEX IF NOT EXISTS idx_category ON nodes(category);
```
## Week 2: Integration and Testing
### Day 6-7: Test Priority Nodes
Focus on these nodes first (they cover most edge cases):
1. **HTTP Request** - Known documentation mismatch
2. **Slack** - Complex declarative node
3. **Code** - Versioned node with documentation issues
4. **AI Agent** - LangChain node with AI tool flag
### Day 8-9: MCP Server Updates
**File**: `src/mcp/tools-update.ts`
```typescript
// Simplified get_node_info tool
async function getNodeInfo(nodeType: string) {
const node = db.prepare(`
SELECT * FROM nodes WHERE node_type = ?
`).get(nodeType);
if (!node) {
throw new Error(`Node ${nodeType} not found`);
}
return {
nodeType: node.node_type,
displayName: node.display_name,
description: node.description,
category: node.category,
developmentStyle: node.development_style,
isAITool: !!node.is_ai_tool,
isTrigger: !!node.is_trigger,
isWebhook: !!node.is_webhook,
version: node.version,
properties: JSON.parse(node.properties_schema),
operations: JSON.parse(node.operations || '[]'),
credentials: JSON.parse(node.credentials_required),
documentation: node.documentation
};
}
// New tool: list_ai_tools
{
name: 'list_ai_tools',
description: 'List all nodes that can be used as AI Agent tools',
inputSchema: {
type: 'object',
properties: {}
}
}
async function listAITools() {
const tools = db.prepare(`
SELECT node_type, display_name, description, package_name
FROM nodes
WHERE is_ai_tool = 1
ORDER BY display_name
`).all();
return {
tools,
totalCount: tools.length,
requirements: {
environmentVariable: 'N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true',
nodeProperty: 'usableAsTool: true'
}
};
}
```
### Day 10: Validation Script
**File**: `src/scripts/validate.ts`
```typescript
#!/usr/bin/env node
import Database from 'better-sqlite3';
async function validate() {
const db = new Database('./data/nodes.db');
console.log('🔍 Validating critical nodes...\n');
const criticalChecks = [
{
type: 'n8n-nodes-base.httpRequest',
checks: {
hasDocumentation: true,
documentationContains: 'httprequest',
style: 'programmatic'
}
},
{
type: 'n8n-nodes-base.code',
checks: {
hasDocumentation: true,
documentationContains: 'code',
isVersioned: true
}
},
{
type: 'n8n-nodes-base.slack',
checks: {
hasOperations: true,
style: 'declarative'
}
},
{
type: '@n8n/n8n-nodes-langchain.agent',
checks: {
isAITool: true,
packageName: '@n8n/n8n-nodes-langchain'
}
}
];
let passed = 0;
let failed = 0;
for (const check of criticalChecks) {
const node = db.prepare('SELECT * FROM nodes WHERE node_type = ?').get(check.type);
if (!node) {
console.log(`❌ ${check.type}: NOT FOUND`);
failed++;
continue;
}
let nodeOk = true;
const issues = [];
// Run checks
if (check.checks.hasDocumentation && !node.documentation) {
nodeOk = false;
issues.push('missing documentation');
}
if (check.checks.documentationContains &&
!node.documentation?.includes(check.checks.documentationContains)) {
nodeOk = false;
issues.push(`documentation doesn't contain "${check.checks.documentationContains}"`);
}
if (check.checks.style && node.development_style !== check.checks.style) {
nodeOk = false;
issues.push(`wrong style: ${node.development_style}`);
}
if (check.checks.hasOperations) {
const operations = JSON.parse(node.operations || '[]');
if (!operations.length) {
nodeOk = false;
issues.push('no operations found');
}
}
if (check.checks.isAITool && !node.is_ai_tool) {
nodeOk = false;
issues.push('not marked as AI tool');
}
if (check.checks.isVersioned && !node.is_versioned) {
nodeOk = false;
issues.push('not marked as versioned');
}
if (nodeOk) {
console.log(`✅ ${check.type}`);
passed++;
} else {
console.log(`❌ ${check.type}: ${issues.join(', ')}`);
failed++;
}
}
console.log(`\n📊 Results: ${passed} passed, ${failed} failed`);
// Additional statistics
const stats = db.prepare(`
SELECT
COUNT(*) as total,
SUM(is_ai_tool) as ai_tools,
SUM(is_trigger) as triggers,
SUM(is_versioned) as versioned,
COUNT(DISTINCT package_name) as packages
FROM nodes
`).get();
console.log('\n📈 Database Statistics:');
console.log(` Total nodes: ${stats.total}`);
console.log(` AI tools: ${stats.ai_tools}`);
console.log(` Triggers: ${stats.triggers}`);
console.log(` Versioned: ${stats.versioned}`);
console.log(` Packages: ${stats.packages}`);
db.close();
process.exit(failed > 0 ? 1 : 0);
}
if (require.main === module) {
validate().catch(console.error);
}
```
## MVP Deliverables Checklist
### Week 1 ✅
- [ ] Clone n8n-docs repository locally
- [ ] Build rebuild script first (test harness)
- [ ] Basic node loader for n8n-nodes-base and langchain packages
- [ ] Simple parser (no complex analysis)
- [ ] Documentation fetcher with file-based access
- [ ] SQLite database setup with minimal schema
- [ ] Get 5 nodes working end-to-end on Day 1
### Week 2 ✅
- [ ] Test priority nodes (HTTP Request, Slack, Code, AI Agent)
- [ ] Fix all documentation mapping issues
- [ ] Update MCP tools for simplified schema
- [ ] Add AI tools listing functionality
- [ ] Create validation script
- [ ] Document usage instructions
- [ ] Run full validation suite
## What We're Deferring Post-MVP
1. **Version history tracking** - Just current version
2. **Source code extraction** - Not needed for documentation
3. **Complex property type analysis** - Keep n8n's structure as-is
4. **Custom node directory support** - Focus on npm packages only
5. **Performance optimizations** - SQLite is fast enough
6. **Real-time monitoring** - Static documentation only
7. **Web UI** - CLI tools only
8. **Multi-tenant support** - Single instance
9. **Advanced search** - Basic SQL queries are sufficient
10. **Community nodes** - Just official packages for now
## Success Metrics
1. **Accuracy**: 100% correct node-to-documentation mapping for test nodes
2. **Coverage**: All nodes from n8n-nodes-base and n8n-nodes-langchain
3. **Performance**: Full rebuild in <30 seconds
4. **Simplicity**: Single command rebuild (`npm run rebuild`)
5. **Reliability**: No failures on standard nodes
6. **Validation**: All critical nodes pass validation script
## Quick Start Guide
```bash
# Setup
git clone https://github.com/n8n-io/n8n-docs.git ../n8n-docs
npm install
# Build
npm run build
# Rebuild database
npm run rebuild
# Validate
npm run validate
# Start MCP server
npm start
```
## NPM Scripts
```json
{
"scripts": {
"build": "tsc",
"rebuild": "node dist/scripts/rebuild.js",
"validate": "node dist/scripts/validate.js",
"start": "node dist/mcp/server.js",
"dev": "npm run build && npm run rebuild && npm run validate"
}
}
```
## Summary
This v2.1 Final plan delivers a working MVP in 2 weeks by:
- **Starting with the test harness** - Build rebuild script first
- **Getting quick wins** - 5 nodes on Day 1
- **Testing critical nodes early** - HTTP Request, Slack, Code, AI Agent
- **Using local documentation** - Clone n8n-docs for file access
- **Validating success** - Automated validation script
The result: A reliable, accurate node documentation service that can be enhanced incrementally post-MVP.
**Ready to build! 🚀**

View File

@@ -1,101 +0,0 @@
# Claude Desktop Configuration for n8n-MCP
## Setup Instructions
1. **Build the project first:**
```bash
cd /Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp
npm run build
npm run rebuild
```
2. **Locate your Claude Desktop config file:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
3. **Add the n8n-documentation server to your config:**
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/Users/johndoe/projects/n8n-mcp/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "production"
}
}
}
}
```
**Note**: Update the path in `args` to match your actual installation directory.
4. **Restart Claude Desktop** to load the new configuration.
## Available Tools
Once configured, you'll have access to these tools in Claude:
- **`list_nodes`** - List and filter n8n nodes
```
list_nodes({ package: "n8n-nodes-base", limit: 10 })
```
- **`get_node_info`** - Get detailed information about a specific node
```
get_node_info({ nodeType: "httpRequest" })
```
- **`search_nodes`** - Search across all node documentation
```
search_nodes({ query: "webhook", limit: 20 })
```
- **`list_ai_tools`** - List nodes that can be used as AI Agent tools
```
list_ai_tools({})
```
- **`get_node_documentation`** - Get full documentation for a node
```
get_node_documentation({ nodeType: "slack" })
```
- **`get_database_statistics`** - Get statistics about the node database
```
get_database_statistics({})
```
## Troubleshooting
1. **If the server doesn't appear in Claude:**
- Check that the path in `args` is absolute and correct
- Ensure you've run `npm run build` and `npm run rebuild`
- Check `~/.n8n-mcp/logs/` for error logs
2. **If tools return errors:**
- Ensure the database exists: `data/nodes.db`
- Run `npm run validate` to check the database
- Rebuild if necessary: `npm run rebuild`
3. **For development/testing:**
You can also run with more verbose logging:
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/path/to/your/n8n-mcp/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "development",
"LOG_LEVEL": "debug"
}
}
}
}
```

62
docs/DOCKER_BUILD_FIX.md Normal file
View File

@@ -0,0 +1,62 @@
# Docker Build Fix
## Issue
The Docker build was failing with the error:
```
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref: "/data/nodes.db": not found
```
## Root Cause
The Dockerfile contained an invalid COPY command that tried to use shell operators:
```dockerfile
# This doesn't work in Docker
COPY --from=builder /app/data/nodes.db ./data/nodes.db 2>/dev/null || true
```
Docker's COPY command doesn't support shell operators like `2>/dev/null || true`.
## Solution
1. Removed the problematic COPY command
2. Created the data directory with RUN instead
3. Removed database pre-initialization from build stage
4. Database is now initialized at runtime by the entrypoint script
## Changes Made
### Dockerfile
```diff
- # Pre-initialize database during build
- RUN mkdir -p /app/data && npm run rebuild || echo "Database will be initialized at runtime"
+ # Build TypeScript only
+ RUN npm run build
- # Copy pre-built database if it exists
- COPY --from=builder /app/data/nodes.db ./data/nodes.db 2>/dev/null || true
+ # Create data directory
+ RUN mkdir -p /app/data
```
### GitHub Actions Workflow
Added conditional login to prevent failures on pull requests:
```diff
- name: Log in to GitHub Container Registry
+ if: github.event_name != 'pull_request'
uses: docker/login-action@v3
```
## Result
✅ Docker build now succeeds
✅ Database initialization happens at container startup
✅ GitHub Actions workflow will work properly
✅ No manual intervention required
## Testing
```bash
# Build locally
docker build -t n8n-mcp:test .
# Run and verify
docker run -d --name test -e MCP_MODE=http -e AUTH_TOKEN=test -p 3000:3000 n8n-mcp:test
docker logs test
curl http://localhost:3000/health
```

View File

@@ -74,10 +74,11 @@
### 🔧 Recommended Fixes
1. **Immediate (Phase 1)**
- Include schema.sql in Docker image
- Add scripts directory for rebuild functionality
- Test database initialization in clean environment
1. **Immediate (Phase 1)** ✅ FIXED
- Include schema.sql in Docker image
- Add scripts directory for rebuild functionality
- ✅ Removed invalid COPY syntax that caused build errors
- ✅ Database initialization happens at runtime, not build time
2. **Future Improvements (Phase 2)**
- Optimize image size with multi-stage pruning

View File

@@ -6,17 +6,70 @@ This guide explains how to deploy n8n-MCP as a private HTTP server for remote ac
The HTTP mode allows you to run n8n-MCP on a remote server and connect to it from Claude Desktop using the mcp-remote adapter. This is designed for single-user private deployments.
## Requirements
## Deployment Options
- Node.js v16+ on the server
- A server with a public IP or domain
- HTTPS proxy (nginx/caddy) for secure connections
- mcp-remote installed on the client
### Option 1: Docker Deployment (Recommended) 🐳
## Server Setup
The easiest way to deploy n8n-MCP is using Docker:
### 1. Clone and Build
#### Quick Start
```bash
# 1. Create configuration
echo "AUTH_TOKEN=$(openssl rand -base64 32)" > .env
# 2. Start with Docker Compose
docker compose up -d
# 3. Check health
curl http://localhost:3000/health
```
#### Production Deployment
```bash
# 1. Clone repository
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
# 2. Create production .env
cat > .env << EOF
AUTH_TOKEN=$(openssl rand -base64 32)
NODE_ENV=production
LOG_LEVEL=info
PORT=3000
EOF
# 3. Deploy with Docker Compose
docker compose up -d
# 4. Check logs
docker compose logs -f
```
#### Using Pre-built Images
```yaml
# docker-compose.yml
version: '3.8'
services:
n8n-mcp:
image: ghcr.io/czlonkowski/n8n-mcp:latest
environment:
MCP_MODE: http
AUTH_TOKEN: ${AUTH_TOKEN:?Required}
ports:
- "3000:3000"
volumes:
- n8n-mcp-data:/app/data
restart: unless-stopped
volumes:
n8n-mcp-data:
```
### Option 2: Manual Installation
If you prefer not to use Docker:
#### 1. Clone and Build
```bash
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
@@ -25,8 +78,7 @@ npm run build
npm run rebuild
```
### 2. Configure Environment
#### 2. Configure Environment
```bash
cp .env.example .env
```
@@ -47,13 +99,7 @@ MCP_LOG_LEVEL=info
NODE_ENV=production
```
Generate a secure token:
```bash
openssl rand -base64 32
```
### 3. Start the Server
#### 3. Start the Server
```bash
# Using the deployment script
./scripts/deploy-http.sh
@@ -220,33 +266,95 @@ The test script checks:
## Troubleshooting
### Connection Refused
### Docker-specific Issues
#### Container won't start
```bash
# Check logs
docker compose logs n8n-mcp
# Check if port is already in use
lsof -i :3000
# Rebuild and restart
docker compose down
docker compose up -d --build
```
#### Database initialization fails
```bash
# Copy existing database
docker cp data/nodes.db n8n-mcp:/app/data/
# Or rebuild inside container
docker compose exec n8n-mcp npm run rebuild
```
#### Permission issues
```bash
# Fix volume permissions
docker compose exec n8n-mcp chown -R nodejs:nodejs /app/data
```
### General Issues
#### Connection Refused
- Check firewall rules
- Verify server is running
- Check nginx/proxy configuration
- Run the test script to diagnose
- For Docker: ensure ports are mapped correctly
### Authentication Failed
#### Authentication Failed
- Verify AUTH_TOKEN matches in both server and client
- Check Authorization header format
- Token should be at least 32 characters
- Docker: check .env file is loaded
### MCP Tools Not Available
#### MCP Tools Not Available
- Restart Claude Desktop
- Check mcp-remote installation
- Verify server logs for errors
- Ensure CORS headers are working
- Docker: check container health status
## Performance Tips
1. Use a VPS with good network connectivity
2. Enable gzip compression in your proxy
3. Consider using PM2 for process management:
3. For Docker deployments:
- Use `--restart unless-stopped` for reliability
- Monitor with `docker stats n8n-mcp`
- Set memory limits in docker-compose.yml
4. For manual deployments, use PM2:
```bash
pm2 start npm --name "n8n-mcp" -- run start:http
```
## Example Systemd Service
## Production Deployment Examples
### Using Docker with Systemd
Create `/etc/systemd/system/n8n-mcp-docker.service`:
```ini
[Unit]
Description=n8n MCP Docker Container
After=docker.service
Requires=docker.service
[Service]
Type=simple
WorkingDirectory=/opt/n8n-mcp
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
### Manual Installation with Systemd
Create `/etc/systemd/system/n8n-mcp.service`:

331
docs/INSTALLATION.md Normal file
View File

@@ -0,0 +1,331 @@
# Installation Guide
This guide covers all installation methods for n8n-MCP.
## Table of Contents
- [Quick Start](#quick-start)
- [Docker Installation](#docker-installation)
- [Manual Installation](#manual-installation)
- [Development Setup](#development-setup)
- [Troubleshooting](#troubleshooting)
## Quick Start
The fastest way to get n8n-MCP running:
```bash
# Using Docker (recommended)
echo "AUTH_TOKEN=$(openssl rand -base64 32)" > .env
docker compose up -d
```
## Docker Installation
### Prerequisites
- Docker Desktop or Docker Engine
- Docker Compose (included with Docker Desktop)
### Method 1: Using Pre-built Images
1. **Create a project directory:**
```bash
mkdir n8n-mcp && cd n8n-mcp
```
2. **Create docker-compose.yml:**
```yaml
version: '3.8'
services:
n8n-mcp:
image: ghcr.io/czlonkowski/n8n-mcp:latest
container_name: n8n-mcp
restart: unless-stopped
environment:
MCP_MODE: ${MCP_MODE:-http}
AUTH_TOKEN: ${AUTH_TOKEN:?AUTH_TOKEN is required}
NODE_ENV: ${NODE_ENV:-production}
LOG_LEVEL: ${LOG_LEVEL:-info}
PORT: ${PORT:-3000}
volumes:
- n8n-mcp-data:/app/data
ports:
- "${PORT:-3000}:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
n8n-mcp-data:
driver: local
```
3. **Create .env file:**
```bash
echo "AUTH_TOKEN=$(openssl rand -base64 32)" > .env
```
4. **Start the container:**
```bash
docker compose up -d
```
5. **Verify installation:**
```bash
curl http://localhost:3000/health
```
### Method 2: Building from Source
1. **Clone the repository:**
```bash
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
```
2. **Build the image:**
```bash
docker build -t n8n-mcp:local .
```
3. **Run with docker-compose:**
```bash
docker compose up -d
```
### Docker Management Commands
```bash
# View logs
docker compose logs -f
# Stop the container
docker compose stop
# Remove container and volumes
docker compose down -v
# Update to latest image
docker compose pull
docker compose up -d
# Execute commands inside container
docker compose exec n8n-mcp npm run validate
# Backup database
docker cp n8n-mcp:/app/data/nodes.db ./nodes-backup.db
```
## Manual Installation
### Prerequisites
- Node.js v16+ (v20+ recommended)
- npm or yarn
- Git
### Step-by-Step Installation
1. **Clone the repository:**
```bash
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
```
2. **Clone n8n documentation (optional but recommended):**
```bash
git clone https://github.com/n8n-io/n8n-docs.git ../n8n-docs
```
3. **Install dependencies:**
```bash
npm install
```
4. **Build the project:**
```bash
npm run build
```
5. **Initialize the database:**
```bash
npm run rebuild
```
6. **Validate installation:**
```bash
npm run test-nodes
```
### Running the Server
#### stdio Mode (for Claude Desktop)
```bash
npm start
```
#### HTTP Mode (for remote access)
```bash
npm run start:http
```
### Environment Configuration
Create a `.env` file in the project root:
```env
# Server configuration
MCP_MODE=http # or stdio
PORT=3000
HOST=0.0.0.0
NODE_ENV=production
LOG_LEVEL=info
# Authentication (required for HTTP mode)
AUTH_TOKEN=your-secure-token-here
# Database
NODE_DB_PATH=./data/nodes.db
REBUILD_ON_START=false
```
## Development Setup
### Prerequisites
- All manual installation prerequisites
- TypeScript knowledge
- Familiarity with MCP protocol
### Setup Steps
1. **Clone and install:**
```bash
git clone https://github.com/czlonkowski/n8n-mcp.git
cd n8n-mcp
npm install
```
2. **Set up development environment:**
```bash
cp .env.example .env
# Edit .env with your settings
```
3. **Development commands:**
```bash
# Run in development mode with auto-reload
npm run dev
# Run tests
npm test
# Type checking
npm run typecheck
# Linting
npm run lint
```
### Docker Development
1. **Use docker-compose override:**
```bash
cp docker-compose.override.yml.example docker-compose.override.yml
```
2. **Edit override for development:**
```yaml
version: '3.8'
services:
n8n-mcp:
build: .
environment:
NODE_ENV: development
LOG_LEVEL: debug
volumes:
- ./src:/app/src:ro
- ./dist:/app/dist
```
3. **Run with live reload:**
```bash
docker compose up --build
```
## Troubleshooting
### Common Issues
#### Port Already in Use
```bash
# Find process using port 3000
lsof -i :3000
# Use a different port
PORT=3001 docker compose up -d
```
#### Database Initialization Failed
```bash
# For Docker
docker compose exec n8n-mcp npm run rebuild
# For manual installation
npm run rebuild
```
#### Permission Denied Errors
```bash
# Fix permissions (Linux/macOS)
sudo chown -R $(whoami) ./data
# For Docker volumes
docker compose exec n8n-mcp chown -R nodejs:nodejs /app/data
```
#### Node Version Mismatch
The project includes automatic fallback to sql.js for compatibility. If you still have issues:
```bash
# Check Node version
node --version
# Use nvm to switch versions
nvm use 20
```
### Getting Help
1. Check the logs:
- Docker: `docker compose logs`
- Manual: Check console output or `LOG_LEVEL=debug npm start`
2. Validate the database:
```bash
npm run validate
```
3. Run tests:
```bash
npm test
```
4. Report issues:
- GitHub Issues: https://github.com/czlonkowski/n8n-mcp/issues
- Include logs and environment details
## Next Steps
After installation, configure Claude Desktop to use n8n-MCP:
- See [Claude Desktop Setup Guide](./README_CLAUDE_SETUP.md)
- For remote deployments, see [HTTP Deployment Guide](./HTTP_DEPLOYMENT.md)
- For Docker details, see [Docker README](../DOCKER_README.md)

66
docs/README.md Normal file
View File

@@ -0,0 +1,66 @@
# n8n-MCP Documentation
Welcome to the n8n-MCP documentation. This directory contains comprehensive guides for installation, configuration, and troubleshooting.
## 📚 Documentation Index
### Getting Started
- **[Installation Guide](./INSTALLATION.md)** - All installation methods including Docker, manual, and development setup
- **[Claude Desktop Setup](./README_CLAUDE_SETUP.md)** - Configure Claude Desktop to use n8n-MCP
- **[Quick Start Tutorial](../README.md)** - Basic overview and quick start instructions
### Deployment
- **[HTTP Deployment Guide](./HTTP_DEPLOYMENT.md)** - Deploy n8n-MCP as an HTTP server for remote access
- **[Docker Deployment](../DOCKER_README.md)** - Comprehensive Docker deployment guide
- **[Docker Testing Results](./DOCKER_TESTING_RESULTS.md)** - Docker implementation test results and findings
### Development
- **[Implementation Plan](../IMPLEMENTATION_PLAN.md)** - Technical implementation details
- **[HTTP Implementation Guide](./HTTP_IMPLEMENTATION_GUIDE.md)** - HTTP server implementation details
- **[Development Setup](./INSTALLATION.md#development-setup)** - Set up development environment
### Reference
- **[Troubleshooting Guide](./TROUBLESHOOTING.md)** - Solutions for common issues
- **[API Reference](./API_REFERENCE.md)** - MCP tools and API documentation (if available)
- **[Environment Variables](./INSTALLATION.md#environment-configuration)** - Configuration options
## 🚀 Quick Links
### For Users
1. **First Time Setup**: Start with the [Installation Guide](./INSTALLATION.md)
2. **Claude Desktop Users**: Follow [Claude Desktop Setup](./README_CLAUDE_SETUP.md)
3. **Remote Deployment**: See [HTTP Deployment Guide](./HTTP_DEPLOYMENT.md)
### For Developers
1. **Local Development**: See [Development Setup](./INSTALLATION.md#development-setup)
2. **Docker Development**: Check [Docker README](../DOCKER_README.md)
3. **Contributing**: Read the implementation plans and guides
## 🐳 Docker Quick Start
```bash
# Quick start with Docker
echo "AUTH_TOKEN=$(openssl rand -base64 32)" > .env
docker compose up -d
# Check health
curl http://localhost:3000/health
```
## 📖 Documentation Updates
This documentation is actively maintained. Recent updates include:
- ✅ Docker deployment support (Phase 1 complete)
- ✅ Simplified installation process
- ✅ Enhanced troubleshooting guide
- ✅ Multiple deployment options
## 🤝 Getting Help
- **Issues**: [GitHub Issues](https://github.com/czlonkowski/n8n-mcp/issues)
- **Discussions**: [GitHub Discussions](https://github.com/czlonkowski/n8n-mcp/discussions)
- **Troubleshooting**: [Troubleshooting Guide](./TROUBLESHOOTING.md)
## 📝 License
This project is licensed under the Sustainable Use License. See [LICENSE](../LICENSE) for details.

203
docs/README_CLAUDE_SETUP.md Normal file
View File

@@ -0,0 +1,203 @@
# Claude Desktop Configuration for n8n-MCP
## Setup Options
You can set up n8n-MCP with Claude Desktop in three ways:
### Option 1: Docker (Recommended) 🐳
The easiest way to get started is using Docker:
#### 1a. Docker with HTTP Mode (Remote Access)
```json
{
"mcpServers": {
"n8n-remote": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/mcp-remote@latest",
"connect",
"http://localhost:3000/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-auth-token-here"
}
}
}
}
```
**Setup steps:**
1. Create a `.env` file:
```bash
echo "AUTH_TOKEN=$(openssl rand -base64 32)" > .env
```
2. Start the server:
```bash
docker compose up -d
```
3. Copy the AUTH_TOKEN to your Claude config
#### 1b. Docker with stdio Mode (Direct)
```json
{
"mcpServers": {
"n8n-docker": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e", "MCP_MODE=stdio",
"-v", "n8n-mcp-data:/app/data",
"ghcr.io/czlonkowski/n8n-mcp:latest"
]
}
}
}
```
### Option 2: Local Installation
1. **Build the project first:**
```bash
cd /path/to/n8n-mcp
npm install
npm run build
npm run rebuild
```
2. **Add to Claude Desktop config:**
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/path/to/n8n-mcp/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "production"
}
}
}
}
```
### Option 3: NPM Global Install (Coming Soon)
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "npx",
"args": [
"-y",
"n8n-mcp@latest"
]
}
}
}
```
## Configuration File Locations
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
After updating the config, **restart Claude Desktop** to load the new configuration.
## Available Tools
Once configured, you'll have access to these tools in Claude:
- **`list_nodes`** - List and filter n8n nodes
```
list_nodes({ package: "n8n-nodes-base", limit: 10 })
```
- **`get_node_info`** - Get detailed information about a specific node
```
get_node_info({ nodeType: "httpRequest" })
```
- **`search_nodes`** - Search across all node documentation
```
search_nodes({ query: "webhook", limit: 20 })
```
- **`list_ai_tools`** - List nodes that can be used as AI Agent tools
```
list_ai_tools({})
```
- **`get_node_documentation`** - Get full documentation for a node
```
get_node_documentation({ nodeType: "slack" })
```
- **`get_database_statistics`** - Get statistics about the node database
```
get_database_statistics({})
```
## Troubleshooting
### Docker Issues
1. **Container fails to start:**
```bash
# Check logs
docker compose logs -f
# Check if port is in use
lsof -i :3000
```
2. **Authentication errors:**
- Ensure AUTH_TOKEN matches in .env and Claude config
- Token should be at least 32 characters
- Check quotes in JSON config
3. **Database not found:**
- The container will auto-initialize on first run
- To rebuild: `docker compose exec n8n-mcp npm run rebuild`
### Local Installation Issues
1. **If the server doesn't appear in Claude:**
- Check that the path in `args` is absolute and correct
- Ensure you've run `npm run build` and `npm run rebuild`
- Verify Node.js version compatibility
2. **If tools return errors:**
- Ensure the database exists: `data/nodes.db`
- Run `npm run validate` to check the database
- Rebuild if necessary: `npm run rebuild`
3. **For development/testing:**
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/path/to/your/n8n-mcp/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "development",
"LOG_LEVEL": "debug"
}
}
}
}
```
### Common Solutions
- **Restart Claude Desktop** after config changes
- **Check file permissions** on Unix systems
- **Use absolute paths** in configuration
- **Verify JSON syntax** in claude_desktop_config.json

402
docs/TROUBLESHOOTING.md Normal file
View File

@@ -0,0 +1,402 @@
# Troubleshooting Guide
This guide helps resolve common issues with n8n-MCP.
## Table of Contents
- [Docker Issues](#docker-issues)
- [Installation Issues](#installation-issues)
- [Runtime Errors](#runtime-errors)
- [Claude Desktop Issues](#claude-desktop-issues)
- [Database Problems](#database-problems)
- [Network and Authentication](#network-and-authentication)
- [Performance Issues](#performance-issues)
## Docker Issues
### Container Won't Start
#### Symptoms
- `docker compose up` fails
- Container exits immediately
- No logs available
#### Solutions
1. **Check if port is in use:**
```bash
lsof -i :3000
# or
netstat -tulpn | grep 3000
```
2. **View detailed logs:**
```bash
docker compose logs -f --tail 100
```
3. **Check Docker resources:**
```bash
docker system df
docker system prune -a # Clean up unused resources
```
4. **Verify image download:**
```bash
docker compose pull
```
### Database Initialization Fails in Docker
#### Symptoms
- Error: `ENOENT: no such file or directory, open '/app/src/database/schema.sql'`
- Database not found errors
#### Solutions
1. **Rebuild the image with latest Dockerfile:**
```bash
docker compose build --no-cache
docker compose up -d
```
2. **Copy existing database:**
```bash
# From host to container
docker cp data/nodes.db n8n-mcp:/app/data/
# Restart container
docker compose restart
```
3. **Initialize inside container:**
```bash
docker compose exec n8n-mcp npm run rebuild
```
### Permission Denied in Docker
#### Symptoms
- Cannot write to /app/data
- Permission denied errors in logs
#### Solutions
```bash
# Fix permissions
docker compose exec n8n-mcp chown -R nodejs:nodejs /app/data
# Or run as root temporarily
docker compose exec -u root n8n-mcp chown -R nodejs:nodejs /app
```
### Docker Compose Variables Not Loading
#### Symptoms
- AUTH_TOKEN not recognized
- Environment variables missing
#### Solutions
1. **Check .env file location:**
```bash
ls -la .env
cat .env
```
2. **Verify compose file:**
```bash
docker compose config
```
3. **Set variables explicitly:**
```bash
AUTH_TOKEN=mytoken docker compose up -d
```
## Installation Issues
### npm install Fails
#### Symptoms
- Dependency errors
- Node version mismatch
- Native module compilation fails
#### Solutions
1. **Clear npm cache:**
```bash
npm cache clean --force
rm -rf node_modules package-lock.json
npm install
```
2. **Check Node version:**
```bash
node --version # Should be v16+
npm --version # Should be v7+
```
3. **Use fallback for better-sqlite3:**
The project automatically falls back to sql.js if native modules fail.
### Build Errors
#### Symptoms
- TypeScript compilation errors
- Missing type definitions
#### Solutions
```bash
# Clean build
rm -rf dist
npm run build
# Check TypeScript version
npx tsc --version
# Install missing types
npm install --save-dev @types/node
```
## Runtime Errors
### MCP Tools Not Available
#### Symptoms
- Tools don't appear in Claude Desktop
- "Unknown tool" errors
#### Solutions
1. **Verify server is running:**
```bash
# For Docker
docker compose ps
docker compose logs
# For local
ps aux | grep node
```
2. **Check database:**
```bash
npm run validate
npm run test-nodes
```
3. **Restart Claude Desktop** after configuration changes
### Stream Not Readable Error
#### Symptoms
- Error: "InternalServerError: stream is not readable"
- MCP endpoint returns errors
#### Solutions
1. **Check database initialization:**
```bash
ls -la data/nodes.db
npm run validate
```
2. **Verify HTTP headers:**
```bash
curl -H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $AUTH_TOKEN" \
http://localhost:3000/mcp
```
## Claude Desktop Issues
### Server Not Appearing
#### Solutions
1. **Verify config file location:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
2. **Check JSON syntax:**
```bash
# Validate JSON
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | jq .
```
3. **Use absolute paths:**
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/absolute/path/to/n8n-mcp/dist/mcp/index.js"
]
}
}
}
```
### Authentication Errors with Claude
#### Solutions
1. **Match tokens exactly:**
```bash
# In .env
AUTH_TOKEN=your-token-here
# In Claude config
"MCP_AUTH_TOKEN": "your-token-here"
```
2. **Check for special characters:**
- Avoid quotes in token values
- Use base64 encoding for safety
## Database Problems
### Database Corruption
#### Symptoms
- SQLite errors
- Unexpected results
- Missing nodes
#### Solutions
1. **Rebuild database:**
```bash
# Backup first
cp data/nodes.db data/nodes.db.bak
# Rebuild
npm run rebuild
```
2. **Validate after rebuild:**
```bash
npm run validate
npm run test-nodes
```
### Database Locked
#### Symptoms
- SQLITE_BUSY errors
- Cannot write to database
#### Solutions
```bash
# Find processes using the database
lsof data/nodes.db
# For Docker
docker compose restart
```
## Network and Authentication
### CORS Errors
#### Symptoms
- Browser console shows CORS errors
- Preflight requests fail
#### Solutions
1. **Check server CORS settings:**
- Verify MCP_MODE=http
- Check proxy configuration
2. **Test with curl:**
```bash
curl -X OPTIONS http://localhost:3000/mcp \
-H "Origin: http://localhost" \
-H "Access-Control-Request-Method: POST"
```
### SSL/HTTPS Issues
#### Solutions
1. **For development, use HTTP:**
```json
"connect", "http://localhost:3000/mcp"
```
2. **For production, use reverse proxy:**
- See nginx/Caddy examples in HTTP_DEPLOYMENT.md
## Performance Issues
### Slow Response Times
#### Solutions
1. **Check resource usage:**
```bash
# Docker
docker stats n8n-mcp
# System
top
htop
```
2. **Increase memory limits:**
```yaml
# docker-compose.yml
deploy:
resources:
limits:
memory: 1G
```
3. **Enable query logging:**
```bash
LOG_LEVEL=debug npm start
```
### High Memory Usage
#### Solutions
1. **Monitor with Docker:**
```bash
docker compose exec n8n-mcp ps aux
```
2. **Restart periodically:**
```bash
# Add to crontab
0 */6 * * * docker compose restart
```
## Getting More Help
1. **Enable debug logging:**
```bash
LOG_LEVEL=debug docker compose up
```
2. **Collect diagnostic info:**
```bash
# System info
uname -a
node --version
docker --version
# Project info
git rev-parse HEAD
npm list
```
3. **Report issues:**
- GitHub: https://github.com/czlonkowski/n8n-mcp/issues
- Include logs, environment, and steps to reproduce