mcp-use
Version:
Opinionated MCP Framework for TypeScript (@modelcontextprotocol/sdk compatible) - Build MCP Agents, Clients and Servers with support for ChatGPT Apps, Code Mode, OAuth, Notifications, Sampling, Observability and more.
146 lines • 4.59 kB
TypeScript
/**
* Redis Stream Manager
*
* Manages active SSE connections using Redis Pub/Sub for distributed notifications.
* Enables server-to-client push notifications across multiple server instances.
*
* **Note:** Redis is an optional dependency. Install it with:
* ```bash
* npm install redis
* # or
* pnpm add redis
* ```
*
* If Redis is not installed, importing this module will throw an error at runtime
* when attempting to use RedisStreamManager. Use dynamic imports with error handling
* if you want to gracefully fall back when Redis is not available.
*/
import type { StreamManager } from "./index.js";
import type { RedisClient } from "../stores/redis.js";
/**
* Check if Redis is available as an optional dependency
* @returns true if Redis can be imported, false otherwise
*/
export declare function isRedisAvailable(): Promise<boolean>;
/**
* Configuration for Redis stream manager
*/
export interface RedisStreamManagerConfig {
/**
* Redis client for Pub/Sub subscriptions
* Should be a separate client from the main Redis client
*/
pubSubClient: RedisClient;
/**
* Redis client for checking session availability
* Can be shared with SessionStore
*/
client: RedisClient;
/**
* Channel prefix for Pub/Sub (default: "mcp:stream:")
*/
prefix?: string;
/**
* Heartbeat interval in seconds to keep sessions alive (default: 10)
* Redis keys expire after this interval * 2
*/
heartbeatInterval?: number;
}
/**
* Redis-backed stream management for distributed SSE connections
*
* Enables notifications, sampling, and resource subscriptions to work across
* multiple server instances using Redis Pub/Sub.
*
* Architecture:
* 1. Client connects to Server A → creates SSE stream
* 2. Server A subscribes to Redis channel `mcp:stream:{sessionId}`
* 3. Client makes request → Load balancer routes to Server B
* 4. Server B sends notification → publishes to Redis channel
* 5. Server A receives Redis message → pushes to SSE stream → Client gets notification
*
* @example
* ```typescript
* import { MCPServer, RedisStreamManager } from 'mcp-use/server';
* import { createClient } from 'redis';
*
* // Create two separate Redis clients (required for Pub/Sub)
* const redis = createClient({ url: process.env.REDIS_URL });
* const pubSubRedis = redis.duplicate();
*
* await redis.connect();
* await pubSubRedis.connect();
*
* const streamManager = new RedisStreamManager({
* client: redis,
* pubSubClient: pubSubRedis
* });
*
* const server = new MCPServer({
* name: 'my-server',
* version: '1.0.0',
* streamManager
* });
* ```
*/
export declare class RedisStreamManager implements StreamManager {
private pubSubClient;
private client;
private prefix;
private heartbeatInterval;
private textEncoder;
/**
* Map of local controllers (only on this server instance)
* Key: sessionId, Value: controller
*/
private localControllers;
/**
* Map of heartbeat intervals for keeping sessions alive
* Key: sessionId, Value: interval timer
*/
private heartbeats;
constructor(config: RedisStreamManagerConfig);
/**
* Get the Redis channel name for a session
*/
private getChannel;
/**
* Get the Redis key for tracking active sessions
*/
private getAvailableKey;
/**
* Get the Redis key for the active sessions SET
*/
private getActiveSessionsKey;
/**
* Register an active SSE stream and subscribe to Redis channel
*/
create(sessionId: string, controller: ReadableStreamDefaultController): Promise<void>;
/**
* Send data to sessions via Redis Pub/Sub
*
* This works across distributed servers - any server with an active
* SSE connection for the target session will receive and forward the message.
*
* Note: Uses the regular client (not pubSubClient) for publishing.
* In node-redis v5+, clients in subscriber mode cannot publish.
*/
send(sessionIds: string[] | undefined, data: string): Promise<void>;
/**
* Remove an active SSE stream
*/
delete(sessionId: string): Promise<void>;
/**
* Check if a session has an active stream (on ANY server)
*/
has(sessionId: string): Promise<boolean>;
/**
* Close all connections and cleanup
*/
close(): Promise<void>;
/**
* Get count of active local streams on this server instance
*/
get localSize(): number;
}
//# sourceMappingURL=redis.d.ts.map