UNPKG

@modelcontextprotocol/sdk

Version:

Model Context Protocol implementation for TypeScript

152 lines 5.42 kB
import { IncomingMessage, ServerResponse } from "node:http"; import { Transport } from "../shared/transport.js"; import { JSONRPCMessage, RequestId } from "../types.js"; import { AuthInfo } from "./auth/types.js"; export type StreamId = string; export type EventId = string; /** * Interface for resumability support via event storage */ export interface EventStore { /** * Stores an event for later retrieval * @param streamId ID of the stream the event belongs to * @param message The JSON-RPC message to store * @returns The generated event ID for the stored event */ storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>; replayEventsAfter(lastEventId: EventId, { send }: { send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>; }): Promise<StreamId>; } /** * Configuration options for StreamableHTTPServerTransport */ export interface StreamableHTTPServerTransportOptions { /** * Function that generates a session ID for the transport. * The session ID SHOULD be globally unique and cryptographically secure (e.g., a securely generated UUID, a JWT, or a cryptographic hash) * * Return undefined to disable session management. */ sessionIdGenerator: (() => string) | undefined; /** * A callback for session initialization events * This is called when the server initializes a new session. * Useful in cases when you need to register multiple mcp sessions * and need to keep track of them. * @param sessionId The generated session ID */ onsessioninitialized?: (sessionId: string) => void; /** * If true, the server will return JSON responses instead of starting an SSE stream. * This can be useful for simple request/response scenarios without streaming. * Default is false (SSE streams are preferred). */ enableJsonResponse?: boolean; /** * Event store for resumability support * If provided, resumability will be enabled, allowing clients to reconnect and resume messages */ eventStore?: EventStore; } /** * Server transport for Streamable HTTP: this implements the MCP Streamable HTTP transport specification. * It supports both SSE streaming and direct HTTP responses. * * Usage example: * * ```typescript * // Stateful mode - server sets the session ID * const statefulTransport = new StreamableHTTPServerTransport({ * sessionIdGenerator: () => randomUUID(), * }); * * // Stateless mode - explicitly set session ID to undefined * const statelessTransport = new StreamableHTTPServerTransport({ * sessionIdGenerator: undefined, * }); * * // Using with pre-parsed request body * app.post('/mcp', (req, res) => { * transport.handleRequest(req, res, req.body); * }); * ``` * * In stateful mode: * - Session ID is generated and included in response headers * - Session ID is always included in initialization responses * - Requests with invalid session IDs are rejected with 404 Not Found * - Non-initialization requests without a session ID are rejected with 400 Bad Request * - State is maintained in-memory (connections, message history) * * In stateless mode: * - No Session ID is included in any responses * - No session validation is performed */ export declare class StreamableHTTPServerTransport implements Transport { private sessionIdGenerator; private _started; private _streamMapping; private _requestToStreamMapping; private _requestResponseMap; private _initialized; private _enableJsonResponse; private _standaloneSseStreamId; private _eventStore?; private _onsessioninitialized?; sessionId?: string; onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: JSONRPCMessage, extra?: { authInfo?: AuthInfo; }) => void; constructor(options: StreamableHTTPServerTransportOptions); /** * Starts the transport. This is required by the Transport interface but is a no-op * for the Streamable HTTP transport as connections are managed per-request. */ start(): Promise<void>; /** * Handles an incoming HTTP request, whether GET or POST */ handleRequest(req: IncomingMessage & { auth?: AuthInfo; }, res: ServerResponse, parsedBody?: unknown): Promise<void>; /** * Handles GET requests for SSE stream */ private handleGetRequest; /** * Replays events that would have been sent after the specified event ID * Only used when resumability is enabled */ private replayEvents; /** * Writes an event to the SSE stream with proper formatting */ private writeSSEEvent; /** * Handles unsupported requests (PUT, PATCH, etc.) */ private handleUnsupportedRequest; /** * Handles POST requests containing JSON-RPC messages */ private handlePostRequest; /** * Handles DELETE requests to terminate sessions */ private handleDeleteRequest; /** * Validates session ID for non-initialization requests * Returns true if the session is valid, false otherwise */ private validateSession; private validateProtocolVersion; close(): Promise<void>; send(message: JSONRPCMessage, options?: { relatedRequestId?: RequestId; }): Promise<void>; } //# sourceMappingURL=streamableHttp.d.ts.map