1
/**2
* Transport factory: creates the appropriate MCP transport based on the3
* plugin's resolved config. Stdio spawns a child process (with credential4
* scrubbing); Streamable HTTP connects to a URL.5
*6
* @module7
*/9
import type { Transport } from '@modelcontextprotocol/client'10
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio'11
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/client'12
import { scrubbedParentEnv } from '@deepseek-ai/dsh-subprocess'13
import type { Config } from './index.ts'15
/**16
* The subprocess seam's scrubbed parent env (credential-shaped and stale17
* `DSH_*` names dropped), plus the spec's explicit env. The MCP SDK owns the18
* actual spawn, so this transport shares the scrub definition rather than the19
* spawn path.20
*/21
function buildChildEnv(extra: Record<string, string>): Record<string, string> {22
return { ...scrubbedParentEnv(), ...extra }23
}25
/**26
* Create an MCP transport from the resolved plugin config.27
*28
* @param config - Resolved plugin config discriminated on `transport`.29
* @returns A connected-ready MCP Transport (stdio or Streamable HTTP).30
*/31
export function createTransport(config: Config): Transport {32
switch (config.transport) {33
case 'stdio':34
return new StdioClientTransport({35
command: config.command,36
args: config.args,37
env: buildChildEnv(config.env),38
cwd: config.cwd,39
})40
case 'streamable-http':41
return new StreamableHTTPClientTransport(42
new URL(config.url),43
{ requestInit: { headers: config.headers } },44
)45
}46
}