type StdioMcpServerLaunchConfig = { command: string; args?: string[]; env?: Record; cwd?: string; }; type StdioMcpServerLaunchResult = | { ok: true; config: StdioMcpServerLaunchConfig } | { ok: false; reason: string }; function isRecord(value: unknown): value is Record { return value !== null && typeof value === "object" && !Array.isArray(value); } function toStringRecord(value: unknown): Record | undefined { if (!isRecord(value)) { return undefined; } const entries = Object.entries(value) .map(([key, entry]) => { if (typeof entry === "string") { return [key, entry] as const; } if (typeof entry === "number" || typeof entry === "boolean") { return [key, String(entry)] as const; } return null; }) .filter((entry): entry is readonly [string, string] => entry !== null); return entries.length > 0 ? Object.fromEntries(entries) : undefined; } function toStringArray(value: unknown): string[] | undefined { if (!Array.isArray(value)) { return undefined; } const entries = value.filter((entry): entry is string => typeof entry === "string"); return entries.length > 0 ? entries : []; } export function resolveStdioMcpServerLaunchConfig(raw: unknown): StdioMcpServerLaunchResult { if (!isRecord(raw)) { return { ok: false, reason: "server config must be an object" }; } if (typeof raw.command !== "string" || raw.command.trim().length === 0) { if (typeof raw.url === "string" && raw.url.trim().length > 0) { return { ok: false, reason: "only stdio MCP servers are supported right now", }; } return { ok: false, reason: "its command is missing" }; } const cwd = typeof raw.cwd === "string" && raw.cwd.trim().length > 0 ? raw.cwd : typeof raw.workingDirectory === "string" && raw.workingDirectory.trim().length > 0 ? raw.workingDirectory : undefined; return { ok: true, config: { command: raw.command, args: toStringArray(raw.args), env: toStringRecord(raw.env), cwd, }, }; } export function describeStdioMcpServerLaunchConfig(config: StdioMcpServerLaunchConfig): string { const args = Array.isArray(config.args) && config.args.length > 0 ? ` ${config.args.join(" ")}` : ""; const cwd = config.cwd ? ` (cwd=${config.cwd})` : ""; return `${config.command}${args}${cwd}`; } export type { StdioMcpServerLaunchConfig, StdioMcpServerLaunchResult };