{"version":3,"file":"mcp-error.d.ts","sourceRoot":"","sources":["../../../src/core/mcp-foundation/mcp-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,YAAY,GACrB,sBAAsB,GACtB,2BAA2B,GAC3B,kBAAkB,GAClB,2BAA2B,GAC3B,yBAAyB,GACzB,qBAAqB,GACrB,qBAAqB,GACrB,uBAAuB,GACvB,oBAAoB,GACpB,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,qBAAqB,GACrB,uBAAuB,GACvB,qBAAqB,GACrB,uBAAuB,CAAC;AAE3B,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAEzB,YAAY,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,EAS7E;IAED,oEAAoE;IACpE,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUhC;CACD;AAUD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CA6ClG;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAwBpE","sourcesContent":["/**\n * MCP Client Foundation — structured error model (2.13.0).\n *\n * Every failure crossing the Jensen boundary is a machine-readable\n * `McpClientError` with a stable `code`, a useful human description, and\n * retained server/tool identity. Transport/process failures retain diagnostics;\n * secrets never leak through error serialization.\n *\n * SDK mapping (v2): wire/protocol errors are `ProtocolError` (numeric JSON-RPC\n * codes); local SDK failures are `SdkError` (string `SdkErrorCode`); process\n * spawn failures are Node `ErrnoException`s. All are normalized to the stable\n * Jensen vocabulary below — callers never see SDK error classes.\n */\n\nimport { ProtocolError, ProtocolErrorCode, SdkError, SdkErrorCode } from \"@modelcontextprotocol/client\";\n\nexport type McpErrorCode =\n\t| \"MCP_SERVER_NOT_FOUND\"\n\t| \"MCP_INVALID_SERVER_CONFIG\"\n\t| \"MCP_SPAWN_FAILED\"\n\t| \"MCP_INITIALIZATION_FAILED\"\n\t| \"MCP_INCOMPATIBLE_SERVER\"\n\t| \"MCP_CONNECTION_LOST\"\n\t| \"MCP_REQUEST_TIMEOUT\"\n\t| \"MCP_REQUEST_CANCELLED\"\n\t| \"MCP_TOOL_NOT_FOUND\"\n\t| \"MCP_TOOL_CALL_FAILED\"\n\t| \"MCP_PROTOCOL_ERROR\"\n\t| \"MCP_INVALID_RESULT\"\n\t| \"MCP_SHUTDOWN_FAILED\"\n\t| \"MCP_SESSION_NOT_FOUND\"\n\t| \"MCP_SESSION_INVALID\"\n\t| \"MCP_INVALID_TOOL_CALL\";\n\nexport interface McpErrorContext {\n\tserverId?: string;\n\tsessionId?: string;\n\ttoolName?: string;\n\t/** Safe diagnostic detail (e.g., argv identity or stderr tail). Never env secrets. */\n\tdetail?: string;\n\tcause?: unknown;\n}\n\n/**\n * Jensen MCP error. The `message` is human-facing; `code`, `serverId`,\n * `sessionId`, and `toolName` are machine-readable.\n */\nexport class McpClientError extends Error {\n\treadonly code: McpErrorCode;\n\treadonly serverId?: string;\n\treadonly sessionId?: string;\n\treadonly toolName?: string;\n\treadonly detail?: string;\n\treadonly cause?: unknown;\n\n\tconstructor(code: McpErrorCode, message: string, context: McpErrorContext = {}) {\n\t\tsuper(message);\n\t\tthis.name = \"McpClientError\";\n\t\tthis.code = code;\n\t\tthis.serverId = context.serverId;\n\t\tthis.sessionId = context.sessionId;\n\t\tthis.toolName = context.toolName;\n\t\tthis.detail = context.detail;\n\t\tif (context.cause !== undefined) this.cause = context.cause;\n\t}\n\n\t/** Secret-safe serialization surface for CLI/evidence consumers. */\n\ttoJSON(): Record<string, unknown> {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tcode: this.code,\n\t\t\tmessage: this.message,\n\t\t\tserverId: this.serverId,\n\t\t\tsessionId: this.sessionId,\n\t\t\ttoolName: this.toolName,\n\t\t\tdetail: this.detail,\n\t\t};\n\t}\n}\n\nfunction isAbortError(error: unknown): error is Error & { name: \"AbortError\" } {\n\treturn typeof error === \"object\" && error !== null && (error as { name?: unknown }).name === \"AbortError\";\n}\n\nfunction isNodeErrno(error: unknown): error is NodeJS.ErrnoException {\n\treturn typeof error === \"object\" && error !== null && \"code\" in error && !(error instanceof Error);\n}\n\n/**\n * Map an arbitrary SDK/transport/protocol error to a stable Jensen code.\n * Transport failure, protocol failure, server failure, and tool failure are\n * kept distinct so callers and the evidence system never conflate them.\n */\nexport function classifyMcpError(error: unknown, options: { toolName?: string } = {}): McpErrorCode {\n\tif (isAbortError(error)) return \"MCP_REQUEST_CANCELLED\";\n\n\tif (error instanceof SdkError) {\n\t\tswitch (error.code) {\n\t\t\tcase SdkErrorCode.RequestTimeout:\n\t\t\t\treturn \"MCP_REQUEST_TIMEOUT\";\n\t\t\tcase SdkErrorCode.ConnectionClosed:\n\t\t\t\treturn \"MCP_CONNECTION_LOST\";\n\t\t\tcase SdkErrorCode.InvalidResult:\n\t\t\t\treturn \"MCP_INVALID_RESULT\";\n\t\t\tcase SdkErrorCode.EraNegotiationFailed:\n\t\t\t\treturn \"MCP_INCOMPATIBLE_SERVER\";\n\t\t\tcase SdkErrorCode.MethodNotSupportedByProtocolVersion:\n\t\t\t\treturn \"MCP_PROTOCOL_ERROR\";\n\t\t\tdefault:\n\t\t\t\treturn \"MCP_PROTOCOL_ERROR\";\n\t\t}\n\t}\n\n\tif (error instanceof ProtocolError) {\n\t\tswitch (error.code) {\n\t\t\tcase ProtocolErrorCode.InvalidParams: {\n\t\t\t\tconst message = error.message ?? \"\";\n\t\t\t\t// A peer that names an unknown tool (either era) surfaces as InvalidParams.\n\t\t\t\tif (/not found/i.test(message) || (options.toolName && message.includes(options.toolName))) {\n\t\t\t\t\treturn \"MCP_TOOL_NOT_FOUND\";\n\t\t\t\t}\n\t\t\t\treturn \"MCP_TOOL_CALL_FAILED\";\n\t\t\t}\n\t\t\tcase ProtocolErrorCode.MethodNotFound:\n\t\t\t\treturn \"MCP_PROTOCOL_ERROR\";\n\t\t\tcase ProtocolErrorCode.InternalError:\n\t\t\t\treturn \"MCP_TOOL_CALL_FAILED\";\n\t\t\tdefault:\n\t\t\t\treturn \"MCP_PROTOCOL_ERROR\";\n\t\t}\n\t}\n\n\tif (isNodeErrno(error)) {\n\t\t// Spawn / process-level failures (ENOENT, EACCES, ENOTDIR, ...).\n\t\treturn \"MCP_SPAWN_FAILED\";\n\t}\n\n\treturn \"MCP_PROTOCOL_ERROR\";\n}\n\n/**\n * Classify a connect/initialize/negotiation failure specifically. Initialization\n * has its own vocabulary (incompatible vs failed vs lost) while still respecting\n * the underlying timeout/spawn distinctions.\n */\nexport function classifyMcpConnectError(error: unknown): McpErrorCode {\n\tif (isAbortError(error)) return \"MCP_REQUEST_CANCELLED\";\n\n\tif (error instanceof SdkError) {\n\t\tswitch (error.code) {\n\t\t\tcase SdkErrorCode.RequestTimeout:\n\t\t\t\treturn \"MCP_INITIALIZATION_FAILED\";\n\t\t\tcase SdkErrorCode.ConnectionClosed:\n\t\t\t\treturn \"MCP_CONNECTION_LOST\";\n\t\t\tcase SdkErrorCode.EraNegotiationFailed:\n\t\t\t\treturn \"MCP_INCOMPATIBLE_SERVER\";\n\t\t\tdefault:\n\t\t\t\treturn \"MCP_INITIALIZATION_FAILED\";\n\t\t}\n\t}\n\n\tif (error instanceof ProtocolError) return \"MCP_INITIALIZATION_FAILED\";\n\n\tif (isNodeErrno(error)) return \"MCP_SPAWN_FAILED\";\n\n\tconst message = error instanceof Error ? error.message : String(error);\n\tif (/protocol version is not supported/i.test(message)) return \"MCP_INCOMPATIBLE_SERVER\";\n\n\treturn \"MCP_INITIALIZATION_FAILED\";\n}\n"]}