Skip to main content
The library supports multiple storage backends for session persistence, allowing you to choose the best option for your deployment environment.

Automatic Backend Selection

The library automatically selects the appropriate storage backend using this priority: Priority Order:
  1. Explicit: If MCP_TS_STORAGE_TYPE is set, use that backend
  2. Auto-detect Redis: If REDIS_URL is present, use Redis
  3. Auto-detect Supabase: If SUPABASE_URL is present, use Supabase
  4. Auto-detect Neon: If NEON_DATABASE_URL is present, use Neon
  5. Auto-detect File: If MCP_TS_STORAGE_FILE is present, use File
  6. Auto-detect SQLite: If MCP_TS_STORAGE_SQLITE_PATH is present, use SQLite
  7. Default: Fall back to In-Memory storage

Backend Comparison

FeatureRedisSupabaseNeonSQLiteFile SystemIn-Memory
PersistenceYesYesYesYesYesNo
DistributedYesYesYesNoNoNo
Auto-ExpiryYesYes (Manual)Yes (Manual)Yes (Manual)Yes (Manual)Yes (Manual)
PerformanceFastFastFastVery FastMediumFastest
SetupExternalCloudCloudNativeBuilt-inBuilt-in
ServerlessYesRecommendedRecommendedLimitedNoYes
ProductionRecommendedRecommendedRecommendedSingle-instanceNot recommendedNot recommended

Custom Backend Implementation

You can use specific storage backends directly:
import { 
  RedisStorageBackend,
  MemoryStorageBackend,
  FileStorageBackend,
  NeonStorageBackend
} from '@mcp-ts/sdk/server';
import { Redis } from 'ioredis';
import { neon } from '@neondatabase/serverless';

// Custom Redis instance
const redis = new Redis({
  host: 'localhost',
  port: 6379,
  password: 'secret',
});
const redisStorage = new RedisStorageBackend(redis);

// Custom file path
const fileStorage = new FileStorageBackend({ 
  path: '/var/data/sessions.json' 
});
await fileStorage.init();

// Custom Neon query function
const sql = neon(process.env.NEON_DATABASE_URL!);
const neonStorage = new NeonStorageBackend(sql);
await neonStorage.init();

// In-memory for testing
const memoryStorage = new MemoryStorageBackend();

Session Data Structure

All backends store the same session data structure:
interface Session {
  sessionId: string;
  userId: string;
  serverId?: string;
  serverName?: string;
  serverUrl: string;
  callbackUrl: string;
  transportType: 'sse' | 'streamable-http';
  status: 'pending' | 'active';
  createdAt: number;
  updatedAt?: number;
  expiresAt?: number | null;
  headers?: Record<string, string>;
}
OAuth runtime credentials are stored separately from connection metadata in durable SQL backends.