import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"; import { getDefaultEnvironment, StdioClientTransport, } from "@modelcontextprotocol/sdk/client/stdio.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js"; import { findActualExecutable } from "spawn-rx"; export type TransportOptions = { transportType: "sse" | "stdio" | "http"; command?: string; args?: string[]; url?: string; headers?: Record; }; function createStdioTransport(options: TransportOptions): Transport { let args: string[] = []; if (options.args !== undefined) { args = options.args; } const processEnv: Record = {}; for (const [key, value] of Object.entries(process.env)) { if (value !== undefined) { processEnv[key] = value; } } const defaultEnv = getDefaultEnvironment(); const env: Record = { ...defaultEnv, ...processEnv, }; const { cmd: actualCommand, args: actualArgs } = findActualExecutable( options.command ?? "", args, ); return new StdioClientTransport({ command: actualCommand, args: actualArgs, env, stderr: "pipe", }); } export function createTransport(options: TransportOptions): Transport { const { transportType } = options; try { if (transportType === "stdio") { return createStdioTransport(options); } // If not STDIO, then it must be either SSE or HTTP. if (!options.url) { throw new Error("URL must be provided for SSE or HTTP transport types."); } const url = new URL(options.url); if (transportType === "sse") { const transportOptions = options.headers ? { requestInit: { headers: options.headers, }, } : undefined; return new SSEClientTransport(url, transportOptions); } if (transportType === "http") { const transportOptions = options.headers ? { requestInit: { headers: options.headers, }, } : undefined; return new StreamableHTTPClientTransport(url, transportOptions); } throw new Error(`Unsupported transport type: ${transportType}`); } catch (error) { throw new Error( `Failed to create transport: ${error instanceof Error ? error.message : String(error)}`, ); } }