- Added SSE server implementation for real-time event streaming - Created n8n compatibility mode with strict schema validation - Implemented session management for concurrent connections - Added comprehensive SSE documentation and examples - Enhanced MCP tools with async execution support - Added Docker Compose configuration for SSE deployment - Included test scripts and integration tests 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
6.8 KiB
SSE (Server-Sent Events) Implementation for n8n MCP
Overview
This document describes the SSE implementation that enables n8n's MCP Server Trigger to connect to n8n-mcp server using Server-Sent Events protocol.
Architecture
Components
-
SSE Server (
src/sse-server.ts)- Main Express server with SSE endpoints
- Handles authentication and CORS
- Manages both SSE connections and message processing
-
SSE Session Manager (
src/utils/sse-session-manager.ts)- Manages active SSE client connections
- Handles session lifecycle and cleanup
- Sends events to connected clients
-
Type Definitions (
src/types/sse.ts)- TypeScript interfaces for SSE messages
- MCP protocol message types
Endpoints
GET /sse, GET /mcp, and GET /mcp/:path/sse
- Purpose: SSE connection endpoint for n8n MCP Server Trigger
- Authentication: Multiple methods supported (see Authentication section)
- Query Parameters (optional):
workflowId: n8n workflow IDexecutionId: n8n execution IDnodeId: n8n node IDnodeName: n8n node namerunId: n8n run IDtoken: Authentication token (for SSE connections)
- Headers (optional):
X-Workflow-ID: n8n workflow IDX-Execution-ID: n8n execution IDX-Node-ID: n8n node IDX-Node-Name: n8n node nameX-Run-ID: n8n run ID
- Response: Event stream with MCP protocol messages
- Events:
connected: Initial connection confirmation with client IDmcp-response: MCP protocol responsesmcp-error: Error messagesping: Keep-alive messages (every 30 seconds)
POST /mcp/message and POST /mcp/:path/message
- Purpose: Receive MCP requests from n8n
- Authentication: Multiple methods supported (see Authentication section)
- Headers:
X-Client-ID: SSE session client ID (required)
- Request Body: JSON-RPC 2.0 format
- Response: Acknowledgment with message ID
POST /mcp and POST /mcp/:path (Legacy)
- Purpose: Backward compatibility with HTTP POST mode
- Authentication: Multiple methods supported (see Authentication section)
- Request/Response: Standard JSON-RPC 2.0
GET /health
- Purpose: Health check endpoint
- Response: Server status including active SSE sessions
Protocol Flow
-
Connection:
n8n → GET /mcp/workflow-123/sse?workflowId=123&nodeId=456 (with auth) ← SSE connection established ← Event: connected {clientId: "uuid"} ← Event: mcp-response {method: "mcp/ready"} -
Tool Discovery:
n8n → POST /mcp/workflow-123/message {method: "tools/list"} ← Response: {status: "ok"} ← Event: mcp-response {result: {tools: [...]}} -
Tool Execution:
n8n → POST /mcp/workflow-123/message {method: "tools/call", params: {name, arguments}} ← Response: {status: "ok"} ← Event: mcp-response {result: {content: [...]}} -
Resources and Prompts (empty implementations):
n8n → POST /mcp/message {method: "resources/list"} ← Event: mcp-response {result: {resources: []}} n8n → POST /mcp/message {method: "prompts/list"} ← Event: mcp-response {result: {prompts: []}}
Configuration
Environment Variables
AUTH_TOKENorAUTH_TOKEN_FILE: Authentication token (required)AUTH_HEADER_NAME: Custom authentication header name (default: x-auth-token)PORT: Server port (default: 3000)HOST: Server host (default: 0.0.0.0)CORS_ORIGIN: Allowed CORS origin (default: *)TRUST_PROXY: Number of proxy hops for correct IP logging
Usage
Starting the SSE Server
# Build and start
npm run sse
# Development mode with auto-reload
npm run dev:sse
# With environment variables
AUTH_TOKEN=your-secure-token npm run sse
Testing the Implementation
# Run SSE tests
npm run test:sse
# Manual test with curl
# 1. Connect to SSE endpoint
curl -N -H "Authorization: Bearer your-token" http://localhost:3000/sse
# 2. Send a message (in another terminal)
curl -X POST http://localhost:3000/mcp/message \
-H "Authorization: Bearer your-token" \
-H "X-Client-ID: <client-id-from-sse>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
n8n Configuration
MCP Client Tool Node
- SSE Endpoint:
http://your-server:3000/mcp/your-path/sse - Authentication: Choose from supported methods
- Token: Your AUTH_TOKEN value
- Optional Headers: Add workflow context headers for better tracking
Security Considerations
Authentication Methods
The SSE server supports multiple authentication methods:
-
Bearer Token (recommended):
- Header:
Authorization: Bearer <token>
- Header:
-
Custom Header:
- Header:
X-Auth-Token: <token>(or custom via AUTH_HEADER_NAME env var)
- Header:
-
Query Parameter (for SSE connections):
- URL:
/sse?token=<token>
- URL:
-
API Key Header:
- Header:
X-API-Key: <token>
- Header:
Additional Security Features
- CORS: Configure CORS_ORIGIN for production deployments
- HTTPS: Use reverse proxy with SSL in production
- Session Timeout: Sessions expire after 5 minutes of inactivity
- Workflow Context: Track requests by workflow/node for auditing
Performance
- Keep-alive pings every 30 seconds prevent connection timeouts
- Session cleanup runs every 30 seconds
- Supports up to 1000 concurrent SSE connections (configurable)
- Minimal memory footprint per connection
- Enhanced debug logging available with LOG_LEVEL=debug
Troubleshooting
Connection Issues
- Check AUTH_TOKEN is set correctly
- Verify firewall allows SSE connections
- Check proxy configuration if behind reverse proxy
- n8n Connection Failed: If you see "Could not connect to your MCP server" in n8n logs, this is likely due to gzip compression breaking SSE. The server now explicitly disables compression with
Content-Encoding: identityheader
Message Delivery
- Ensure X-Client-ID header matches active session
- Check server logs for session expiration
- Verify JSON-RPC format is correct
Nginx Configuration
If behind Nginx, add these directives:
proxy_set_header Connection '';
proxy_http_version 1.1;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400s;
gzip off; # Important: Disable gzip for SSE endpoints
Note: n8n has known issues with gzip compression on SSE connections. Always disable compression for SSE endpoints.
Integration with n8n
The SSE implementation enables n8n workflows to:
- Receive real-time MCP events
- Execute long-running tool operations
- Handle asynchronous responses
- Support multiple concurrent workflows
This provides a more robust integration compared to simple HTTP polling, especially for:
- Long-running operations
- Real-time notifications
- Event-driven workflows
- Scalable deployments