TypeScript SDK for implementing the Model Context Protocol, enabling developers to build MCP servers and clients with support for multiple transports, tools, resources, prompts, and authentication
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The SDK supports multiple transport mechanisms. All transports implement the same Transport interface.
For local integrations where server is spawned as a child process.
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
class StdioServerTransport implements Transport {
constructor(stdin?: Readable, stdout?: Writable);
}import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
class StdioClientTransport implements Transport {
constructor(options: {
command: string;
args?: string[];
env?: Record<string, string>;
stderr?: 'inherit' | 'ignore' | 'pipe' | Stream | number;
cwd?: string;
});
}// Server
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
const transport = new StdioServerTransport();
await server.connect(transport);
// Client
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const client = new Client({ name: 'my-client', version: '1.0.0' });
const transport = new StdioClientTransport({
command: 'node',
args: ['server.js'],
env: { ...process.env, DEBUG: 'true' },
cwd: '/path/to/server'
});
await client.connect(transport);Modern HTTP-based transport for remote servers with session management, reconnection support, and event replay.
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
class StreamableHTTPServerTransport implements Transport {
constructor(options: {
sessionIdGenerator?: () => string; // undefined for stateless mode
onsessioninitialized?: (sessionId: string) => void | Promise<void>;
onsessionclosed?: (sessionId: string) => void | Promise<void>;
enableJsonResponse?: boolean; // JSON responses instead of newline-delimited JSON
eventStore?: EventStore; // Event store for session resumption
allowedHosts?: string[]; // DNS rebinding protection
allowedOrigins?: string[]; // DNS rebinding protection
enableDnsRebindingProtection?: boolean; // Default: false
});
async handleRequest(req: IncomingMessage, res: ServerResponse, body?: JSONRPCMessage): Promise<void>;
}
interface EventStore {
storeEvent(sessionId: string, event: { sequence: number; data: JSONRPCMessage }): Promise<void>;
replayEventsAfter(sessionId: string, afterSequence: number): Promise<Array<{ sequence: number; data: JSONRPCMessage }>>;
}import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
class StreamableHTTPClientTransport implements Transport {
constructor(
url: URL,
options?: {
reconnectionOptions?: {
maxReconnectionDelay: number;
initialReconnectionDelay: number;
reconnectionDelayGrowFactor: number;
maxRetries: number;
};
authProvider?: OAuthClientProvider;
fetch?: FetchLike;
}
);
async finishAuth(authorizationCode: string): Promise<void>;
}// Server - Stateless mode (recommended)
import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
const app = express();
app.use(express.json());
const server = new McpServer({ name: 'http-server', version: '1.0.0' });
app.post('/mcp', async (req, res) => {
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // Stateless
enableJsonResponse: true
});
res.on('close', () => transport.close());
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
app.listen(3000);
// Server - Stateful mode with session management
const transports = {};
app.post('/mcp', async (req, res) => {
const sessionId = req.headers['mcp-session-id'];
let transport;
if (sessionId && transports[sessionId]) {
transport = transports[sessionId];
} else {
transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => crypto.randomUUID(),
onsessioninitialized: (id) => { transports[id] = transport; },
onsessionclosed: (id) => { delete transports[id]; },
enableDnsRebindingProtection: true,
allowedHosts: ['127.0.0.1', 'localhost']
});
await server.connect(transport);
}
await transport.handleRequest(req, res, req.body);
});
// Client
const client = new Client({ name: 'http-client', version: '1.0.0' });
const transport = new StreamableHTTPClientTransport(
new URL('http://localhost:3000/mcp'),
{
reconnectionOptions: {
maxReconnectionDelay: 30000,
initialReconnectionDelay: 1000,
reconnectionDelayGrowFactor: 2,
maxRetries: 10
}
}
);
await client.connect(transport);WebSocket-based communication (client-side only).
import { WebSocketClientTransport } from '@modelcontextprotocol/sdk/client/websocket.js';
class WebSocketClientTransport implements Transport {
constructor(url: URL);
}const client = new Client({ name: 'ws-client', version: '1.0.0' });
const transport = new WebSocketClientTransport(new URL('ws://localhost:3000/mcp'));
await client.connect(transport);For testing and development.
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
class InMemoryTransport implements Transport {
static createLinkedPair(): [InMemoryTransport, InMemoryTransport];
}import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
const client = new Client({ name: 'test-client', version: '1.0.0' });
const server = new Server({ name: 'test-server', version: '1.0.0' });
await Promise.all([
client.connect(clientTransport),
server.connect(serverTransport)
]);interface Transport {
sessionId?: string;
onclose?: () => void;
onerror?: (error: Error) => void;
onmessage?: (message: JSONRPCMessage) => void;
start(): Promise<void>;
send(message: JSONRPCMessage): Promise<void>;
close(): Promise<void>;
setProtocolVersion?: (version: string) => void; // HTTP transports only
}| Transport | Use Case | Characteristics |
|---|---|---|
| Stdio | Local integrations, CLI tools, IDE extensions | Simple, fast |
| StreamableHTTP | Remote servers, web services, distributed systems | Stateless, scalable |
| WebSocket | Real-time bidirectional communication | Low latency |
| InMemory | Unit tests, integration tests | Isolated |
Note: SSE transport is deprecated - use StreamableHTTP for new implementations.