Skip to main content
Redis is the recommended storage backend for production and serverless deployments. It keeps sessions in a distributed key-value store with automatic TTL expiry, which means you get horizontal scaling, multi-instance support, and no manual cleanup of stale sessions. The SDK uses ioredis under the hood and stores each session as a JSON-serialised hash with a configurable TTL.

Install the peer dependency

npm install ioredis

Configure environment variables

# Force Redis selection (optional — auto-detected if REDIS_URL is present)
MCP_TS_STORAGE_TYPE=redis

# Redis connection URL
REDIS_URL=redis://localhost:6379
If REDIS_URL is present in your environment, the SDK automatically selects Redis without needing MCP_TS_STORAGE_TYPE. Setting the type explicitly is useful when you want to document intent clearly or override a different auto-detected backend.

Connection URL formats

REDIS_URL=redis://localhost:6379

How auto-detection works

When MCP_TS_STORAGE_TYPE is not set, the SDK scans for known environment variables in priority order. REDIS_URL is checked first — before MCP_TS_STORAGE_FILE, MCP_TS_STORAGE_SQLITE_PATH, and SUPABASE_URL. If REDIS_URL is present and the connection succeeds, Redis is used without any further configuration.

Fallback behavior

If the Redis connection fails at startup — whether due to a bad URL, a timeout, or an unreachable host — the SDK logs an error and falls back to in-memory storage:
[mcp-ts][Storage] Failed to initialize Redis: connect ECONNREFUSED 127.0.0.1:6379
[mcp-ts][Storage] Falling back to In-Memory storage
In-memory fallback means sessions will not survive a server restart. If you see this message in production, investigate the Redis connection immediately. Sessions created during the fallback period will be lost when the process exits.

Key schema

The SDK stores sessions under two types of Redis keys:
Key patternTypePurpose
mcp:session:<identity>:<sessionId>String (JSON)Full session data
mcp:identity:<identity>:sessionsSetIndex of session IDs per identity
Both keys are set with the session TTL. Stale entries in the identity set are pruned lazily when you call getIdentitySessionsData.

Example: use the auto-detected storage export

import { storage } from '@mcp-ts/sdk/server';

// With REDIS_URL in your environment, `storage` uses Redis automatically
const sessionId = await storage.generateSessionId();

await storage.createSession({
  sessionId,
  identity: 'user-123',
  serverUrl: 'https://mcp.example.com',
  callbackUrl: 'https://app.example.com/callback',
  transportType: 'sse',
  createdAt: Date.now(),
});

const session = await storage.getSession('user-123', sessionId);

Example: instantiate directly with a custom client

Use this pattern when you need fine-grained control over the ioredis configuration — for example, to set a custom connectTimeout, use a Redis Cluster, or inject a client in tests.
import { RedisStorageBackend } from '@mcp-ts/sdk/server';
import { Redis } from 'ioredis';

const redis = new Redis({
  host: 'your-redis-host.upstash.io',
  port: 6379,
  password: 'your-token',
  tls: {},
});

const storage = new RedisStorageBackend(redis);
await storage.init(); // pings Redis; throws if unreachable

Deploying to Upstash

Upstash is a serverless Redis provider that works well with Vercel, Cloudflare Workers, and other edge environments. Create a database in the Upstash console, then copy the REST URL from the Details tab.
1

Create an Upstash Redis database

Go to console.upstash.com, create a new database, and select your preferred region.
2

Copy the connection URL

In the database details, find the Redis URL (starts with rediss://). Copy it.
3

Set the environment variable

Add REDIS_URL to your deployment environment:
REDIS_URL=rediss://default:your-token@your-endpoint.upstash.io:6379
On Vercel, add this in Project Settings → Environment Variables.
4

Deploy

Redeploy your application. The SDK will auto-detect REDIS_URL and connect on first request.

Troubleshooting

connect ECONNREFUSED — Redis is not running locally. Start it with redis-server or check your Docker setup. WRONGPASS invalid username-password pair — The password in REDIS_URL is incorrect. ERR unknown command 'SCAN' — You are using a Redis-compatible store that does not support SCAN. The SDK falls back to KEYS automatically in this case, which is safe but slower on large keysets.
# Verify your local Redis is reachable
redis-cli -u "$REDIS_URL" ping
# Expected output: PONG