Package Exports
- mcp-server-sdk
- mcp-server-sdk/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (mcp-server-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
mcp-server-sdk
Enhanced Model Context Protocol (MCP) server SDK with session management, message routing, and distributed capabilities.
Features
- ð Single Instance, Multiple Sessions - One server handles concurrent connections
- ð Per-Request Transport - Initialize transport for each request
- ð Session Management - Unique distributed session tracking with automatic timeouts
- ðĻ Message Routing - Route and store messages for resumability and replay
- ðū Message Storage - Built-in and custom storage implementations
- ð Event System - Listen to session and message events
- ðŊ TypeScript Support - Full type definitions
- ð MCP Compatible - Extends official
@modelcontextprotocol/sdk - ðŠķ Minimal Dependencies
Installation
npm install mcp-server-sdk @modelcontextprotocol/sdkArchitecture
The SDK supports a distributed architecture where:
- Single Server Instance - Runs continuously and handles multiple sessions
- Per-Request Transports - Each HTTP request can initialize its own transport
- Session-Based Routing - Messages are routed by unique session IDs
- Message Storage - All messages can be stored for resumability
- Event-Driven - React to session lifecycle and message events
Quick Start
Basic Usage
import { createMCPServer } from "mcp-server-sdk";
// Create server instance (singleton pattern recommended)
const server = createMCPServer({
name: "my-mcp-server",
version: "1.0.0",
title: "My MCP Server",
websiteUrl: "https://example.com"
});
// Register tools
server.tool("hello", "Say hello", async () => {
return {
content: [{ type: "text", text: "Hello from MCP!" }]
};
});
// Register resources
server.resource("config", "file:///config.json", async (uri) => {
return {
contents: [{
uri: uri.href,
text: JSON.stringify({ setting: "value" }),
mimeType: "application/json"
}]
};
});
console.log(`Server instance ID: ${server.getInstanceId()}`);HTTP/SSE Server Integration
import express from "express";
import { createMCPServer } from "mcp-server-sdk";
import { DistributedStreamableHttpServerTransport } from "@human4.ai/distributed-streamable-http-server-transport";
const app = express();
const server = createMCPServer({
name: "distributed-mcp-server",
version: "1.0.0"
});
// Register your tools, resources, and prompts
server.tool("process-data", "Process data", async (args) => {
return {
content: [{ type: "text", text: `Processed: ${JSON.stringify(args)}` }]
};
});
// Handle incoming requests
app.use("/mcp", async (req, res) => {
try {
// Create per-request transport
const transport = new DistributedStreamableHttpServerTransport();
// Create or resume session
const sessionId = req.headers["x-session-id"] as string;
const session = await server.connectWithSession(transport, sessionId);
// Set session header for client
res.setHeader("X-Session-ID", session.sessionId);
// Handle the request
await transport.handleRequest(req, res);
// Update session activity
server.updateSessionActivity(session.sessionId);
} catch (error) {
console.error("MCP request error:", error);
res.status(500).json({
jsonrpc: "2.0",
error: { code: -32603, message: "Internal server error" },
id: null
});
}
});
app.listen(3000, () => {
console.log("MCP server listening on port 3000");
});Session Management
const server = createMCPServer(
{ name: "my-server", version: "1.0.0" },
{
sessionTimeout: 30 * 60 * 1000, // 30 minutes
enableMessageRouting: true
}
);
// Listen to session events
server.on("session:created", (session) => {
console.log(`Session created: ${session.sessionId}`);
});
server.on("session:closed", (session) => {
console.log(`Session closed: ${session.sessionId}`);
});
// Get active sessions
const sessions = server.getActiveSessions();
console.log(`Active sessions: ${sessions.length}`);
// Manually close a session
await server.closeSession("session-id");Message Storage and Replay
import { createMCPServer, InMemoryMessageStorage } from "mcp-server-sdk";
const server = createMCPServer(
{ name: "my-server", version: "1.0.0" },
{
messageStorage: new InMemoryMessageStorage(),
enableMessageRouting: true
}
);
// Listen to message events
server.on("message:stored", (message) => {
console.log(`Message stored: ${message.id}`);
});
// Retrieve session messages for replay
const messages = await server.getMessages("session-id", {
limit: 100,
offset: 0
});
console.log(`Retrieved ${messages.length} messages`);Custom Message Storage
Implement your own storage backend:
import { MessageStorage, Message } from "mcp-server-sdk";
import { createClient } from "redis";
class RedisMessageStorage implements MessageStorage {
private client = createClient();
async store(message: Message): Promise<void> {
await this.client.connect();
const key = `messages:${message.sessionId}`;
await this.client.rPush(key, JSON.stringify(message));
await this.client.expire(key, 86400); // 24 hour TTL
}
async retrieve(
sessionId: string,
options?: { limit?: number; offset?: number }
): Promise<Message[]> {
await this.client.connect();
const key = `messages:${sessionId}`;
const start = options?.offset || 0;
const end = start + (options?.limit || 100) - 1;
const data = await this.client.lRange(key, start, end);
return data.map((item) => JSON.parse(item));
}
async delete(sessionId: string): Promise<void> {
await this.client.connect();
await this.client.del(`messages:${sessionId}`);
}
}
const server = createMCPServer(
{ name: "my-server", version: "1.0.0" },
{ messageStorage: new RedisMessageStorage() }
);API Reference
createMCPServer(serverInfo, options)
Creates a new MCP server instance with enhanced capabilities.
Parameters:
serverInfo: Implementation- Server metadataname: string- Server name (required)version: string- Server version (required)title?: string- Display titlewebsiteUrl?: string- Website URLicons?: Array- Server icons
options?: McpServerOptions- Configuration optionsinstanceId?: string- Unique server instance ID (auto-generated if omitted)distributed?: boolean- Enable distributed features (default: true)messageStorage?: MessageStorage- Message storage implementationenableMessageRouting?: boolean- Enable message routing (default: true)sessionTimeout?: number- Session timeout in ms (default: 1800000 / 30 min)
Returns: MCPServer
MCPServer
Main server class extending McpServer from @modelcontextprotocol/sdk.
Session Methods:
createSession(metadata?: Record<string, unknown>): SessionInfo- Create a new sessiongetSession(sessionId: string): SessionInfo | undefined- Get session by IDupdateSessionActivity(sessionId: string): void- Update session activity timestampcloseSession(sessionId: string): Promise<void>- Close a specific sessiongetActiveSessions(): SessionInfo[]- Get all active sessions
Message Methods:
storeMessage(message: Omit<Message, "id" | "timestamp">): Promise<Message>- Store a messagegetMessages(sessionId: string, options?: { limit?: number; offset?: number }): Promise<Message[]>- Retrieve messages
Connection Methods:
connect(transport: Transport): Promise<void>- Connect to transport (standard MCP)connectWithSession(transport: Transport, sessionId?: string): Promise<SessionInfo>- Connect with session supportclose(): Promise<void>- Close all connections and sessions
Instance Methods:
getInstanceId(): string- Get the unique instance identifierisDistributed(): boolean- Check if distributed mode is enabled
Event Methods:
on(event: string, listener: (...args: unknown[]) => void): this- Listen to eventsoff(event: string, listener: (...args: unknown[]) => void): this- Remove event listener
Inherited Methods:
All methods from McpServer:
tool()- Register toolsresource()- Register resourcesprompt()- Register promptssendLoggingMessage()- Send log messages- And more...
Events
Session Events:
session:created- Emitted when a session is createdsession:closed- Emitted when a session is closed
Message Events:
message:stored- Emitted when a message is stored
Types
interface SessionInfo {
sessionId: string;
instanceId: string;
createdAt: Date;
lastActivity: Date;
metadata?: Record<string, unknown>;
}
interface Message {
id: string;
sessionId: string;
timestamp: Date;
direction: "request" | "response" | "notification";
payload: unknown;
metadata?: Record<string, unknown>;
}
interface MessageStorage {
store(message: Message): Promise<void>;
retrieve(sessionId: string, options?: { limit?: number; offset?: number }): Promise<Message[]>;
delete(sessionId: string): Promise<void>;
}Built-in Storage
InMemoryMessageStorage
In-memory implementation of MessageStorage interface. Suitable for development and testing.
import { InMemoryMessageStorage } from "mcp-server-sdk";
const storage = new InMemoryMessageStorage();Use Cases
1. HTTP/SSE MCP Server
Single server instance handling multiple HTTP requests with SSE for streaming responses.
2. WebSocket MCP Server
Maintain sessions across WebSocket connections with message replay on reconnection.
3. Distributed MCP Cluster
Multiple server instances with shared session storage (e.g., Redis) for load balancing.
4. Development and Testing
In-memory storage for rapid development without external dependencies.
TypeScript Support
Full TypeScript support with exported types:
import type {
Implementation,
Transport,
ToolCallback,
RegisteredTool,
ResourceTemplate,
CallToolResult,
SessionInfo,
Message,
MessageStorage,
McpServerOptions,
} from "mcp-server-sdk";Backward Compatibility
Legacy exports are maintained for backward compatibility:
import { DistributedMcpServer, createDistributedMcpServer } from "mcp-server-sdk";
// Aliases for MCPServer and createMCPServerRequirements
- Node.js >= 18.0.0
@modelcontextprotocol/sdk>= 1.0.0
License
MIT
Contributing
Contributions are welcome! This SDK is designed to be extended for specific distributed use cases.