Session Management
Session management controls how the gateway routes requests to server instances. While Scoping provides a simple high-level interface (global, workspace, credential), session management offers fine-grained control over instance routing and lifecycle.
Session Modes
The gateway supports three session modes:
| Mode | Instances | Routing | Best For |
|---|---|---|---|
| Shared | 1 | All requests → same instance | Stateless servers, public APIs |
| Pooled | N | Requests → instance by key hash | Most servers (default) |
| Dedicated | 1 per client | Each client → own instance | Stateful servers |
Shared Mode
A single server instance handles all requests. Most memory-efficient, but no isolation.
servers:
docs:
url: "https://mcp.context7.com/mcp"
session_mode:
type: shared
Use when:
- Server has no authentication
- Server is stateless (documentation, utilities)
- You want minimal resource usage
Client A ──┐
Client B ──┼──▶ Single Instance
Client C ──┘
Pooled Mode
Multiple server instances, with requests routed based on a pool key. Clients with the same key share an instance.
servers:
github:
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
session_mode:
type: pooled
pool_size: 10
pool_key:
strategy: env_vars
keys: ["GITHUB_TOKEN"]
Configuration:
pool_size— Maximum instances (default: 5)pool_key— Strategy for computing instance key
Pool Key Strategies
The pool key determines which instance handles a request:
| Strategy | Key Based On | Example |
|---|---|---|
project | Resolved project/workspace name | Same project → same instance |
cwd | Working directory path | Same directory → same instance |
env_vars | Hash of specified env var values | Same GITHUB_TOKEN → same instance |
project_config | Hash of project config fields | Same github_org → same instance |
composite | Combination of strategies | Project + region → same instance |
Project Strategy (Default)
Routes by resolved project name:
pool_key:
strategy: project
/app/frontend (project: my-app) ──┐
/app/backend (project: my-app) ──┼──▶ Instance 1
│
/other/project (project: other) ──┴──▶ Instance 2
Environment Variables Strategy
Routes by hash of specified environment variable values:
pool_key:
strategy: env_vars
keys: ["GITHUB_TOKEN", "GITHUB_USER"]
This is the most secure option for credential isolation. Different tokens = different instances = no credential leakage.
Token A (alice) ──▶ Instance 1
Token A (alice) ──▶ Instance 1 (reused)
Token B (bob) ──▶ Instance 2
Composite Strategy
Combines multiple strategies for multi-dimensional routing:
pool_key:
strategy: composite
strategies:
- strategy: project
- strategy: env_vars
keys: ["API_REGION"]
project=app + region=us-east ──▶ Instance 1
project=app + region=eu-west ──▶ Instance 2
project=other + region=us-east ──▶ Instance 3
Dedicated Mode
Each client session gets its own server instance. Maximum isolation but highest resource usage.
servers:
memory:
command: npx
args: ["-y", "@modelcontextprotocol/server-memory"]
session_mode:
type: dedicated
idle_timeout_ms: 300000 # 5 minutes
Configuration:
idle_timeout_ms— Auto-cleanup after inactivity (default: 300000 / 5 min)
Use when:
- Server maintains per-session state (memory, chat history)
- Maximum isolation is required
- You need clean instances per client
Client A ──▶ Instance A (state: A's data)
Client B ──▶ Instance B (state: B's data)
Client C ──▶ Instance C (state: C's data)
↓ (idle > 5 min)
Stopped
Scope vs Session Mode
The scope field in server config is a shorthand that maps to session modes:
| Scope | Session Mode | Pool Key Strategy |
|---|---|---|
global | Shared | — |
workspace | Pooled | project |
credential | Pooled | env_vars (auto-detected) |
For simple cases, use scope. For fine-grained control, use session_mode.
# Simple (use scope)
servers:
github:
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
scope: credential
# Advanced (use session_mode)
servers:
github:
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
session_mode:
type: pooled
pool_size: 10
pool_key:
strategy: env_vars
keys: ["GITHUB_TOKEN"]
Choosing a Mode
Is server stateful (stores per-session data)?
├── YES → Dedicated
└── NO
│
Does server require credentials?
├── NO → Shared
└── YES
│
Need credential isolation?
├── YES → Pooled (env_vars strategy)
└── NO → Pooled (project strategy)
Defaults
| Setting | Default |
|---|---|
| Session mode | shared |
| Pool size | 5 |
| Pool key strategy | project |
| Idle timeout (dedicated) | 300000ms (5 min) |
Examples
Multi-Account GitHub
Different GitHub tokens get isolated instances:
servers:
github:
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "${GITHUB_TOKEN}"
session_mode:
type: pooled
pool_key:
strategy: env_vars
keys: ["GITHUB_TOKEN"]
Regional API Isolation
Separate instances per region:
servers:
api:
url: "https://api.example.com/mcp"
session_mode:
type: pooled
pool_key:
strategy: composite
strategies:
- strategy: project
- strategy: env_vars
keys: ["API_REGION"]
Stateful Memory Server
Per-client isolated state with auto-cleanup:
servers:
memory:
command: npx
args: ["-y", "@modelcontextprotocol/server-memory"]
session_mode:
type: dedicated
idle_timeout_ms: 600000 # 10 min