docs: add comprehensive HTTP remote deployment planning documentation

- HTTP_REMOTE_DEPLOYMENT_PLAN.md: High-level architecture and implementation plan
- HTTP_IMPLEMENTATION_GUIDE.md: Detailed technical implementation with code examples
- HTTP_IMPLEMENTATION_ROADMAP.md: Day-by-day implementation checklist and milestones
- HTTP_REMOTE_SUMMARY.md: Executive summary with key findings and recommendations
- Updated README.md with references to future HTTP deployment plans

Key findings:
- Claude Desktop currently only supports stdio transport (local execution)
- mcp-remote adapter enables remote server connectivity as a bridge solution
- Implementation requires adding StreamableHTTPServerTransport support
- Dual-mode operation will maintain backward compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-06-13 11:22:48 +02:00
parent 37637f4437
commit 23a21071bc
5 changed files with 1716 additions and 0 deletions

View File

@@ -0,0 +1,792 @@
# 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

@@ -0,0 +1,371 @@
# 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

@@ -0,0 +1,286 @@
# 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.

251
HTTP_REMOTE_SUMMARY.md Normal file
View File

@@ -0,0 +1,251 @@
# 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

@@ -184,6 +184,22 @@ Current implementation achieves:
- ✅ 35 AI-capable tools detected
- ✅ All critical nodes validated
## Future Development
### HTTP Remote Deployment (Planned)
We are planning to add HTTP transport support to enable remote deployment of the MCP server. This will allow:
- Centralized hosting on cloud servers
- Multiple users connecting to a single instance
- No local installation required
- Enterprise-ready authentication
For detailed planning documents, see:
- [HTTP Remote Deployment Plan](./HTTP_REMOTE_DEPLOYMENT_PLAN.md)
- [HTTP Implementation Guide](./HTTP_IMPLEMENTATION_GUIDE.md)
- [HTTP Implementation Roadmap](./HTTP_IMPLEMENTATION_ROADMAP.md)
- [HTTP Remote Summary](./HTTP_REMOTE_SUMMARY.md)
## Contributing
1. Fork the repository