/** * MCP Streamable HTTP transport — the spec successor to the original * HTTP+SSE transport, used by cloud-hosted MCP servers (Anthropic remote * servers, internal HTTP wrappers, etc.). * * Per the 2025-03 spec, a single URL endpoint accepts both: * - POST { jsonrpc, id, method, params } → JSON response, or * text/event-stream of one-or-more JSON-RPC frames. * - GET → text/event-stream channel * for server-initiated notifications and requests (sampling, etc.). * * This client opens the GET stream lazily on the first message the server * tells us to expect — many simple HTTP servers never send anything * unsolicited, so we don't burn a TCP connection waiting. * * Session continuity uses the `mcp-session-id` header. The server sets it * on the initialize response; we echo it on every subsequent request. */ export interface StreamableHttpOptions { /** Endpoint URL of the MCP server. */ url: string; /** Optional headers (Authorization, custom auth, etc.). */ headers?: Record; /** Called for every JSON-RPC frame the server sends, from either channel. */ onFrame: (msg: unknown) => void; /** Called when the server's notification stream errors or closes unexpectedly. */ onError?: (err: Error) => void; } export declare class StreamableHttpClient { private readonly opts; private sessionId; private notificationAbort; private stopped; /** True after the server has set a session id (i.e. it tracks state). */ constructor(opts: StreamableHttpOptions); /** * Issue a JSON-RPC frame as POST. Reply may be a single JSON response * (synchronous tools/call), or an SSE stream of one-or-more responses * + notifications. The transport invokes `onFrame` for every message * it sees on the response, regardless of shape. */ send(frame: object): Promise; /** * Open the server-push SSE channel. Idempotent — won't open twice if * already streaming. Errors are surfaced via `onError`, not thrown, so * a transient network blip doesn't crash the agent loop. */ private openNotificationStream; /** * Parse a `text/event-stream` body, invoking `onFrame` for each JSON * payload. SSE framing is intentionally permissive — we treat any line * starting with `data:` as one event's payload and join multi-line * data: blocks until a blank line. * * Bounded by `MAX_SSE_BYTES`: a misbehaving or malicious remote server * can push unbounded data on an SSE channel — without a cap, the * accumulating buffer would OOM the agent. We track cumulative bytes * read and bail with `onError` past the cap. */ private consumeSseBody; private dispatchSseEvent; /** Tear down the notification stream and refuse further sends. */ stop(): Promise; }