{"version":3,"file":"server-config.d.ts","sourceRoot":"","sources":["../../../src/core/mcp-foundation/server-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,eAAO,MAAM,8BAA8B,QAAS,CAAC;AACrD,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAKrD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AA0CD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAkChF;AAED,uEAAuE;AACvE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAQ1E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,mBAAmB,GAAG,MAAM,CAEzE;AAED,4EAA0E;AAC1E,wBAAgB,YAAY,CAAC,UAAU,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAEtE","sourcesContent":["/**\n * MCP Client Foundation — server configuration (2.13.0).\n *\n * Parses/validates a configured stdio server into a normalized\n * `McpServerDefinition`. Secret hygiene is enforced here: environment values are\n * never echoed into diagnostics or evidence; only variable names are surfaced.\n */\n\nimport { McpClientError } from \"./mcp-error.js\";\nimport type { McpServerDefinition } from \"./mcp-types.js\";\n\nexport const DEFAULT_MCP_STARTUP_TIMEOUT_MS = 30_000;\nexport const DEFAULT_MCP_REQUEST_TIMEOUT_MS = 60_000;\n\n/** Server ids must be durable/path-safe: short, [A-Za-z0-9._-], no traversal. */\nconst SAFE_SERVER_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;\n\nexport function isSafeMcpServerId(value: string): boolean {\n\treturn SAFE_SERVER_ID.test(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction requireString(value: unknown, field: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw invalidConfig(`${field} must be a non-empty string`);\n\treturn value;\n}\n\nfunction invalidConfig(message: string): McpClientError {\n\treturn new McpClientError(\"MCP_INVALID_SERVER_CONFIG\", message);\n}\n\nfunction normalizeTimeout(value: unknown, field: string, fallback: number): number {\n\tif (value === undefined) return fallback;\n\tif (typeof value !== \"number\" || !Number.isSafeInteger(value) || value <= 0) {\n\t\tthrow invalidConfig(`${field} must be a positive integer (milliseconds)`);\n\t}\n\treturn value;\n}\n\nfunction normalizeStringArray(value: unknown, field: string): string[] | undefined {\n\tif (value === undefined) return undefined;\n\tif (!Array.isArray(value) || value.some((entry) => typeof entry !== \"string\")) {\n\t\tthrow invalidConfig(`${field} must be an array of strings`);\n\t}\n\treturn [...(value as string[])];\n}\n\nfunction normalizeEnv(value: unknown): Record<string, string> | undefined {\n\tif (value === undefined) return undefined;\n\tif (!isRecord(value)) throw invalidConfig(\"env must be an object of string values\");\n\tconst out: Record<string, string> = {};\n\tfor (const [key, entry] of Object.entries(value)) {\n\t\tif (typeof entry !== \"string\") throw invalidConfig(`env.${key} must be a string`);\n\t\tout[key] = entry;\n\t}\n\treturn out;\n}\n\n/**\n * Validate a raw JSON-decoded object into a normalized server definition.\n * Throws `McpClientError(\"MCP_INVALID_SERVER_CONFIG\")` on any structural error.\n */\nexport function normalizeMcpServerDefinition(input: unknown): McpServerDefinition {\n\tif (!isRecord(input)) throw invalidConfig(\"server config must be a JSON object\");\n\n\tconst id = requireString(input.id, \"id\");\n\tif (!isSafeMcpServerId(id)) {\n\t\tthrow invalidConfig(\"id must be durable-safe: 1-64 chars of [A-Za-z0-9._-] starting with a letter/digit\");\n\t}\n\n\tconst command = requireString(input.command, \"command\");\n\tconst name = input.name === undefined ? undefined : requireString(input.name, \"name\");\n\tconst args = normalizeStringArray(input.args, \"args\");\n\tconst env = normalizeEnv(input.env);\n\tconst cwd = input.cwd === undefined ? undefined : requireString(input.cwd, \"cwd\");\n\tconst startupTimeoutMs = normalizeTimeout(\n\t\tinput.startupTimeoutMs,\n\t\t\"startupTimeoutMs\",\n\t\tDEFAULT_MCP_STARTUP_TIMEOUT_MS,\n\t);\n\tconst requestTimeoutMs = normalizeTimeout(\n\t\tinput.requestTimeoutMs,\n\t\t\"requestTimeoutMs\",\n\t\tDEFAULT_MCP_REQUEST_TIMEOUT_MS,\n\t);\n\n\treturn Object.freeze({\n\t\tid,\n\t\tname,\n\t\tcommand,\n\t\targs: args ? Object.freeze(args) : undefined,\n\t\tenv: env ? Object.freeze(env) : undefined,\n\t\tcwd,\n\t\tstartupTimeoutMs,\n\t\trequestTimeoutMs,\n\t});\n}\n\n/** Parse a server-config JSON document into a validated definition. */\nexport function parseMcpServerConfigJson(text: string): McpServerDefinition {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(text);\n\t} catch (error) {\n\t\tthrow invalidConfig(`server config is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n\treturn normalizeMcpServerDefinition(parsed);\n}\n\n/**\n * argv identity for diagnostics: `command` plus explicit args. Environment\n * contents are deliberately excluded.\n */\nexport function safeServerCommand(definition: McpServerDefinition): string {\n\treturn [definition.command, ...(definition.args ?? [])].join(\" \");\n}\n\n/** Sorted environment variable NAMES only — values are never surfaced. */\nexport function safeEnvNames(definition: McpServerDefinition): string[] {\n\treturn Object.keys(definition.env ?? {}).sort();\n}\n"]}