@agent-inspect/mcp 6.31.20 → 6.31.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -78,22 +78,34 @@ function extractCallMetadata(bag) {
78
78
  }
79
79
  return {};
80
80
  }
81
+ function peelOptionsObject(value) {
82
+ if (value === null || value === void 0) {
83
+ return { callMetadata: {}, requestOptions: void 0 };
84
+ }
85
+ if (typeof value !== "object") {
86
+ return { callMetadata: {}, requestOptions: void 0 };
87
+ }
88
+ const obj = value;
89
+ const callMetadata = extractCallMetadata(obj);
90
+ if (isAgentInspectMetadataBag(value)) {
91
+ return { callMetadata, requestOptions: void 0 };
92
+ }
93
+ if (isSdkRequestOptions(value) || Object.keys(obj).length > 0) {
94
+ const { metadata: _ignored, ...rest } = obj;
95
+ return {
96
+ callMetadata,
97
+ requestOptions: rest
98
+ };
99
+ }
100
+ return { callMetadata, requestOptions: void 0 };
101
+ }
81
102
  function resolveCallToolArgs(resultSchemaOrOptions, maybeOptions) {
82
103
  if (maybeOptions !== void 0) {
83
- let callMetadata = {};
84
- let requestOptions;
85
- if (isAgentInspectMetadataBag(maybeOptions)) {
86
- callMetadata = extractCallMetadata(maybeOptions);
87
- requestOptions = void 0;
88
- } else if (isSdkRequestOptions(maybeOptions) || maybeOptions === null) {
89
- requestOptions = maybeOptions && typeof maybeOptions === "object" ? maybeOptions : void 0;
90
- } else if (maybeOptions && typeof maybeOptions === "object") {
91
- requestOptions = maybeOptions;
92
- }
104
+ const peeled = peelOptionsObject(maybeOptions);
93
105
  return {
94
106
  resultSchema: resultSchemaOrOptions,
95
- requestOptions,
96
- callMetadata
107
+ requestOptions: peeled.requestOptions,
108
+ callMetadata: peeled.callMetadata
97
109
  };
98
110
  }
99
111
  if (isAgentInspectMetadataBag(resultSchemaOrOptions)) {
@@ -104,10 +116,11 @@ function resolveCallToolArgs(resultSchemaOrOptions, maybeOptions) {
104
116
  };
105
117
  }
106
118
  if (isSdkRequestOptions(resultSchemaOrOptions)) {
119
+ const peeled = peelOptionsObject(resultSchemaOrOptions);
107
120
  return {
108
121
  resultSchema: void 0,
109
- requestOptions: resultSchemaOrOptions,
110
- callMetadata: {}
122
+ requestOptions: peeled.requestOptions,
123
+ callMetadata: peeled.callMetadata
111
124
  };
112
125
  }
113
126
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/summarize.ts","../src/wrap.ts"],"names":["step"],"mappings":";;;;;AAAA,IAAM,0BAAA,GAA6B,GAAA;AAEnC,SAAS,eAAe,KAAA,EAAwB;AAC9C,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,kBAAA;AAAA,EACT;AACF;AAEO,SAAS,iBAAA,CACd,KAAA,EACA,SAAA,GAAY,0BAAA,EACJ;AACR,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,IAAA,GAAO,KAAA;AAAA,IACT,CAAA,MAAO;AAIL,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AACvC,MAAA,IAAA,GAAO,UAAA,KAAe,KAAA,CAAA,GAAY,cAAA,CAAe,KAAK,CAAA,GAAI,UAAA;AAAA,IAC5D;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,IAAA,GAAO,eAAe,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,IAAI,IAAA,CAAK,MAAA,IAAU,SAAA,EAAW,OAAO,IAAA;AACrC,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,SAAA,GAAY,CAAC,CAAC,CAAC,CAAA,GAAA,CAAA;AACrD;AAEO,SAAS,cAAc,GAAA,EAAqB;AACjD,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,KAAK,CAAA,EAAG;AACtC,IAAA,IAAA,GAAQ,IAAA,GAAO,EAAA,GAAK,GAAA,CAAI,UAAA,CAAW,CAAC,CAAA,KAAO,CAAA;AAAA,EAC7C;AACA,EAAA,OAAO,KAAK,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAC1C;AC5BA,IAAI,eAAA,GAAkB,CAAA;AAEtB,SAAS,eAAe,MAAA,EAAyB;AAC/C,EAAA,eAAA,IAAmB,CAAA;AACnB,EAAA,MAAM,IAAA,GAAO,MAAA,EAAQ,IAAA,EAAK,IAAK,KAAA;AAC/B,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,eAAe,CAAA,CAAA;AACnC;AAEA,SAAS,YAAA,CACP,OAAA,EACA,SAAA,GAAuC,EAAC,EACf;AACzB,EAAA,MAAM,QAAA,GAA6B;AAAA,IACjC,MAAA,EAAQ,EAAE,IAAA,EAAM,YAAA,EAAa;AAAA,IAC7B,GAAI,QAAQ,UAAA,GAAa,EAAE,eAAe,OAAA,CAAQ,UAAA,KAAe,EAAC;AAAA,IAClE,GAAI,OAAA,CAAQ,SAAA,GACR,EAAE,gBAAA,EAAkB,cAAc,OAAA,CAAQ,SAAS,CAAA,EAAE,GACrD,EAAC;AAAA,IACL,GAAI,QAAQ,SAAA,GAAY,EAAE,WAAW,OAAA,CAAQ,SAAA,KAAc,EAAC;AAAA,IAC5D,GAAG;AAAA,GACL;AACA,EAAA,OAAO,EAAE,GAAI,OAAA,CAAQ,YAAY,EAAC,EAAI,GAAG,QAAA,EAAS;AACpD;AAGA,IAAM,uBAAA,GAA0B;AAAA,EAC9B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,wBAAA;AAAA,EACA,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA;AAEA,SAAS,oBAAoB,KAAA,EAA4C;AACvE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,OAAO,uBAAA,CAAwB,IAAA,CAAK,CAAC,GAAA,KAAQ,OAAO,GAAG,CAAA;AACzD;AAMA,SAAS,0BACP,KAAA,EACiD;AACjD,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,IAAI,mBAAA,CAAoB,KAAK,CAAA,EAAG,OAAO,KAAA;AACvC,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,IAAI,EAAE,UAAA,IAAc,GAAA,CAAA,EAAM,OAAO,KAAA;AAEjC,EAAA,IAAI,OAAA,IAAW,KAAK,OAAO,KAAA;AAC3B,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,oBAAoB,GAAA,EAED;AAC1B,EAAA,IAAI,GAAA,CAAI,QAAA,IAAY,OAAO,GAAA,CAAI,aAAa,QAAA,EAAU;AACpD,IAAA,OAAO,GAAA,CAAI,QAAA;AAAA,EACb;AACA,EAAA,OAAO,EAAC;AACV;AAOO,SAAS,mBAAA,CACd,uBACA,YAAA,EAKA;AAEA,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,IAAI,eAAwC,EAAC;AAC7C,IAAA,IAAI,cAAA;AAEJ,IAAA,IAAI,yBAAA,CAA0B,YAAY,CAAA,EAAG;AAC3C,MAAA,YAAA,GAAe,oBAAoB,YAAY,CAAA;AAE/C,MAAA,cAAA,GAAiB,MAAA;AAAA,IACnB,CAAA,MAAA,IAAW,mBAAA,CAAoB,YAAY,CAAA,IAAK,iBAAiB,IAAA,EAAM;AACrE,MAAA,cAAA,GACE,YAAA,IAAgB,OAAO,YAAA,KAAiB,QAAA,GACnC,YAAA,GACD,MAAA;AAAA,IACR,CAAA,MAAA,IAAW,YAAA,IAAgB,OAAO,YAAA,KAAiB,QAAA,EAAU;AAE3D,MAAA,cAAA,GAAiB,YAAA;AAAA,IACnB;AAEA,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,qBAAA;AAAA,MACd,cAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI,yBAAA,CAA0B,qBAAqB,CAAA,EAAG;AACpD,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,MAAA;AAAA,MACd,cAAA,EAAgB,MAAA;AAAA,MAChB,YAAA,EAAc,oBAAoB,qBAAqB;AAAA,KACzD;AAAA,EACF;AAEA,EAAA,IAAI,mBAAA,CAAoB,qBAAqB,CAAA,EAAG;AAC9C,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,MAAA;AAAA,MACd,cAAA,EAAgB,qBAAA;AAAA,MAChB,cAAc;AAAC,KACjB;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,qBAAA;AAAA,IACd,cAAA,EAAgB,MAAA;AAAA,IAChB,cAAc;AAAC,GACjB;AACF;AAEA,SAAS,cAAA,CACP,YAAA,EACA,MAAA,EACA,YAAA,EACA,cAAA,EACkB;AAClB,EAAA,MAAM,EAAA,GAAK,YAAA;AAKX,EAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,IAAA,OAAO,EAAA,CAAG,MAAA,EAAQ,YAAA,EAAc,cAAc,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,OAAO,EAAA,CAAG,QAAQ,YAAY,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAG,MAAM,CAAA;AAClB;AAcO,SAAS,aAAA,CACd,MAAA,EACA,OAAA,GAAkC,EAAC,EAChC;AACH,EAAA,MAAM,gBAAA,GAAmB,QAAQ,gBAAA,IAAoB,GAAA;AAErD,EAAA,MAAM,aAAA,GACJ,OAAO,MAAA,CAAO,SAAA,KAAc,aACxB,MAAA,CAAO,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA,GAC5B,MAAA;AACN,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,aAAA,GACrB,OAAO,MAAA,EAAkB,cAAA,KACvBA,iBAAA;AAAA,IACE,gBAAA;AAAA,IACA,YAAY;AACV,MAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,QAAA,OACE,aAAA,CAIA,QAAQ,cAAc,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,cAAc,MAAM,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,QAAA,EAAU,aAAa,OAAA,EAAS;AAAA,QAC9B,QAAA,EAAU,YAAA;AAAA,QACV,UAAA,EAAY,cAAA,CAAe,OAAA,CAAQ,gBAAgB;AAAA,OACpD;AAAA;AACH,GACF,GACF,MAAA;AAEJ,EAAA,MAAM,eAAA,GAAkB,OACtB,MAAA,EACA,qBAAA,EACA,YAAA,KACG;AACH,IAAA,MAAM,EAAE,YAAA,EAAc,cAAA,EAAgB,YAAA,EAAa,GAAI,mBAAA;AAAA,MACrD,qBAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAOA,iBAAA;AAAA,MACL,CAAA,IAAA,EAAO,OAAO,IAAI,CAAA,CAAA;AAAA,MAClB,YACE,cAAA,CAAe,YAAA,EAAc,MAAA,EAAQ,cAAc,cAAc,CAAA;AAAA,MACnE;AAAA,QACE,IAAA,EAAM,MAAA;AAAA,QACN,QAAA,EAAU,aAAa,OAAA,EAAS;AAAA,UAC9B,UAAU,MAAA,CAAO,IAAA;AAAA,UACjB,UAAA,EAAY,cAAA,CAAe,OAAA,CAAQ,gBAAgB,CAAA;AAAA,UACnD,eAAA,EAAiB,iBAAA;AAAA,YACf,MAAA,CAAO,aAAa,EAAC;AAAA,YACrB;AAAA,WACF;AAAA,UACA,GAAG;AAAA,SACJ;AAAA;AACH,KACF;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU;AAC9B,MAAA,IAAI,QAAA,KAAa,WAAA,IAAe,gBAAA,KAAqB,MAAA,EAAW;AAC9D,QAAA,OAAO,gBAAA;AAAA,MACT;AACA,MAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,QAAA,OAAO,eAAA;AAAA,MACT;AACA,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,UAAU,QAAQ,CAAA;AACpD,MAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,QAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACD,CAAA;AACH;AAGO,SAAS,2BAAA,GAAoC;AAClD,EAAA,eAAA,GAAkB,CAAA;AACpB","file":"index.cjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nfunction fallbackString(value: unknown): string {\n try {\n return String(value);\n } catch {\n return \"[unserializable]\";\n }\n}\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n // JSON.stringify returns undefined (not a string) for undefined,\n // functions, and symbols; falling through with undefined would crash\n // instrumentation at text.length below.\n const serialized = JSON.stringify(value);\n text = serialized === undefined ? fallbackString(value) : serialized;\n }\n } catch {\n text = fallbackString(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpRequestOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/** SDK RequestOptions keys — must never be swallowed as AgentInspect metadata. */\nconst SDK_REQUEST_OPTION_KEYS = [\n \"signal\",\n \"timeout\",\n \"onprogress\",\n \"resetTimeoutOnProgress\",\n \"maxTotalTimeout\",\n \"relatedRequestId\",\n \"resumptionToken\",\n \"onresumptiontoken\",\n] as const;\n\nfunction isSdkRequestOptions(value: unknown): value is McpRequestOptions {\n if (!value || typeof value !== \"object\") return false;\n const obj = value as Record<string, unknown>;\n return SDK_REQUEST_OPTION_KEYS.some((key) => key in obj);\n}\n\n/**\n * AgentInspect per-call metadata bag: `{ metadata: {...} }` without SDK option keys.\n * Must not consume ordinary SDK RequestOptions that happen to be objects.\n */\nfunction isAgentInspectMetadataBag(\n value: unknown,\n): value is { metadata?: Record<string, unknown> } {\n if (!value || typeof value !== \"object\") return false;\n if (isSdkRequestOptions(value)) return false;\n const obj = value as Record<string, unknown>;\n if (!(\"metadata\" in obj)) return false;\n // Zod/result schemas expose parse — never treat those as AI bags.\n if (\"parse\" in obj) return false;\n return true;\n}\n\nfunction extractCallMetadata(bag: {\n metadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n if (bag.metadata && typeof bag.metadata === \"object\") {\n return bag.metadata;\n }\n return {};\n}\n\n/**\n * Resolve SDK callTool arity:\n * callTool(params, resultSchema?, requestOptions?)\n * plus AgentInspect overloads that peel `{ metadata }` without dropping RequestOptions.\n */\nexport function resolveCallToolArgs(\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n): {\n resultSchema: unknown;\n requestOptions: McpRequestOptions | undefined;\n callMetadata: Record<string, unknown>;\n} {\n // Three-arg form: (params, schema|undefined, options)\n if (maybeOptions !== undefined) {\n let callMetadata: Record<string, unknown> = {};\n let requestOptions: McpRequestOptions | undefined;\n\n if (isAgentInspectMetadataBag(maybeOptions)) {\n callMetadata = extractCallMetadata(maybeOptions);\n // Remaining SDK keys (if any were mixed in) still forward — but AI bags exclude them.\n requestOptions = undefined;\n } else if (isSdkRequestOptions(maybeOptions) || maybeOptions === null) {\n requestOptions =\n maybeOptions && typeof maybeOptions === \"object\"\n ? (maybeOptions as McpRequestOptions)\n : undefined;\n } else if (maybeOptions && typeof maybeOptions === \"object\") {\n // Unknown object third arg — forward as RequestOptions to preserve caller intent.\n requestOptions = maybeOptions as McpRequestOptions;\n }\n\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions,\n callMetadata,\n };\n }\n\n // Two-arg form: (params, schema) OR (params, { metadata }) OR (params, RequestOptions)\n if (isAgentInspectMetadataBag(resultSchemaOrOptions)) {\n return {\n resultSchema: undefined,\n requestOptions: undefined,\n callMetadata: extractCallMetadata(resultSchemaOrOptions),\n };\n }\n\n if (isSdkRequestOptions(resultSchemaOrOptions)) {\n return {\n resultSchema: undefined,\n requestOptions: resultSchemaOrOptions,\n callMetadata: {},\n };\n }\n\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions: undefined,\n callMetadata: {},\n };\n}\n\nfunction invokeCallTool(\n callToolImpl: McpClientLike[\"callTool\"],\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchema: unknown,\n requestOptions: McpRequestOptions | undefined,\n): Promise<unknown> {\n const fn = callToolImpl as (\n p: unknown,\n schema?: unknown,\n opts?: unknown,\n ) => Promise<unknown>;\n if (requestOptions !== undefined) {\n return fn(params, resultSchema, requestOptions);\n }\n if (resultSchema !== undefined) {\n return fn(params, resultSchema);\n }\n return fn(params);\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n *\n * Uses a Proxy over the original client so prototype methods (`connect`,\n * `close`, `listResources`, …), private SDK state, and `instanceof` stay intact.\n * A shallow object spread would drop prototype methods and copy private fields.\n *\n * Forwards the real SDK argument positions, including `RequestOptions`\n * (`signal`, `timeout`, progress callbacks). Does not fake cancellation while\n * still dispatching the underlying request.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n\n const listToolsImpl =\n typeof client.listTools === \"function\"\n ? client.listTools.bind(client)\n : undefined;\n const callToolImpl = client.callTool.bind(client);\n\n const wrappedListTools = listToolsImpl\n ? async (params?: unknown, requestOptions?: McpRequestOptions) =>\n step(\n \"mcp:tools/list\",\n async () => {\n if (requestOptions !== undefined) {\n return (\n listToolsImpl as (\n p?: unknown,\n opts?: unknown,\n ) => Promise<unknown>\n )(params, requestOptions);\n }\n return listToolsImpl(params);\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n )\n : undefined;\n\n const wrappedCallTool = async (\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n ) => {\n const { resultSchema, requestOptions, callMetadata } = resolveCallToolArgs(\n resultSchemaOrOptions,\n maybeOptions,\n );\n\n return step(\n `mcp:${params.name}`,\n async () =>\n invokeCallTool(callToolImpl, params, resultSchema, requestOptions),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n ...callMetadata,\n }),\n },\n );\n };\n\n return new Proxy(client, {\n get(target, property, receiver) {\n if (property === \"listTools\" && wrappedListTools !== undefined) {\n return wrappedListTools;\n }\n if (property === \"callTool\") {\n return wrappedCallTool;\n }\n const value = Reflect.get(target, property, receiver);\n if (typeof value === \"function\") {\n return value.bind(target);\n }\n return value;\n },\n }) as T;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
1
+ {"version":3,"sources":["../src/summarize.ts","../src/wrap.ts"],"names":["step"],"mappings":"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","file":"index.cjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nfunction fallbackString(value: unknown): string {\n try {\n return String(value);\n } catch {\n return \"[unserializable]\";\n }\n}\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n // JSON.stringify returns undefined (not a string) for undefined,\n // functions, and symbols; falling through with undefined would crash\n // instrumentation at text.length below.\n const serialized = JSON.stringify(value);\n text = serialized === undefined ? fallbackString(value) : serialized;\n }\n } catch {\n text = fallbackString(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpRequestOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/** SDK RequestOptions keys — must never be swallowed as AgentInspect metadata. */\nconst SDK_REQUEST_OPTION_KEYS = [\n \"signal\",\n \"timeout\",\n \"onprogress\",\n \"resetTimeoutOnProgress\",\n \"maxTotalTimeout\",\n \"relatedRequestId\",\n \"resumptionToken\",\n \"onresumptiontoken\",\n] as const;\n\nfunction isSdkRequestOptions(value: unknown): value is McpRequestOptions {\n if (!value || typeof value !== \"object\") return false;\n const obj = value as Record<string, unknown>;\n return SDK_REQUEST_OPTION_KEYS.some((key) => key in obj);\n}\n\n/**\n * AgentInspect per-call metadata bag: `{ metadata: {...} }` without SDK option keys.\n * Must not consume ordinary SDK RequestOptions that happen to be objects.\n */\nfunction isAgentInspectMetadataBag(\n value: unknown,\n): value is { metadata?: Record<string, unknown> } {\n if (!value || typeof value !== \"object\") return false;\n if (isSdkRequestOptions(value)) return false;\n const obj = value as Record<string, unknown>;\n if (!(\"metadata\" in obj)) return false;\n // Zod/result schemas expose parse — never treat those as AI bags.\n if (\"parse\" in obj) return false;\n return true;\n}\n\nfunction extractCallMetadata(bag: {\n metadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n if (bag.metadata && typeof bag.metadata === \"object\") {\n return bag.metadata;\n }\n return {};\n}\n\n/** Peel AgentInspect `metadata` without consuming SDK RequestOptions keys. */\nfunction peelOptionsObject(value: unknown): {\n callMetadata: Record<string, unknown>;\n requestOptions: McpRequestOptions | undefined;\n} {\n if (value === null || value === undefined) {\n return { callMetadata: {}, requestOptions: undefined };\n }\n if (typeof value !== \"object\") {\n return { callMetadata: {}, requestOptions: undefined };\n }\n const obj = value as Record<string, unknown>;\n const callMetadata = extractCallMetadata(obj);\n\n // Pure AI bag — do not forward as SDK RequestOptions.\n if (isAgentInspectMetadataBag(value)) {\n return { callMetadata, requestOptions: undefined };\n }\n\n if (isSdkRequestOptions(value) || Object.keys(obj).length > 0) {\n const { metadata: _ignored, ...rest } = obj;\n return {\n callMetadata,\n requestOptions: rest as McpRequestOptions,\n };\n }\n\n return { callMetadata, requestOptions: undefined };\n}\n\n/**\n * Resolve SDK callTool arity:\n * callTool(params, resultSchema?, requestOptions?)\n * plus AgentInspect overloads that peel `{ metadata }` without dropping RequestOptions.\n * Composed `{ timeout, metadata: { operationId, attemptId } }` keeps both sides.\n */\nexport function resolveCallToolArgs(\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n): {\n resultSchema: unknown;\n requestOptions: McpRequestOptions | undefined;\n callMetadata: Record<string, unknown>;\n} {\n // Three-arg form: (params, schema|undefined, options)\n if (maybeOptions !== undefined) {\n const peeled = peelOptionsObject(maybeOptions);\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions: peeled.requestOptions,\n callMetadata: peeled.callMetadata,\n };\n }\n\n // Two-arg form: (params, schema) OR (params, { metadata }) OR (params, RequestOptions)\n if (isAgentInspectMetadataBag(resultSchemaOrOptions)) {\n return {\n resultSchema: undefined,\n requestOptions: undefined,\n callMetadata: extractCallMetadata(resultSchemaOrOptions),\n };\n }\n\n if (isSdkRequestOptions(resultSchemaOrOptions)) {\n const peeled = peelOptionsObject(resultSchemaOrOptions);\n return {\n resultSchema: undefined,\n requestOptions: peeled.requestOptions,\n callMetadata: peeled.callMetadata,\n };\n }\n\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions: undefined,\n callMetadata: {},\n };\n}\n\nfunction invokeCallTool(\n callToolImpl: McpClientLike[\"callTool\"],\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchema: unknown,\n requestOptions: McpRequestOptions | undefined,\n): Promise<unknown> {\n const fn = callToolImpl as (\n p: unknown,\n schema?: unknown,\n opts?: unknown,\n ) => Promise<unknown>;\n if (requestOptions !== undefined) {\n return fn(params, resultSchema, requestOptions);\n }\n if (resultSchema !== undefined) {\n return fn(params, resultSchema);\n }\n return fn(params);\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n *\n * Uses a Proxy over the original client so prototype methods (`connect`,\n * `close`, `listResources`, …), private SDK state, and `instanceof` stay intact.\n * A shallow object spread would drop prototype methods and copy private fields.\n *\n * Forwards the real SDK argument positions, including `RequestOptions`\n * (`signal`, `timeout`, progress callbacks). Does not fake cancellation while\n * still dispatching the underlying request.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n\n const listToolsImpl =\n typeof client.listTools === \"function\"\n ? client.listTools.bind(client)\n : undefined;\n const callToolImpl = client.callTool.bind(client);\n\n const wrappedListTools = listToolsImpl\n ? async (params?: unknown, requestOptions?: McpRequestOptions) =>\n step(\n \"mcp:tools/list\",\n async () => {\n if (requestOptions !== undefined) {\n return (\n listToolsImpl as (\n p?: unknown,\n opts?: unknown,\n ) => Promise<unknown>\n )(params, requestOptions);\n }\n return listToolsImpl(params);\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n )\n : undefined;\n\n const wrappedCallTool = async (\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n ) => {\n const { resultSchema, requestOptions, callMetadata } = resolveCallToolArgs(\n resultSchemaOrOptions,\n maybeOptions,\n );\n\n return step(\n `mcp:${params.name}`,\n async () =>\n invokeCallTool(callToolImpl, params, resultSchema, requestOptions),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n ...callMetadata,\n }),\n },\n );\n };\n\n return new Proxy(client, {\n get(target, property, receiver) {\n if (property === \"listTools\" && wrappedListTools !== undefined) {\n return wrappedListTools;\n }\n if (property === \"callTool\") {\n return wrappedCallTool;\n }\n const value = Reflect.get(target, property, receiver);\n if (typeof value === \"function\") {\n return value.bind(target);\n }\n return value;\n },\n }) as T;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -36,15 +36,18 @@ interface McpRequestOptions {
36
36
  * Minimal MCP client surface for local tracing. Compatible with common SDK
37
37
  * client shapes without requiring @modelcontextprotocol/sdk at runtime.
38
38
  *
39
+ * Method syntax (not property function types) so real SDK `Client` remains
40
+ * assignable under `strictFunctionTypes` (bivariant method parameters).
41
+ * `callTool` returns `Promise<unknown>` to accept both normal tool results and
42
+ * the SDK compatibility `{ toolResult }` branch.
43
+ *
39
44
  * Matches SDK arity: `callTool(params, resultSchema?, requestOptions?)` and
40
45
  * `listTools(params?, requestOptions?)`. AgentInspect also accepts a
41
46
  * `{ metadata }` bag in place of schema/options when it is not RequestOptions-shaped.
42
47
  */
43
48
  interface McpClientLike {
44
- listTools?: (params?: unknown, options?: McpRequestOptions) => Promise<McpListToolsResult>;
45
- callTool: (params: McpCallToolParams, resultSchemaOrOptions?: unknown, options?: McpRequestOptions | {
46
- metadata?: Record<string, unknown>;
47
- }) => Promise<McpCallToolResult>;
49
+ listTools?(params?: unknown, options?: unknown): Promise<McpListToolsResult | unknown>;
50
+ callTool(params: McpCallToolParams, resultSchemaOrOptions?: unknown, options?: unknown): Promise<unknown>;
48
51
  }
49
52
  interface McpClientTracerOptions {
50
53
  serverName?: string;
@@ -77,6 +80,7 @@ declare function hashServerUrl(url: string): string;
77
80
  * Resolve SDK callTool arity:
78
81
  * callTool(params, resultSchema?, requestOptions?)
79
82
  * plus AgentInspect overloads that peel `{ metadata }` without dropping RequestOptions.
83
+ * Composed `{ timeout, metadata: { operationId, attemptId } }` keeps both sides.
80
84
  */
81
85
  declare function resolveCallToolArgs(resultSchemaOrOptions?: unknown, maybeOptions?: unknown): {
82
86
  resultSchema: unknown;
package/dist/index.d.ts CHANGED
@@ -36,15 +36,18 @@ interface McpRequestOptions {
36
36
  * Minimal MCP client surface for local tracing. Compatible with common SDK
37
37
  * client shapes without requiring @modelcontextprotocol/sdk at runtime.
38
38
  *
39
+ * Method syntax (not property function types) so real SDK `Client` remains
40
+ * assignable under `strictFunctionTypes` (bivariant method parameters).
41
+ * `callTool` returns `Promise<unknown>` to accept both normal tool results and
42
+ * the SDK compatibility `{ toolResult }` branch.
43
+ *
39
44
  * Matches SDK arity: `callTool(params, resultSchema?, requestOptions?)` and
40
45
  * `listTools(params?, requestOptions?)`. AgentInspect also accepts a
41
46
  * `{ metadata }` bag in place of schema/options when it is not RequestOptions-shaped.
42
47
  */
43
48
  interface McpClientLike {
44
- listTools?: (params?: unknown, options?: McpRequestOptions) => Promise<McpListToolsResult>;
45
- callTool: (params: McpCallToolParams, resultSchemaOrOptions?: unknown, options?: McpRequestOptions | {
46
- metadata?: Record<string, unknown>;
47
- }) => Promise<McpCallToolResult>;
49
+ listTools?(params?: unknown, options?: unknown): Promise<McpListToolsResult | unknown>;
50
+ callTool(params: McpCallToolParams, resultSchemaOrOptions?: unknown, options?: unknown): Promise<unknown>;
48
51
  }
49
52
  interface McpClientTracerOptions {
50
53
  serverName?: string;
@@ -77,6 +80,7 @@ declare function hashServerUrl(url: string): string;
77
80
  * Resolve SDK callTool arity:
78
81
  * callTool(params, resultSchema?, requestOptions?)
79
82
  * plus AgentInspect overloads that peel `{ metadata }` without dropping RequestOptions.
83
+ * Composed `{ timeout, metadata: { operationId, attemptId } }` keeps both sides.
80
84
  */
81
85
  declare function resolveCallToolArgs(resultSchemaOrOptions?: unknown, maybeOptions?: unknown): {
82
86
  resultSchema: unknown;
package/dist/index.mjs CHANGED
@@ -76,22 +76,34 @@ function extractCallMetadata(bag) {
76
76
  }
77
77
  return {};
78
78
  }
79
+ function peelOptionsObject(value) {
80
+ if (value === null || value === void 0) {
81
+ return { callMetadata: {}, requestOptions: void 0 };
82
+ }
83
+ if (typeof value !== "object") {
84
+ return { callMetadata: {}, requestOptions: void 0 };
85
+ }
86
+ const obj = value;
87
+ const callMetadata = extractCallMetadata(obj);
88
+ if (isAgentInspectMetadataBag(value)) {
89
+ return { callMetadata, requestOptions: void 0 };
90
+ }
91
+ if (isSdkRequestOptions(value) || Object.keys(obj).length > 0) {
92
+ const { metadata: _ignored, ...rest } = obj;
93
+ return {
94
+ callMetadata,
95
+ requestOptions: rest
96
+ };
97
+ }
98
+ return { callMetadata, requestOptions: void 0 };
99
+ }
79
100
  function resolveCallToolArgs(resultSchemaOrOptions, maybeOptions) {
80
101
  if (maybeOptions !== void 0) {
81
- let callMetadata = {};
82
- let requestOptions;
83
- if (isAgentInspectMetadataBag(maybeOptions)) {
84
- callMetadata = extractCallMetadata(maybeOptions);
85
- requestOptions = void 0;
86
- } else if (isSdkRequestOptions(maybeOptions) || maybeOptions === null) {
87
- requestOptions = maybeOptions && typeof maybeOptions === "object" ? maybeOptions : void 0;
88
- } else if (maybeOptions && typeof maybeOptions === "object") {
89
- requestOptions = maybeOptions;
90
- }
102
+ const peeled = peelOptionsObject(maybeOptions);
91
103
  return {
92
104
  resultSchema: resultSchemaOrOptions,
93
- requestOptions,
94
- callMetadata
105
+ requestOptions: peeled.requestOptions,
106
+ callMetadata: peeled.callMetadata
95
107
  };
96
108
  }
97
109
  if (isAgentInspectMetadataBag(resultSchemaOrOptions)) {
@@ -102,10 +114,11 @@ function resolveCallToolArgs(resultSchemaOrOptions, maybeOptions) {
102
114
  };
103
115
  }
104
116
  if (isSdkRequestOptions(resultSchemaOrOptions)) {
117
+ const peeled = peelOptionsObject(resultSchemaOrOptions);
105
118
  return {
106
119
  resultSchema: void 0,
107
- requestOptions: resultSchemaOrOptions,
108
- callMetadata: {}
120
+ requestOptions: peeled.requestOptions,
121
+ callMetadata: peeled.callMetadata
109
122
  };
110
123
  }
111
124
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/summarize.ts","../src/wrap.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nfunction fallbackString(value: unknown): string {\n try {\n return String(value);\n } catch {\n return \"[unserializable]\";\n }\n}\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n // JSON.stringify returns undefined (not a string) for undefined,\n // functions, and symbols; falling through with undefined would crash\n // instrumentation at text.length below.\n const serialized = JSON.stringify(value);\n text = serialized === undefined ? fallbackString(value) : serialized;\n }\n } catch {\n text = fallbackString(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpRequestOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/** SDK RequestOptions keys — must never be swallowed as AgentInspect metadata. */\nconst SDK_REQUEST_OPTION_KEYS = [\n \"signal\",\n \"timeout\",\n \"onprogress\",\n \"resetTimeoutOnProgress\",\n \"maxTotalTimeout\",\n \"relatedRequestId\",\n \"resumptionToken\",\n \"onresumptiontoken\",\n] as const;\n\nfunction isSdkRequestOptions(value: unknown): value is McpRequestOptions {\n if (!value || typeof value !== \"object\") return false;\n const obj = value as Record<string, unknown>;\n return SDK_REQUEST_OPTION_KEYS.some((key) => key in obj);\n}\n\n/**\n * AgentInspect per-call metadata bag: `{ metadata: {...} }` without SDK option keys.\n * Must not consume ordinary SDK RequestOptions that happen to be objects.\n */\nfunction isAgentInspectMetadataBag(\n value: unknown,\n): value is { metadata?: Record<string, unknown> } {\n if (!value || typeof value !== \"object\") return false;\n if (isSdkRequestOptions(value)) return false;\n const obj = value as Record<string, unknown>;\n if (!(\"metadata\" in obj)) return false;\n // Zod/result schemas expose parse — never treat those as AI bags.\n if (\"parse\" in obj) return false;\n return true;\n}\n\nfunction extractCallMetadata(bag: {\n metadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n if (bag.metadata && typeof bag.metadata === \"object\") {\n return bag.metadata;\n }\n return {};\n}\n\n/**\n * Resolve SDK callTool arity:\n * callTool(params, resultSchema?, requestOptions?)\n * plus AgentInspect overloads that peel `{ metadata }` without dropping RequestOptions.\n */\nexport function resolveCallToolArgs(\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n): {\n resultSchema: unknown;\n requestOptions: McpRequestOptions | undefined;\n callMetadata: Record<string, unknown>;\n} {\n // Three-arg form: (params, schema|undefined, options)\n if (maybeOptions !== undefined) {\n let callMetadata: Record<string, unknown> = {};\n let requestOptions: McpRequestOptions | undefined;\n\n if (isAgentInspectMetadataBag(maybeOptions)) {\n callMetadata = extractCallMetadata(maybeOptions);\n // Remaining SDK keys (if any were mixed in) still forward — but AI bags exclude them.\n requestOptions = undefined;\n } else if (isSdkRequestOptions(maybeOptions) || maybeOptions === null) {\n requestOptions =\n maybeOptions && typeof maybeOptions === \"object\"\n ? (maybeOptions as McpRequestOptions)\n : undefined;\n } else if (maybeOptions && typeof maybeOptions === \"object\") {\n // Unknown object third arg — forward as RequestOptions to preserve caller intent.\n requestOptions = maybeOptions as McpRequestOptions;\n }\n\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions,\n callMetadata,\n };\n }\n\n // Two-arg form: (params, schema) OR (params, { metadata }) OR (params, RequestOptions)\n if (isAgentInspectMetadataBag(resultSchemaOrOptions)) {\n return {\n resultSchema: undefined,\n requestOptions: undefined,\n callMetadata: extractCallMetadata(resultSchemaOrOptions),\n };\n }\n\n if (isSdkRequestOptions(resultSchemaOrOptions)) {\n return {\n resultSchema: undefined,\n requestOptions: resultSchemaOrOptions,\n callMetadata: {},\n };\n }\n\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions: undefined,\n callMetadata: {},\n };\n}\n\nfunction invokeCallTool(\n callToolImpl: McpClientLike[\"callTool\"],\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchema: unknown,\n requestOptions: McpRequestOptions | undefined,\n): Promise<unknown> {\n const fn = callToolImpl as (\n p: unknown,\n schema?: unknown,\n opts?: unknown,\n ) => Promise<unknown>;\n if (requestOptions !== undefined) {\n return fn(params, resultSchema, requestOptions);\n }\n if (resultSchema !== undefined) {\n return fn(params, resultSchema);\n }\n return fn(params);\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n *\n * Uses a Proxy over the original client so prototype methods (`connect`,\n * `close`, `listResources`, …), private SDK state, and `instanceof` stay intact.\n * A shallow object spread would drop prototype methods and copy private fields.\n *\n * Forwards the real SDK argument positions, including `RequestOptions`\n * (`signal`, `timeout`, progress callbacks). Does not fake cancellation while\n * still dispatching the underlying request.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n\n const listToolsImpl =\n typeof client.listTools === \"function\"\n ? client.listTools.bind(client)\n : undefined;\n const callToolImpl = client.callTool.bind(client);\n\n const wrappedListTools = listToolsImpl\n ? async (params?: unknown, requestOptions?: McpRequestOptions) =>\n step(\n \"mcp:tools/list\",\n async () => {\n if (requestOptions !== undefined) {\n return (\n listToolsImpl as (\n p?: unknown,\n opts?: unknown,\n ) => Promise<unknown>\n )(params, requestOptions);\n }\n return listToolsImpl(params);\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n )\n : undefined;\n\n const wrappedCallTool = async (\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n ) => {\n const { resultSchema, requestOptions, callMetadata } = resolveCallToolArgs(\n resultSchemaOrOptions,\n maybeOptions,\n );\n\n return step(\n `mcp:${params.name}`,\n async () =>\n invokeCallTool(callToolImpl, params, resultSchema, requestOptions),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n ...callMetadata,\n }),\n },\n );\n };\n\n return new Proxy(client, {\n get(target, property, receiver) {\n if (property === \"listTools\" && wrappedListTools !== undefined) {\n return wrappedListTools;\n }\n if (property === \"callTool\") {\n return wrappedCallTool;\n }\n const value = Reflect.get(target, property, receiver);\n if (typeof value === \"function\") {\n return value.bind(target);\n }\n return value;\n },\n }) as T;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
1
+ {"version":3,"sources":["../src/summarize.ts","../src/wrap.ts"],"names":[],"mappings":";;;AAAA,IAAM,0BAAA,GAA6B,GAAA;AAEnC,SAAS,eAAe,KAAA,EAAwB;AAC9C,EAAA,IAAI;AACF,IAAA,OAAO,OAAO,KAAK,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,kBAAA;AAAA,EACT;AACF;AAEO,SAAS,iBAAA,CACd,KAAA,EACA,SAAA,GAAY,0BAAA,EACJ;AACR,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,IAAA,GAAO,KAAA;AAAA,IACT,CAAA,MAAO;AAIL,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AACvC,MAAA,IAAA,GAAO,UAAA,KAAe,KAAA,CAAA,GAAY,cAAA,CAAe,KAAK,CAAA,GAAI,UAAA;AAAA,IAC5D;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,IAAA,GAAO,eAAe,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,IAAI,IAAA,CAAK,MAAA,IAAU,SAAA,EAAW,OAAO,IAAA;AACrC,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAG,SAAA,GAAY,CAAC,CAAC,CAAC,CAAA,GAAA,CAAA;AACrD;AAEO,SAAS,cAAc,GAAA,EAAqB;AACjD,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,KAAK,CAAA,EAAG;AACtC,IAAA,IAAA,GAAQ,IAAA,GAAO,EAAA,GAAK,GAAA,CAAI,UAAA,CAAW,CAAC,CAAA,KAAO,CAAA;AAAA,EAC7C;AACA,EAAA,OAAO,KAAK,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAC1C;AC5BA,IAAI,eAAA,GAAkB,CAAA;AAEtB,SAAS,eAAe,MAAA,EAAyB;AAC/C,EAAA,eAAA,IAAmB,CAAA;AACnB,EAAA,MAAM,IAAA,GAAO,MAAA,EAAQ,IAAA,EAAK,IAAK,KAAA;AAC/B,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,eAAe,CAAA,CAAA;AACnC;AAEA,SAAS,YAAA,CACP,OAAA,EACA,SAAA,GAAuC,EAAC,EACf;AACzB,EAAA,MAAM,QAAA,GAA6B;AAAA,IACjC,MAAA,EAAQ,EAAE,IAAA,EAAM,YAAA,EAAa;AAAA,IAC7B,GAAI,QAAQ,UAAA,GAAa,EAAE,eAAe,OAAA,CAAQ,UAAA,KAAe,EAAC;AAAA,IAClE,GAAI,OAAA,CAAQ,SAAA,GACR,EAAE,gBAAA,EAAkB,cAAc,OAAA,CAAQ,SAAS,CAAA,EAAE,GACrD,EAAC;AAAA,IACL,GAAI,QAAQ,SAAA,GAAY,EAAE,WAAW,OAAA,CAAQ,SAAA,KAAc,EAAC;AAAA,IAC5D,GAAG;AAAA,GACL;AACA,EAAA,OAAO,EAAE,GAAI,OAAA,CAAQ,YAAY,EAAC,EAAI,GAAG,QAAA,EAAS;AACpD;AAGA,IAAM,uBAAA,GAA0B;AAAA,EAC9B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,wBAAA;AAAA,EACA,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA;AAEA,SAAS,oBAAoB,KAAA,EAA4C;AACvE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,OAAO,uBAAA,CAAwB,IAAA,CAAK,CAAC,GAAA,KAAQ,OAAO,GAAG,CAAA;AACzD;AAMA,SAAS,0BACP,KAAA,EACiD;AACjD,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AAChD,EAAA,IAAI,mBAAA,CAAoB,KAAK,CAAA,EAAG,OAAO,KAAA;AACvC,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,IAAI,EAAE,UAAA,IAAc,GAAA,CAAA,EAAM,OAAO,KAAA;AAEjC,EAAA,IAAI,OAAA,IAAW,KAAK,OAAO,KAAA;AAC3B,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,oBAAoB,GAAA,EAED;AAC1B,EAAA,IAAI,GAAA,CAAI,QAAA,IAAY,OAAO,GAAA,CAAI,aAAa,QAAA,EAAU;AACpD,IAAA,OAAO,GAAA,CAAI,QAAA;AAAA,EACb;AACA,EAAA,OAAO,EAAC;AACV;AAGA,SAAS,kBAAkB,KAAA,EAGzB;AACA,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,OAAO,EAAE,YAAA,EAAc,EAAC,EAAG,gBAAgB,MAAA,EAAU;AAAA,EACvD;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,YAAA,EAAc,EAAC,EAAG,gBAAgB,MAAA,EAAU;AAAA,EACvD;AACA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,MAAM,YAAA,GAAe,oBAAoB,GAAG,CAAA;AAG5C,EAAA,IAAI,yBAAA,CAA0B,KAAK,CAAA,EAAG;AACpC,IAAA,OAAO,EAAE,YAAA,EAAc,cAAA,EAAgB,MAAA,EAAU;AAAA,EACnD;AAEA,EAAA,IAAI,mBAAA,CAAoB,KAAK,CAAA,IAAK,MAAA,CAAO,KAAK,GAAG,CAAA,CAAE,SAAS,CAAA,EAAG;AAC7D,IAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,GAAG,MAAK,GAAI,GAAA;AACxC,IAAA,OAAO;AAAA,MACL,YAAA;AAAA,MACA,cAAA,EAAgB;AAAA,KAClB;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,YAAA,EAAc,cAAA,EAAgB,MAAA,EAAU;AACnD;AAQO,SAAS,mBAAA,CACd,uBACA,YAAA,EAKA;AAEA,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,MAAM,MAAA,GAAS,kBAAkB,YAAY,CAAA;AAC7C,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,qBAAA;AAAA,MACd,gBAAgB,MAAA,CAAO,cAAA;AAAA,MACvB,cAAc,MAAA,CAAO;AAAA,KACvB;AAAA,EACF;AAGA,EAAA,IAAI,yBAAA,CAA0B,qBAAqB,CAAA,EAAG;AACpD,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,MAAA;AAAA,MACd,cAAA,EAAgB,MAAA;AAAA,MAChB,YAAA,EAAc,oBAAoB,qBAAqB;AAAA,KACzD;AAAA,EACF;AAEA,EAAA,IAAI,mBAAA,CAAoB,qBAAqB,CAAA,EAAG;AAC9C,IAAA,MAAM,MAAA,GAAS,kBAAkB,qBAAqB,CAAA;AACtD,IAAA,OAAO;AAAA,MACL,YAAA,EAAc,MAAA;AAAA,MACd,gBAAgB,MAAA,CAAO,cAAA;AAAA,MACvB,cAAc,MAAA,CAAO;AAAA,KACvB;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,qBAAA;AAAA,IACd,cAAA,EAAgB,MAAA;AAAA,IAChB,cAAc;AAAC,GACjB;AACF;AAEA,SAAS,cAAA,CACP,YAAA,EACA,MAAA,EACA,YAAA,EACA,cAAA,EACkB;AAClB,EAAA,MAAM,EAAA,GAAK,YAAA;AAKX,EAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,IAAA,OAAO,EAAA,CAAG,MAAA,EAAQ,YAAA,EAAc,cAAc,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,OAAO,EAAA,CAAG,QAAQ,YAAY,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAG,MAAM,CAAA;AAClB;AAcO,SAAS,aAAA,CACd,MAAA,EACA,OAAA,GAAkC,EAAC,EAChC;AACH,EAAA,MAAM,gBAAA,GAAmB,QAAQ,gBAAA,IAAoB,GAAA;AAErD,EAAA,MAAM,aAAA,GACJ,OAAO,MAAA,CAAO,SAAA,KAAc,aACxB,MAAA,CAAO,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA,GAC5B,MAAA;AACN,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAEhD,EAAA,MAAM,gBAAA,GAAmB,aAAA,GACrB,OAAO,MAAA,EAAkB,cAAA,KACvB,IAAA;AAAA,IACE,gBAAA;AAAA,IACA,YAAY;AACV,MAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,QAAA,OACE,aAAA,CAIA,QAAQ,cAAc,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,cAAc,MAAM,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA;AAAA,MACE,IAAA,EAAM,MAAA;AAAA,MACN,QAAA,EAAU,aAAa,OAAA,EAAS;AAAA,QAC9B,QAAA,EAAU,YAAA;AAAA,QACV,UAAA,EAAY,cAAA,CAAe,OAAA,CAAQ,gBAAgB;AAAA,OACpD;AAAA;AACH,GACF,GACF,MAAA;AAEJ,EAAA,MAAM,eAAA,GAAkB,OACtB,MAAA,EACA,qBAAA,EACA,YAAA,KACG;AACH,IAAA,MAAM,EAAE,YAAA,EAAc,cAAA,EAAgB,YAAA,EAAa,GAAI,mBAAA;AAAA,MACrD,qBAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO,IAAA;AAAA,MACL,CAAA,IAAA,EAAO,OAAO,IAAI,CAAA,CAAA;AAAA,MAClB,YACE,cAAA,CAAe,YAAA,EAAc,MAAA,EAAQ,cAAc,cAAc,CAAA;AAAA,MACnE;AAAA,QACE,IAAA,EAAM,MAAA;AAAA,QACN,QAAA,EAAU,aAAa,OAAA,EAAS;AAAA,UAC9B,UAAU,MAAA,CAAO,IAAA;AAAA,UACjB,UAAA,EAAY,cAAA,CAAe,OAAA,CAAQ,gBAAgB,CAAA;AAAA,UACnD,eAAA,EAAiB,iBAAA;AAAA,YACf,MAAA,CAAO,aAAa,EAAC;AAAA,YACrB;AAAA,WACF;AAAA,UACA,GAAG;AAAA,SACJ;AAAA;AACH,KACF;AAAA,EACF,CAAA;AAEA,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU;AAC9B,MAAA,IAAI,QAAA,KAAa,WAAA,IAAe,gBAAA,KAAqB,MAAA,EAAW;AAC9D,QAAA,OAAO,gBAAA;AAAA,MACT;AACA,MAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,QAAA,OAAO,eAAA;AAAA,MACT;AACA,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,UAAU,QAAQ,CAAA;AACpD,MAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC/B,QAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,MAC1B;AACA,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,GACD,CAAA;AACH;AAGO,SAAS,2BAAA,GAAoC;AAClD,EAAA,eAAA,GAAkB,CAAA;AACpB","file":"index.mjs","sourcesContent":["const DEFAULT_MAX_SUMMARY_LENGTH = 240;\n\nfunction fallbackString(value: unknown): string {\n try {\n return String(value);\n } catch {\n return \"[unserializable]\";\n }\n}\n\nexport function summarizeMcpValue(\n value: unknown,\n maxLength = DEFAULT_MAX_SUMMARY_LENGTH,\n): string {\n let text: string;\n try {\n if (typeof value === \"string\") {\n text = value;\n } else {\n // JSON.stringify returns undefined (not a string) for undefined,\n // functions, and symbols; falling through with undefined would crash\n // instrumentation at text.length below.\n const serialized = JSON.stringify(value);\n text = serialized === undefined ? fallbackString(value) : serialized;\n }\n } catch {\n text = fallbackString(value);\n }\n if (text.length <= maxLength) return text;\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\nexport function hashServerUrl(url: string): string {\n let hash = 0;\n for (let i = 0; i < url.length; i += 1) {\n hash = (hash * 31 + url.charCodeAt(i)) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n","import { step } from \"agent-inspect\";\n\nimport { hashServerUrl, summarizeMcpValue } from \"./summarize.js\";\nimport type {\n McpClientLike,\n McpClientTracerOptions,\n McpRequestOptions,\n McpTraceMetadata,\n} from \"./types.js\";\n\nlet toolCallCounter = 0;\n\nfunction nextToolCallId(prefix?: string): string {\n toolCallCounter += 1;\n const base = prefix?.trim() || \"mcp\";\n return `${base}-${toolCallCounter}`;\n}\n\nfunction baseMetadata(\n options: McpClientTracerOptions,\n overrides: Partial<McpTraceMetadata> = {},\n): Record<string, unknown> {\n const metadata: McpTraceMetadata = {\n source: { type: \"mcp-client\" },\n ...(options.serverName ? { mcpServerName: options.serverName } : {}),\n ...(options.serverUrl\n ? { mcpServerUrlHash: hashServerUrl(options.serverUrl) }\n : {}),\n ...(options.sessionId ? { sessionId: options.sessionId } : {}),\n ...overrides,\n };\n return { ...(options.metadata ?? {}), ...metadata };\n}\n\n/** SDK RequestOptions keys — must never be swallowed as AgentInspect metadata. */\nconst SDK_REQUEST_OPTION_KEYS = [\n \"signal\",\n \"timeout\",\n \"onprogress\",\n \"resetTimeoutOnProgress\",\n \"maxTotalTimeout\",\n \"relatedRequestId\",\n \"resumptionToken\",\n \"onresumptiontoken\",\n] as const;\n\nfunction isSdkRequestOptions(value: unknown): value is McpRequestOptions {\n if (!value || typeof value !== \"object\") return false;\n const obj = value as Record<string, unknown>;\n return SDK_REQUEST_OPTION_KEYS.some((key) => key in obj);\n}\n\n/**\n * AgentInspect per-call metadata bag: `{ metadata: {...} }` without SDK option keys.\n * Must not consume ordinary SDK RequestOptions that happen to be objects.\n */\nfunction isAgentInspectMetadataBag(\n value: unknown,\n): value is { metadata?: Record<string, unknown> } {\n if (!value || typeof value !== \"object\") return false;\n if (isSdkRequestOptions(value)) return false;\n const obj = value as Record<string, unknown>;\n if (!(\"metadata\" in obj)) return false;\n // Zod/result schemas expose parse — never treat those as AI bags.\n if (\"parse\" in obj) return false;\n return true;\n}\n\nfunction extractCallMetadata(bag: {\n metadata?: Record<string, unknown>;\n}): Record<string, unknown> {\n if (bag.metadata && typeof bag.metadata === \"object\") {\n return bag.metadata;\n }\n return {};\n}\n\n/** Peel AgentInspect `metadata` without consuming SDK RequestOptions keys. */\nfunction peelOptionsObject(value: unknown): {\n callMetadata: Record<string, unknown>;\n requestOptions: McpRequestOptions | undefined;\n} {\n if (value === null || value === undefined) {\n return { callMetadata: {}, requestOptions: undefined };\n }\n if (typeof value !== \"object\") {\n return { callMetadata: {}, requestOptions: undefined };\n }\n const obj = value as Record<string, unknown>;\n const callMetadata = extractCallMetadata(obj);\n\n // Pure AI bag — do not forward as SDK RequestOptions.\n if (isAgentInspectMetadataBag(value)) {\n return { callMetadata, requestOptions: undefined };\n }\n\n if (isSdkRequestOptions(value) || Object.keys(obj).length > 0) {\n const { metadata: _ignored, ...rest } = obj;\n return {\n callMetadata,\n requestOptions: rest as McpRequestOptions,\n };\n }\n\n return { callMetadata, requestOptions: undefined };\n}\n\n/**\n * Resolve SDK callTool arity:\n * callTool(params, resultSchema?, requestOptions?)\n * plus AgentInspect overloads that peel `{ metadata }` without dropping RequestOptions.\n * Composed `{ timeout, metadata: { operationId, attemptId } }` keeps both sides.\n */\nexport function resolveCallToolArgs(\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n): {\n resultSchema: unknown;\n requestOptions: McpRequestOptions | undefined;\n callMetadata: Record<string, unknown>;\n} {\n // Three-arg form: (params, schema|undefined, options)\n if (maybeOptions !== undefined) {\n const peeled = peelOptionsObject(maybeOptions);\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions: peeled.requestOptions,\n callMetadata: peeled.callMetadata,\n };\n }\n\n // Two-arg form: (params, schema) OR (params, { metadata }) OR (params, RequestOptions)\n if (isAgentInspectMetadataBag(resultSchemaOrOptions)) {\n return {\n resultSchema: undefined,\n requestOptions: undefined,\n callMetadata: extractCallMetadata(resultSchemaOrOptions),\n };\n }\n\n if (isSdkRequestOptions(resultSchemaOrOptions)) {\n const peeled = peelOptionsObject(resultSchemaOrOptions);\n return {\n resultSchema: undefined,\n requestOptions: peeled.requestOptions,\n callMetadata: peeled.callMetadata,\n };\n }\n\n return {\n resultSchema: resultSchemaOrOptions,\n requestOptions: undefined,\n callMetadata: {},\n };\n}\n\nfunction invokeCallTool(\n callToolImpl: McpClientLike[\"callTool\"],\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchema: unknown,\n requestOptions: McpRequestOptions | undefined,\n): Promise<unknown> {\n const fn = callToolImpl as (\n p: unknown,\n schema?: unknown,\n opts?: unknown,\n ) => Promise<unknown>;\n if (requestOptions !== undefined) {\n return fn(params, resultSchema, requestOptions);\n }\n if (resultSchema !== undefined) {\n return fn(params, resultSchema);\n }\n return fn(params);\n}\n\n/**\n * Wraps an MCP client so tools/list and tools/call emit local tool steps.\n * Telemetry only — does not proxy network behavior beyond the wrapped client.\n *\n * Uses a Proxy over the original client so prototype methods (`connect`,\n * `close`, `listResources`, …), private SDK state, and `instanceof` stay intact.\n * A shallow object spread would drop prototype methods and copy private fields.\n *\n * Forwards the real SDK argument positions, including `RequestOptions`\n * (`signal`, `timeout`, progress callbacks). Does not fake cancellation while\n * still dispatching the underlying request.\n */\nexport function wrapMcpClient<T extends McpClientLike>(\n client: T,\n options: McpClientTracerOptions = {},\n): T {\n const maxSummaryLength = options.maxSummaryLength ?? 240;\n\n const listToolsImpl =\n typeof client.listTools === \"function\"\n ? client.listTools.bind(client)\n : undefined;\n const callToolImpl = client.callTool.bind(client);\n\n const wrappedListTools = listToolsImpl\n ? async (params?: unknown, requestOptions?: McpRequestOptions) =>\n step(\n \"mcp:tools/list\",\n async () => {\n if (requestOptions !== undefined) {\n return (\n listToolsImpl as (\n p?: unknown,\n opts?: unknown,\n ) => Promise<unknown>\n )(params, requestOptions);\n }\n return listToolsImpl(params);\n },\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: \"tools/list\",\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n }),\n },\n )\n : undefined;\n\n const wrappedCallTool = async (\n params: Parameters<McpClientLike[\"callTool\"]>[0],\n resultSchemaOrOptions?: unknown,\n maybeOptions?: unknown,\n ) => {\n const { resultSchema, requestOptions, callMetadata } = resolveCallToolArgs(\n resultSchemaOrOptions,\n maybeOptions,\n );\n\n return step(\n `mcp:${params.name}`,\n async () =>\n invokeCallTool(callToolImpl, params, resultSchema, requestOptions),\n {\n type: \"tool\",\n metadata: baseMetadata(options, {\n toolName: params.name,\n toolCallId: nextToolCallId(options.toolCallIdPrefix),\n argumentSummary: summarizeMcpValue(\n params.arguments ?? {},\n maxSummaryLength,\n ),\n ...callMetadata,\n }),\n },\n );\n };\n\n return new Proxy(client, {\n get(target, property, receiver) {\n if (property === \"listTools\" && wrappedListTools !== undefined) {\n return wrappedListTools;\n }\n if (property === \"callTool\") {\n return wrappedCallTool;\n }\n const value = Reflect.get(target, property, receiver);\n if (typeof value === \"function\") {\n return value.bind(target);\n }\n return value;\n },\n }) as T;\n}\n\n/** @internal resets tool call ids for deterministic tests */\nexport function resetMcpToolCallIdsForTests(): void {\n toolCallCounter = 0;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-inspect/mcp",
3
- "version": "6.31.20",
3
+ "version": "6.31.21",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Local MCP client tool-call tracing for AgentInspect",
@@ -35,7 +35,7 @@
35
35
  "dist"
36
36
  ],
37
37
  "dependencies": {
38
- "agent-inspect": "6.31.20"
38
+ "agent-inspect": "6.31.21"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"