- Add header extraction logic in http-server-single-session.ts - Extract X-N8n-Url, X-N8n-Key, X-Instance-Id, X-Session-Id headers - Pass extracted context to handleRequest method - Maintain full backward compatibility (falls back to env vars) - Add comprehensive tests for header extraction scenarios - Update documentation with HTTP header specifications This fixes the bug where instance-specific configuration headers were not being extracted and passed to the MCP server, preventing the multi-tenant feature from working as designed in PR #209. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
Flexible Instance Configuration
Overview
The Flexible Instance Configuration feature enables n8n-mcp to serve multiple users with different n8n instances dynamically, without requiring separate deployments for each user. This feature is designed for scenarios where n8n-mcp is hosted centrally and needs to connect to different n8n instances based on runtime context.
Architecture
Core Components
-
InstanceContext Interface (
src/types/instance-context.ts)- Runtime configuration container for instance-specific settings
- Optional fields for backward compatibility
- Comprehensive validation with security checks
-
Dual-Mode API Client
- Singleton Mode: Uses environment variables (backward compatible)
- Instance Mode: Uses runtime context for multi-instance support
- Automatic fallback between modes
-
LRU Cache with Security
- SHA-256 hashed cache keys for security
- 30-minute TTL with automatic cleanup
- Maximum 100 concurrent instances
- Secure dispose callbacks without logging sensitive data
-
Session Management
- HTTP server tracks session context
- Each session can have different instance configuration
- Automatic cleanup on session end
Configuration
Environment Variables
New environment variables for cache configuration:
INSTANCE_CACHE_MAX- Maximum number of cached instances (default: 100, min: 1, max: 10000)INSTANCE_CACHE_TTL_MINUTES- Cache TTL in minutes (default: 30, min: 1, max: 1440/24 hours)
Example:
# Increase cache size for high-volume deployments
export INSTANCE_CACHE_MAX=500
export INSTANCE_CACHE_TTL_MINUTES=60
InstanceContext Structure
interface InstanceContext {
n8nApiUrl?: string; // n8n instance URL
n8nApiKey?: string; // API key for authentication
n8nApiTimeout?: number; // Request timeout in ms (default: 30000)
n8nApiMaxRetries?: number; // Max retry attempts (default: 3)
instanceId?: string; // Unique instance identifier
sessionId?: string; // Session identifier
metadata?: Record<string, any>; // Additional metadata
}
Validation Rules
-
URL Validation:
- Must be valid HTTP/HTTPS URL
- No file://, javascript:, or other dangerous protocols
- Proper URL format with protocol and host
-
API Key Validation:
- Non-empty string required when provided
- No placeholder values (e.g., "YOUR_API_KEY")
- Case-insensitive placeholder detection
-
Numeric Validation:
- Timeout must be positive number (>0)
- Max retries must be non-negative (≥0)
- No Infinity or NaN values
Usage Examples
Basic Usage
import { getN8nApiClient } from './mcp/handlers-n8n-manager';
import { InstanceContext } from './types/instance-context';
// Create context for a specific instance
const context: InstanceContext = {
n8nApiUrl: 'https://customer1.n8n.cloud',
n8nApiKey: 'customer1-api-key',
instanceId: 'customer1'
};
// Get client for this instance
const client = getN8nApiClient(context);
if (client) {
// Use client for API operations
const workflows = await client.getWorkflows();
}
HTTP Headers for Multi-Tenant Support
When using the HTTP server mode, clients can pass instance-specific configuration via HTTP headers:
# Example curl request with instance headers
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer your-auth-token" \
-H "Content-Type: application/json" \
-H "X-N8n-Url: https://instance1.n8n.cloud" \
-H "X-N8n-Key: instance1-api-key" \
-H "X-Instance-Id: instance-1" \
-H "X-Session-Id: session-123" \
-d '{"method": "n8n_list_workflows", "params": {}, "id": 1}'
Supported Headers
- X-N8n-Url: The n8n instance URL (e.g.,
https://instance.n8n.cloud) - X-N8n-Key: The API key for authentication with the n8n instance
- X-Instance-Id: A unique identifier for the instance (optional, for tracking)
- X-Session-Id: A session identifier (optional, for session tracking)
Header Extraction Logic
- If either
X-N8n-UrlorX-N8n-Keyheader is present, an instance context is created - All headers are extracted and passed to the MCP server
- The server uses the instance-specific configuration instead of environment variables
- If no headers are present, the server falls back to environment variables (backward compatible)
Example: JavaScript Client
const headers = {
'Authorization': 'Bearer your-auth-token',
'Content-Type': 'application/json',
'X-N8n-Url': 'https://customer1.n8n.cloud',
'X-N8n-Key': 'customer1-api-key',
'X-Instance-Id': 'customer-1',
'X-Session-Id': 'session-456'
};
const response = await fetch('http://localhost:3000/mcp', {
method: 'POST',
headers: headers,
body: JSON.stringify({
method: 'n8n_list_workflows',
params: {},
id: 1
})
});
const result = await response.json();
HTTP Server Integration
// In HTTP request handler
app.post('/mcp', (req, res) => {
const context: InstanceContext = {
n8nApiUrl: req.headers['x-n8n-url'],
n8nApiKey: req.headers['x-n8n-key'],
sessionId: req.sessionID
};
// Context passed to handlers
const result = await handleRequest(req.body, context);
res.json(result);
});
Validation Example
import { validateInstanceContext } from './types/instance-context';
const context: InstanceContext = {
n8nApiUrl: 'https://api.n8n.cloud',
n8nApiKey: 'valid-key'
};
const validation = validateInstanceContext(context);
if (!validation.valid) {
console.error('Validation errors:', validation.errors);
} else {
// Context is valid, proceed
const client = getN8nApiClient(context);
}
Security Features
1. Cache Key Hashing
- All cache keys use SHA-256 hashing with memoization
- Prevents sensitive data exposure in logs
- Example:
sha256(url:key:instance)→ 64-char hex string - Memoization cache limited to 1000 entries
2. Enhanced Input Validation
- Field-specific error messages with detailed reasons
- URL protocol restrictions (HTTP/HTTPS only)
- API key placeholder detection (case-insensitive)
- Numeric range validation with specific error messages
- Example: "Invalid n8nApiUrl: ftp://example.com - URL must use HTTP or HTTPS protocol"
3. Secure Logging
- Only first 8 characters of cache keys logged
- No sensitive data in debug logs
- URL sanitization (domain only, no paths)
- Configuration fallback logging for debugging
4. Memory Management
- Configurable LRU cache with automatic eviction
- TTL-based expiration (configurable, default 30 minutes)
- Dispose callbacks for cleanup
- Maximum cache size limits with bounds checking
5. Concurrency Protection
- Mutex-based locking for cache operations
- Prevents duplicate client creation
- Simple lock checking with timeout
- Thread-safe cache operations
Performance Optimization
Cache Strategy
- Max Size: Configurable via
INSTANCE_CACHE_MAX(default: 100) - TTL: Configurable via
INSTANCE_CACHE_TTL_MINUTES(default: 30) - Update on Access: Age refreshed on each use
- Eviction: Least Recently Used (LRU) policy
- Memoization: Hash creation uses memoization for frequently used keys
Cache Metrics
The system tracks comprehensive metrics:
- Cache hits and misses
- Hit rate percentage
- Eviction count
- Current size vs maximum size
- Operation timing
Retrieve metrics using:
import { getInstanceCacheStatistics } from './mcp/handlers-n8n-manager';
console.log(getInstanceCacheStatistics());
Benefits
- Performance: ~12ms average response time
- Memory Efficient: Minimal footprint per instance
- Thread Safe: Mutex protection for concurrent operations
- Auto Cleanup: Unused instances automatically evicted
- No Memory Leaks: Proper disposal callbacks
Backward Compatibility
The feature maintains 100% backward compatibility:
-
Environment Variables Still Work:
- If no context provided, falls back to env vars
- Existing deployments continue working unchanged
-
Optional Parameters:
- All context fields are optional
- Missing fields use defaults or env vars
-
API Unchanged:
- Same handler signatures with optional context
- No breaking changes to existing code
Testing
Comprehensive test coverage ensures reliability:
# Run all flexible instance tests
npm test -- tests/unit/flexible-instance-security-advanced.test.ts
npm test -- tests/unit/mcp/lru-cache-behavior.test.ts
npm test -- tests/unit/types/instance-context-coverage.test.ts
npm test -- tests/unit/mcp/handlers-n8n-manager-simple.test.ts
Test Coverage Areas
- Input validation edge cases
- Cache behavior and eviction
- Security (hashing, sanitization)
- Session management
- Memory leak prevention
- Concurrent access patterns
Migration Guide
For Existing Deployments
No changes required - environment variables continue to work.
For Multi-Instance Support
- Update HTTP Server (if using HTTP mode):
// Add context extraction from headers
const context = extractInstanceContext(req);
- Pass Context to Handlers:
// Old way (still works)
await handleListWorkflows(params);
// New way (with instance context)
await handleListWorkflows(params, context);
- Configure Clients to send instance information:
// Client sends instance info in headers
headers: {
'X-N8n-Url': 'https://instance.n8n.cloud',
'X-N8n-Key': 'api-key',
'X-Instance-Id': 'customer-123'
}
Monitoring
Metrics to Track
- Cache hit/miss ratio
- Instance count in cache
- Average TTL utilization
- Memory usage per instance
- API client creation rate
Debug Logging
Enable debug logs to monitor cache behavior:
LOG_LEVEL=debug npm start
Limitations
- Maximum Instances: 100 concurrent instances (configurable)
- TTL: 30-minute cache lifetime (configurable)
- Memory: ~1MB per cached instance (estimated)
- Validation: Strict validation may reject edge cases
Security Considerations
- Never Log Sensitive Data: API keys are never logged
- Hash All Identifiers: Use SHA-256 for cache keys
- Validate All Input: Comprehensive validation before use
- Limit Resources: Cache size and TTL limits
- Clean Up Properly: Dispose callbacks for resource cleanup
Future Enhancements
Potential improvements for future versions:
- Configurable Cache Settings: Runtime cache size/TTL configuration
- Instance Metrics: Per-instance usage tracking
- Rate Limiting: Per-instance rate limits
- Instance Groups: Logical grouping of instances
- Persistent Cache: Optional Redis/database backing
- Instance Discovery: Automatic instance detection
Support
For issues or questions about flexible instance configuration:
- Check validation errors for specific problems
- Enable debug logging for detailed diagnostics
- Review test files for usage examples
- Open an issue on GitHub with details