Skip to content

Conversation

@stefanskiasan
Copy link

Summary

This PR adds native support for distributed session storage in the MCP SDK, enabling multi-pod/multi-node deployments where session state must be shared across server instances.

The Problem

The official @modelcontextprotocol/sdk stores session state in-memory:

// Original SDK - sessions are local to each process private _initialized: boolean = false; sessionId?: string;

This means:

  • Sessions cannot be shared across multiple pods/containers
  • Load balancers routing requests to different instances will fail
  • Sessions are lost on server restart

The Solution

This PR introduces:

  1. SessionStore interface - Abstract interface for external session storage
  2. SessionData interface - Session metadata structure
  3. SessionStorageMode type - Explicit mode selection ('memory' | 'external')
  4. RedisSessionStore - Production-ready Redis implementation
  5. InMemorySessionStore - For development/testing

Usage

// Single-pod mode (default) - sessions in memory const singlePodTransport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), sessionStorageMode: 'memory' // This is the default }); // Multi-pod mode - sessions in Redis const multiPodTransport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), sessionStorageMode: 'external', // Explicit mode selection sessionStore: new RedisSessionStore({ redis: new Redis(), ttlSeconds: 3600 }) });

Key Features

  • Backward compatible - Default behavior unchanged when no sessionStore provided
  • Explicit mode configuration - Clear distinction between memory and external modes
  • Cross-pod session recovery - Sessions automatically recovered from external store
  • Automatic TTL refresh - Session activity updates refresh TTL
  • Type-safe - Full TypeScript support with exported interfaces
  • Comprehensive tests - Unit and integration tests for all new functionality

Files Changed

  • src/server/streamableHttp.ts - Core SessionStore integration
  • src/server/index.ts - Export new types and classes
  • src/server/session-stores/redis.ts - Redis and InMemory implementations
  • src/server/session-stores/index.ts - Re-exports
  • src/server/streamableHttp.test.ts - Integration tests
  • src/server/session-stores/redis.test.ts - Unit tests

Test plan

  • All 1458 existing SDK tests pass
  • New unit tests for RedisSessionStore (19 tests)
  • New unit tests for InMemorySessionStore (included in above)
  • New integration tests for SessionStore with StreamableHTTPServerTransport
  • Cross-pod session recovery simulation test
  • Build succeeds for both ESM and CJS

🤖 Generated with Claude Code

stefanskiasan and others added 2 commits November 30, 2025 14:48
This adds native support for external session storage in StreamableHTTPServerTransport, enabling multi-pod/multi-node deployments where session state must be shared. Changes: - Add SessionStore interface with store/get/update/delete/exists methods - Add SessionData interface for session metadata - Add SessionStorageMode type ('memory' | 'external') - Add sessionStorageMode option to transport options (default: 'memory') - Add sessionStore option for external session storage implementation - Add RedisSessionStore implementation example - Add InMemorySessionStore for development/testing - Add runtime getters: sessionStorageMode, isUsingExternalSessionStore - Validation: throws error if mode='external' without sessionStore Usage: ```typescript // Memory mode (default) new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), sessionStorageMode: 'memory' }); // External mode (Redis) new StreamableHTTPServerTransport({ sessionIdGenerator: () => randomUUID(), sessionStorageMode: 'external', sessionStore: new RedisSessionStore({ redis, ttlSeconds: 3600 }) }); ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add unit tests for RedisSessionStore and InMemorySessionStore - Store/retrieve session data - TTL handling and expiry - Activity updates - Custom key prefix - Logging callbacks - Add integration tests for StreamableHTTPServerTransport with SessionStore - SessionStorageMode configuration (memory/external) - External session storage integration - Session lifecycle (store, validate, update, delete) - Cross-pod session recovery simulation - Error handling for invalid sessions - InMemorySessionStore integration for development All 1458 SDK tests pass with no regressions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
@stefanskiasan stefanskiasan requested a review from a team as a code owner November 30, 2025 13:56
Include pre-built distribution files (ESM and CJS) in the repository to enable direct npm installation from GitHub without requiring a build step. This allows consuming projects to install via: npm install github:stefanskiasan/typescript-sdk#feature/session-store-interface 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 30, 2025

Open in StackBlitz

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@anthropic-advisori/mcp-sdk@1193 

commit: c258d9f

- Call onsessioninitialized handler BEFORE storing session data - Merge existing session data (including metadata) when updating - Prevents overwrites of custom metadata (e.g., serverId) set by handlers This fix ensures that applications using external session storage can store additional metadata (like serverId for cross-pod recovery) via the onsessioninitialized callback without it being overwritten by the SDK's internal storeSession call. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant