feat: configurable MAX_SESSIONS via N8N_MCP_MAX_SESSIONS env var (v2.28.3) (#468)

Make MAX_SESSIONS limit configurable for multi-tenant SaaS deployments.

- Add N8N_MCP_MAX_SESSIONS environment variable (default: 100)
- Include safety floor with Math.max(1, ...) to prevent invalid configs
- Update documentation in LIBRARY_USAGE.md, SESSION_PERSISTENCE.md
- Update CLAUDE.md and CHANGELOG.md

Fixes #468

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Romuald Członkowski
2025-12-05 09:05:22 +01:00
parent f65514381f
commit fd742d551e
8 changed files with 39 additions and 19 deletions

View File

@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [2.28.3] - 2025-12-05
### Features
**Configurable MAX_SESSIONS Limit (#468)**
The `MAX_SESSIONS` limit is now configurable via the `N8N_MCP_MAX_SESSIONS` environment variable, addressing scalability issues for multi-tenant SaaS deployments.
- **Problem**: Hardcoded limit of 100 concurrent sessions caused "Session limit reached" errors during peak usage
- **Solution**: `MAX_SESSIONS` now reads from `N8N_MCP_MAX_SESSIONS` env var (default: 100)
- **Usage**: Set `N8N_MCP_MAX_SESSIONS=1000` for higher capacity deployments
- **Safety**: Includes `Math.max(1, ...)` floor to prevent invalid configurations
- **Files**: `src/http-server-single-session.ts:44`
```bash
# Example: Allow up to 1000 concurrent sessions
N8N_MCP_MAX_SESSIONS=1000
```
## [2.28.2] - 2025-12-01
### Bug Fixes
@@ -577,7 +596,7 @@ Added export/restore functionality for MCP sessions to enable zero-downtime depl
- `restoreSessionState(sessions)` method for session recovery
- Validates session structure using existing `validateInstanceContext()`
- Handles null/invalid sessions gracefully with warnings
- Enforces MAX_SESSIONS limit (100 concurrent sessions)
- Enforces MAX_SESSIONS limit (default 100, configurable via N8N_MCP_MAX_SESSIONS env var)
- Skips expired sessions during restore
**3. SessionState Type**

View File

@@ -209,7 +209,7 @@ The MCP server exposes tools in several categories:
- **Security-first**: API keys exported as plaintext - downstream MUST encrypt
- **Dormant sessions**: Restored sessions recreate transports on first request
- **Automatic expiration**: Respects `sessionTimeout` setting (default 30 min)
- **MAX_SESSIONS limit**: Caps at 100 concurrent sessions
- **MAX_SESSIONS limit**: Caps at 100 concurrent sessions (configurable via N8N_MCP_MAX_SESSIONS env var)
**Important Implementation Notes:**
- Only exports sessions with valid n8nApiUrl and n8nApiKey in context

View File

@@ -558,7 +558,7 @@ DISABLE_CONSOLE_OUTPUT=false
# Optional: Session configuration
SESSION_TIMEOUT=1800000 # 30 minutes in milliseconds
MAX_SESSIONS=100
N8N_MCP_MAX_SESSIONS=100 # Maximum concurrent sessions (default: 100)
# Optional: Performance
NODE_ENV=production

View File

@@ -93,7 +93,7 @@ console.log(`Restored ${count} sessions`);
- Validates session metadata (timestamps, required fields)
- Skips expired sessions (age > sessionTimeout)
- Skips duplicate sessions (idempotent)
- Respects MAX_SESSIONS limit (100 per container)
- Respects MAX_SESSIONS limit (default 100, configurable via N8N_MCP_MAX_SESSIONS env var)
- Recreates transports/servers lazily on first request
- Logs security events for restore success/failure
@@ -595,19 +595,19 @@ console.log(`Export size: ${sizeKB.toFixed(2)} KB`);
### MAX_SESSIONS Limit
Hard limit: 100 sessions per container
Default limit: 100 sessions per container (configurable via `N8N_MCP_MAX_SESSIONS` env var)
```typescript
// Restore respects limit
const sessions = createSessions(150); // 150 sessions
const restored = engine.restoreSessionState(sessions);
// restored = 100 (only first 100 restored)
// restored = 100 (only first 100 restored, or N8N_MCP_MAX_SESSIONS value)
```
For >100 sessions per tenant:
- Deploy multiple containers
- Use session routing/sharding
- Implement session affinity
For higher session limits:
- Set `N8N_MCP_MAX_SESSIONS=1000` (or desired limit)
- Monitor memory usage as sessions consume resources
- Alternatively, deploy multiple containers with session routing/sharding
## Troubleshooting
@@ -676,10 +676,11 @@ Reached MAX_SESSIONS limit (100), skipping remaining sessions
**Solutions:**
1. Scale horizontally (more containers)
2. Implement session sharding
3. Reduce sessionTimeout
4. Clean up inactive sessions
1. Increase limit: Set `N8N_MCP_MAX_SESSIONS=1000` (or desired value)
2. Scale horizontally (more containers)
3. Implement session sharding
4. Reduce sessionTimeout
5. Clean up inactive sessions
```typescript
// Pre-filter by activity

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "n8n-mcp",
"version": "2.28.2",
"version": "2.28.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "n8n-mcp",
"version": "2.28.2",
"version": "2.28.3",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.20.1",

View File

@@ -1,6 +1,6 @@
{
"name": "n8n-mcp",
"version": "2.28.2",
"version": "2.28.3",
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -41,7 +41,7 @@ interface MultiTenantHeaders {
}
// Session management constants
const MAX_SESSIONS = 100;
const MAX_SESSIONS = Math.max(1, parseInt(process.env.N8N_MCP_MAX_SESSIONS || '100', 10));
const SESSION_CLEANUP_INTERVAL = 5 * 60 * 1000; // 5 minutes
interface Session {

View File

@@ -427,7 +427,7 @@ describe('SingleSessionHTTPServer - Session Persistence', () => {
});
it('should respect MAX_SESSIONS limit during restore', () => {
// Create 99 existing sessions (MAX_SESSIONS is 100)
// Create 99 existing sessions (MAX_SESSIONS defaults to 100, configurable via N8N_MCP_MAX_SESSIONS env var)
const serverAny = server as any;
const now = new Date();
for (let i = 0; i < 99; i++) {