@posthog/mcp 0.10.2 → 0.10.3

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.
@@ -0,0 +1,12 @@
1
+ export interface AnalyticsInjectableJsonSchema {
2
+ additionalProperties?: boolean;
3
+ allOf?: unknown;
4
+ anyOf?: unknown;
5
+ oneOf?: unknown;
6
+ properties?: Record<string, unknown>;
7
+ required?: string[];
8
+ type?: string;
9
+ }
10
+ export declare function hasAnalyticsParameter(schema: AnalyticsInjectableJsonSchema | undefined, parameterName: string): boolean;
11
+ export declare function canInjectAnalyticsParameter(schema: AnalyticsInjectableJsonSchema | undefined, parameterName: string): boolean;
12
+ //# sourceMappingURL=analytics-parameters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/analytics-parameters.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,6BAA6B;IAC5C,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,aAAa,EAAE,MAAM,GACpB,OAAO,CAET"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ canInjectAnalyticsParameter: ()=>canInjectAnalyticsParameter,
28
+ hasAnalyticsParameter: ()=>hasAnalyticsParameter
29
+ });
30
+ function hasAnalyticsParameter(schema, parameterName) {
31
+ return !!schema?.properties && Object.prototype.hasOwnProperty.call(schema.properties, parameterName);
32
+ }
33
+ function canInjectAnalyticsParameter(schema, parameterName) {
34
+ return !hasAnalyticsParameter(schema, parameterName) && !schema?.oneOf && !schema?.allOf && !schema?.anyOf;
35
+ }
36
+ exports.canInjectAnalyticsParameter = __webpack_exports__.canInjectAnalyticsParameter;
37
+ exports.hasAnalyticsParameter = __webpack_exports__.hasAnalyticsParameter;
38
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
39
+ "canInjectAnalyticsParameter",
40
+ "hasAnalyticsParameter"
41
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
42
+ Object.defineProperty(exports, '__esModule', {
43
+ value: true
44
+ });
@@ -0,0 +1,7 @@
1
+ function hasAnalyticsParameter(schema, parameterName) {
2
+ return !!schema?.properties && Object.prototype.hasOwnProperty.call(schema.properties, parameterName);
3
+ }
4
+ function canInjectAnalyticsParameter(schema, parameterName) {
5
+ return !hasAnalyticsParameter(schema, parameterName) && !schema?.oneOf && !schema?.allOf && !schema?.anyOf;
6
+ }
7
+ export { canInjectAnalyticsParameter, hasAnalyticsParameter };
@@ -1,15 +1,7 @@
1
1
  import type { MCPAnalyticsOptions } from '../types';
2
- interface JsonSchema {
3
- additionalProperties?: boolean;
4
- allOf?: unknown;
5
- anyOf?: unknown;
6
- oneOf?: unknown;
7
- properties?: Record<string, unknown>;
8
- required?: string[];
9
- type?: string;
10
- }
2
+ import { type AnalyticsInjectableJsonSchema } from './analytics-parameters';
11
3
  export interface ContextInjectableTool {
12
- inputSchema?: JsonSchema;
4
+ inputSchema?: AnalyticsInjectableJsonSchema;
13
5
  name?: string;
14
6
  [key: string]: unknown;
15
7
  }
@@ -27,5 +19,4 @@ export declare function getContextDescription(context: MCPAnalyticsOptions['cont
27
19
  */
28
20
  export declare function addContextParameterToTool<TTool extends ContextInjectableTool>(tool: TTool, contextDescriptionOverride?: string): TTool;
29
21
  export declare function addContextParameterToTools<TTool extends ContextInjectableTool>(tools: TTool[], contextDescriptionOverride?: string): TTool[];
30
- export {};
31
22
  //# sourceMappingURL=context-parameters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/context-parameters.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAInD,UAAU,UAAU;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,OAAO,CAEjF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAEjG;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,SAAS,qBAAqB,EAC3E,IAAI,EAAE,KAAK,EACX,0BAA0B,CAAC,EAAE,MAAM,GAClC,KAAK,CAgEP;AAED,wBAAgB,0BAA0B,CAAC,KAAK,SAAS,qBAAqB,EAC5E,KAAK,EAAE,KAAK,EAAE,EACd,0BAA0B,CAAC,EAAE,MAAM,GAClC,KAAK,EAAE,CAQT"}
1
+ {"version":3,"file":"context-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/context-parameters.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAGL,KAAK,6BAA6B,EACnC,MAAM,wBAAwB,CAAA;AAI/B,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,6BAA6B,CAAA;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,OAAO,CAEjF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAEjG;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,SAAS,qBAAqB,EAC3E,IAAI,EAAE,KAAK,EACX,0BAA0B,CAAC,EAAE,MAAM,GAClC,KAAK,CA6DP;AAED,wBAAgB,0BAA0B,CAAC,KAAK,SAAS,qBAAqB,EAC5E,KAAK,EAAE,KAAK,EAAE,EACd,0BAA0B,CAAC,EAAE,MAAM,GAClC,KAAK,EAAE,CAQT"}
@@ -29,6 +29,7 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  getContextDescription: ()=>getContextDescription,
30
30
  isContextEnabled: ()=>isContextEnabled
31
31
  });
32
+ const external_analytics_parameters_js_namespaceObject = require("./analytics-parameters.js");
32
33
  const external_constants_js_namespaceObject = require("./constants.js");
33
34
  const external_logger_js_namespaceObject = require("./logger.js");
34
35
  function isContextEnabled(context) {
@@ -43,12 +44,9 @@ function addContextParameterToTool(tool, contextDescriptionOverride) {
43
44
  };
44
45
  const toolName = tool.name || 'unknown';
45
46
  const schema = modifiedTool.inputSchema;
46
- if (schema?.properties?.context) {
47
- (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" already has 'context' parameter. Skipping context injection.`);
48
- return modifiedTool;
49
- }
50
- if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
51
- (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping context injection.`);
47
+ if (!(0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)(schema, 'context')) {
48
+ if ((0, external_analytics_parameters_js_namespaceObject.hasAnalyticsParameter)(schema, 'context')) (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" already has 'context' parameter. Skipping context injection.`);
49
+ else (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping context injection.`);
52
50
  return modifiedTool;
53
51
  }
54
52
  if (!modifiedTool.inputSchema) modifiedTool.inputSchema = {
@@ -1,3 +1,4 @@
1
+ import { canInjectAnalyticsParameter, hasAnalyticsParameter } from "./analytics-parameters.mjs";
1
2
  import { DEFAULT_CONTEXT_PARAMETER_DESCRIPTION } from "./constants.mjs";
2
3
  import { log } from "./logger.mjs";
3
4
  function isContextEnabled(context) {
@@ -12,12 +13,8 @@ function addContextParameterToTool(tool, contextDescriptionOverride) {
12
13
  };
13
14
  const toolName = tool.name || 'unknown';
14
15
  const schema = modifiedTool.inputSchema;
15
- if (schema?.properties?.context) {
16
- log(`WARN: Tool "${toolName}" already has 'context' parameter. Skipping context injection.`);
17
- return modifiedTool;
18
- }
19
- if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
20
- log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping context injection.`);
16
+ if (!canInjectAnalyticsParameter(schema, 'context')) {
17
+ hasAnalyticsParameter(schema, 'context') ? log(`WARN: Tool "${toolName}" already has 'context' parameter. Skipping context injection.`) : log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping context injection.`);
21
18
  return modifiedTool;
22
19
  }
23
20
  if (!modifiedTool.inputSchema) modifiedTool.inputSchema = {
@@ -1,15 +1,7 @@
1
+ import { type AnalyticsInjectableJsonSchema } from './analytics-parameters';
1
2
  export declare const CONVERSATION_ID_PARAM_NAME = "conversation_id";
2
- interface JsonSchema {
3
- additionalProperties?: boolean;
4
- allOf?: unknown;
5
- anyOf?: unknown;
6
- oneOf?: unknown;
7
- properties?: Record<string, unknown>;
8
- required?: string[];
9
- type?: string;
10
- }
11
3
  export interface ConversationIdInjectableTool {
12
- inputSchema?: JsonSchema;
4
+ inputSchema?: AnalyticsInjectableJsonSchema;
13
5
  name?: string;
14
6
  [key: string]: unknown;
15
7
  }
@@ -48,5 +40,4 @@ export declare function buildConversationIdPromptBack(conversationId: string): {
48
40
  text: string;
49
41
  };
50
42
  export declare function injectConversationIdPromptBack(result: unknown, conversationId: string): unknown;
51
- export {};
52
43
  //# sourceMappingURL=conversation-id.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-id.d.ts","sourceRoot":"","sources":["../../src/extensions/conversation-id.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D,UAAU,UAAU;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,4BAA4B,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CA2CtG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,4BAA4B,EACjF,KAAK,EAAE,KAAK,EAAE,EACd,yBAAyB,GAAE,MAA4B,GACtD,KAAK,EAAE,CAOT;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,yBAAyB,GAAE,MAA4B,GACtD,wBAAwB,CAS1B;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAS1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,SAAS;IAAE,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAAE,EAC3E,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAe7B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAM1D;AAED,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAKA;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAS/F"}
1
+ {"version":3,"file":"conversation-id.d.ts","sourceRoot":"","sources":["../../src/extensions/conversation-id.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,6BAA6B,EACnC,MAAM,wBAAwB,CAAA;AAK/B,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,6BAA6B,CAAA;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,4BAA4B,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CA0CtG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,4BAA4B,EACjF,KAAK,EAAE,KAAK,EAAE,EACd,yBAAyB,GAAE,MAA4B,GACtD,KAAK,EAAE,CAOT;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,yBAAyB,GAAE,MAA4B,GACtD,wBAAwB,CAS1B;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAS1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,SAAS;IAAE,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAAE,EAC3E,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAe7B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAM1D;AAED,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAKA;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAS/F"}
@@ -36,6 +36,7 @@ __webpack_require__.d(__webpack_exports__, {
36
36
  canInjectConversationIdPromptBack: ()=>canInjectConversationIdPromptBack
37
37
  });
38
38
  const core_namespaceObject = require("@posthog/core");
39
+ const external_analytics_parameters_js_namespaceObject = require("./analytics-parameters.js");
39
40
  const external_constants_js_namespaceObject = require("./constants.js");
40
41
  const external_logger_js_namespaceObject = require("./logger.js");
41
42
  const external_tools_js_namespaceObject = require("./tools.js");
@@ -46,12 +47,9 @@ function addConversationIdToTool(tool) {
46
47
  };
47
48
  const toolName = tool.name || 'unknown';
48
49
  const schema = modifiedTool.inputSchema;
49
- if (schema?.properties?.[CONVERSATION_ID_PARAM_NAME]) {
50
- (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`);
51
- return modifiedTool;
52
- }
53
- if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
54
- (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`);
50
+ if (!(0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)(schema, CONVERSATION_ID_PARAM_NAME)) {
51
+ if ((0, external_analytics_parameters_js_namespaceObject.hasAnalyticsParameter)(schema, CONVERSATION_ID_PARAM_NAME)) (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`);
52
+ else (0, external_logger_js_namespaceObject.log)(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`);
55
53
  return modifiedTool;
56
54
  }
57
55
  if (!modifiedTool.inputSchema) modifiedTool.inputSchema = {
@@ -1,4 +1,5 @@
1
1
  import { uuidv7 } from "@posthog/core";
2
+ import { canInjectAnalyticsParameter, hasAnalyticsParameter } from "./analytics-parameters.mjs";
2
3
  import { DEFAULT_CONVERSATION_ID_DESCRIPTION } from "./constants.mjs";
3
4
  import { log } from "./logger.mjs";
4
5
  import { GET_MORE_TOOLS_NAME } from "./tools.mjs";
@@ -9,12 +10,8 @@ function addConversationIdToTool(tool) {
9
10
  };
10
11
  const toolName = tool.name || 'unknown';
11
12
  const schema = modifiedTool.inputSchema;
12
- if (schema?.properties?.[CONVERSATION_ID_PARAM_NAME]) {
13
- log(`WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`);
14
- return modifiedTool;
15
- }
16
- if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
17
- log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`);
13
+ if (!canInjectAnalyticsParameter(schema, CONVERSATION_ID_PARAM_NAME)) {
14
+ hasAnalyticsParameter(schema, CONVERSATION_ID_PARAM_NAME) ? log(`WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`) : log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`);
18
15
  return modifiedTool;
19
16
  }
20
17
  if (!modifiedTool.inputSchema) modifiedTool.inputSchema = {
@@ -1 +1 @@
1
- {"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,sBAAsB,EAIvB,MAAM,UAAU,CAAA;AAqPjB,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAwB9E"}
1
+ {"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,sBAAsB,EAIvB,MAAM,UAAU,CAAA;AAsSjB,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAwB9E"}
@@ -26,7 +26,9 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  instrumentHighLevelServer: ()=>instrumentHighLevelServer
28
28
  });
29
+ const external_analytics_parameters_js_namespaceObject = require("./analytics-parameters.js");
29
30
  const external_conversation_id_js_namespaceObject = require("./conversation-id.js");
31
+ const external_context_parameters_js_namespaceObject = require("./context-parameters.js");
30
32
  const external_event_types_js_namespaceObject = require("./event-types.js");
31
33
  const external_internal_js_namespaceObject = require("./internal.js");
32
34
  const external_logger_js_namespaceObject = require("./logger.js");
@@ -39,6 +41,27 @@ const MCP_ANALYTICS_PROCESSED = Symbol('__posthog_mcp_analytics_processed__');
39
41
  function isCallbackUpdate(value) {
40
42
  return !!value && 'object' == typeof value && 'callback' in value && 'function' == typeof value.callback;
41
43
  }
44
+ function analyticsOwnsParameter(inputSchema, parameterName) {
45
+ if (!inputSchema || 'object' != typeof inputSchema) return (0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)(void 0, parameterName);
46
+ if ((0, external_mcp_sdk_compat_js_namespaceObject.isZodRawShapeCompat)(inputSchema)) return (0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)({
47
+ properties: inputSchema
48
+ }, parameterName);
49
+ const shape = (0, external_mcp_sdk_compat_js_namespaceObject.getObjectShape)(inputSchema);
50
+ if (shape) return (0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)({
51
+ properties: shape
52
+ }, parameterName);
53
+ const schema = inputSchema;
54
+ if ('_def' in schema || '_zod' in schema || '~standard' in schema) return (0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)(void 0, parameterName);
55
+ return (0, external_analytics_parameters_js_namespaceObject.canInjectAnalyticsParameter)(schema, parameterName);
56
+ }
57
+ function stripOwnedAnalyticsArguments(args, ownership) {
58
+ let cleanedArgs = args;
59
+ if (ownership.context && cleanedArgs && 'object' == typeof cleanedArgs && 'context' in cleanedArgs) {
60
+ const { context: _context, ...rest } = cleanedArgs;
61
+ cleanedArgs = rest;
62
+ }
63
+ return ownership.conversationId ? (0, external_conversation_id_js_namespaceObject.stripConversationId)(cleanedArgs) : cleanedArgs;
64
+ }
42
65
  function addTracingToToolRegistry(tools, server) {
43
66
  return Object.fromEntries(Object.entries(tools).map(([name, tool])=>[
44
67
  name,
@@ -62,7 +85,8 @@ function setupListenerToRegisteredTools(server) {
62
85
  (0, external_logger_js_namespaceObject.log)(`Tool ${String(property)} callback already wrapped, skipping proxy wrapping`);
63
86
  return Reflect.set(target, property, value);
64
87
  }
65
- const nextValue = addTracingToToolCallbackInternal(value, property, server);
88
+ const getCurrentInputSchema = ()=>value.inputSchema;
89
+ const nextValue = addTracingToToolCallbackInternal(value, property, server, getCurrentInputSchema);
66
90
  if ('function' == typeof nextValue.update) {
67
91
  const originalUpdate = nextValue.update;
68
92
  nextValue.update = function(...updateArgs) {
@@ -71,7 +95,7 @@ function setupListenerToRegisteredTools(server) {
71
95
  if (isCallbackUpdate(updateObj)) {
72
96
  const wrappedTool = addTracingToToolCallbackInternal({
73
97
  callback: updateObj.callback
74
- }, property, server);
98
+ }, property, server, getCurrentInputSchema);
75
99
  updateObj.callback = (0, external_mcp_sdk_compat_js_namespaceObject.getToolFunction)(wrappedTool);
76
100
  }
77
101
  }
@@ -103,9 +127,10 @@ function setupListenerToRegisteredTools(server) {
103
127
  (0, external_logger_js_namespaceObject.log)(`Warning: Failed to setup listener for registered tools - ${error}`);
104
128
  }
105
129
  }
106
- function addTracingToToolCallbackInternal(tool, toolName, server) {
130
+ function addTracingToToolCallbackInternal(tool, toolName, server, getCurrentInputSchema = ()=>tool.inputSchema) {
107
131
  const originalCallback = (0, external_mcp_sdk_compat_js_namespaceObject.getToolFunction)(tool);
108
- const missingToolName = (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)((0, external_internal_js_namespaceObject.getServerTrackingData)(server.server)?.options);
132
+ const options = (0, external_internal_js_namespaceObject.getServerTrackingData)(server.server)?.options;
133
+ const missingToolName = (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(options);
109
134
  if (wrappedCallbacks.has(originalCallback)) {
110
135
  (0, external_logger_js_namespaceObject.log)(`Tool ${toolName} callback already wrapped, skipping re-wrap`);
111
136
  return tool;
@@ -124,14 +149,11 @@ function addTracingToToolCallbackInternal(tool, toolName, server) {
124
149
  args = void 0;
125
150
  extra = params[0];
126
151
  }
127
- const removeContextFromArgs = (input)=>{
128
- if (input && 'object' == typeof input && 'context' in input) {
129
- const { context: _context, ...rest } = input;
130
- return rest;
131
- }
132
- return input;
133
- };
134
- const cleanedArgs = toolName === missingToolName ? args : (0, external_conversation_id_js_namespaceObject.stripConversationId)(removeContextFromArgs(args));
152
+ const inputSchema = getCurrentInputSchema();
153
+ const cleanedArgs = stripOwnedAnalyticsArguments(args, {
154
+ context: toolName !== missingToolName && (0, external_context_parameters_js_namespaceObject.isContextEnabled)(options?.context) && analyticsOwnsParameter(inputSchema, 'context'),
155
+ conversationId: toolName !== missingToolName && options?.enableConversationId === true && analyticsOwnsParameter(inputSchema, 'conversation_id')
156
+ });
135
157
  try {
136
158
  if (void 0 === cleanedArgs) {
137
159
  const handler = originalCallback;
@@ -1,8 +1,10 @@
1
+ import { canInjectAnalyticsParameter } from "./analytics-parameters.mjs";
1
2
  import { stripConversationId } from "./conversation-id.mjs";
3
+ import { isContextEnabled } from "./context-parameters.mjs";
2
4
  import { MCPAnalyticsEventType } from "./event-types.mjs";
3
5
  import { getServerTrackingData } from "./internal.mjs";
4
6
  import { log } from "./logger.mjs";
5
- import { createWrappedTool, getToolFunction, hasToolFunction } from "./mcp-sdk-compat.mjs";
7
+ import { createWrappedTool, getObjectShape, getToolFunction, hasToolFunction, isZodRawShapeCompat } from "./mcp-sdk-compat.mjs";
6
8
  import { handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
7
9
  import { captureToolCall, handleInitializeRequest, handleListToolsRequest, patchRequestHandlers, readToolMetaCategory } from "./instrumentation.mjs";
8
10
  import { getContextArgument } from "./tracing-helpers.mjs";
@@ -11,6 +13,27 @@ const MCP_ANALYTICS_PROCESSED = Symbol('__posthog_mcp_analytics_processed__');
11
13
  function isCallbackUpdate(value) {
12
14
  return !!value && 'object' == typeof value && 'callback' in value && 'function' == typeof value.callback;
13
15
  }
16
+ function analyticsOwnsParameter(inputSchema, parameterName) {
17
+ if (!inputSchema || 'object' != typeof inputSchema) return canInjectAnalyticsParameter(void 0, parameterName);
18
+ if (isZodRawShapeCompat(inputSchema)) return canInjectAnalyticsParameter({
19
+ properties: inputSchema
20
+ }, parameterName);
21
+ const shape = getObjectShape(inputSchema);
22
+ if (shape) return canInjectAnalyticsParameter({
23
+ properties: shape
24
+ }, parameterName);
25
+ const schema = inputSchema;
26
+ if ('_def' in schema || '_zod' in schema || '~standard' in schema) return canInjectAnalyticsParameter(void 0, parameterName);
27
+ return canInjectAnalyticsParameter(schema, parameterName);
28
+ }
29
+ function stripOwnedAnalyticsArguments(args, ownership) {
30
+ let cleanedArgs = args;
31
+ if (ownership.context && cleanedArgs && 'object' == typeof cleanedArgs && 'context' in cleanedArgs) {
32
+ const { context: _context, ...rest } = cleanedArgs;
33
+ cleanedArgs = rest;
34
+ }
35
+ return ownership.conversationId ? stripConversationId(cleanedArgs) : cleanedArgs;
36
+ }
14
37
  function addTracingToToolRegistry(tools, server) {
15
38
  return Object.fromEntries(Object.entries(tools).map(([name, tool])=>[
16
39
  name,
@@ -34,7 +57,8 @@ function setupListenerToRegisteredTools(server) {
34
57
  log(`Tool ${String(property)} callback already wrapped, skipping proxy wrapping`);
35
58
  return Reflect.set(target, property, value);
36
59
  }
37
- const nextValue = addTracingToToolCallbackInternal(value, property, server);
60
+ const getCurrentInputSchema = ()=>value.inputSchema;
61
+ const nextValue = addTracingToToolCallbackInternal(value, property, server, getCurrentInputSchema);
38
62
  if ('function' == typeof nextValue.update) {
39
63
  const originalUpdate = nextValue.update;
40
64
  nextValue.update = function(...updateArgs) {
@@ -43,7 +67,7 @@ function setupListenerToRegisteredTools(server) {
43
67
  if (isCallbackUpdate(updateObj)) {
44
68
  const wrappedTool = addTracingToToolCallbackInternal({
45
69
  callback: updateObj.callback
46
- }, property, server);
70
+ }, property, server, getCurrentInputSchema);
47
71
  updateObj.callback = getToolFunction(wrappedTool);
48
72
  }
49
73
  }
@@ -75,9 +99,10 @@ function setupListenerToRegisteredTools(server) {
75
99
  log(`Warning: Failed to setup listener for registered tools - ${error}`);
76
100
  }
77
101
  }
78
- function addTracingToToolCallbackInternal(tool, toolName, server) {
102
+ function addTracingToToolCallbackInternal(tool, toolName, server, getCurrentInputSchema = ()=>tool.inputSchema) {
79
103
  const originalCallback = getToolFunction(tool);
80
- const missingToolName = resolveMissingCapabilityToolName(getServerTrackingData(server.server)?.options);
104
+ const options = getServerTrackingData(server.server)?.options;
105
+ const missingToolName = resolveMissingCapabilityToolName(options);
81
106
  if (wrappedCallbacks.has(originalCallback)) {
82
107
  log(`Tool ${toolName} callback already wrapped, skipping re-wrap`);
83
108
  return tool;
@@ -96,14 +121,11 @@ function addTracingToToolCallbackInternal(tool, toolName, server) {
96
121
  args = void 0;
97
122
  extra = params[0];
98
123
  }
99
- const removeContextFromArgs = (input)=>{
100
- if (input && 'object' == typeof input && 'context' in input) {
101
- const { context: _context, ...rest } = input;
102
- return rest;
103
- }
104
- return input;
105
- };
106
- const cleanedArgs = toolName === missingToolName ? args : stripConversationId(removeContextFromArgs(args));
124
+ const inputSchema = getCurrentInputSchema();
125
+ const cleanedArgs = stripOwnedAnalyticsArguments(args, {
126
+ context: toolName !== missingToolName && isContextEnabled(options?.context) && analyticsOwnsParameter(inputSchema, 'context'),
127
+ conversationId: toolName !== missingToolName && options?.enableConversationId === true && analyticsOwnsParameter(inputSchema, 'conversation_id')
128
+ });
107
129
  try {
108
130
  if (void 0 === cleanedArgs) {
109
131
  const handler = originalCallback;
@@ -28,6 +28,7 @@ export declare function hasToolFunction(tool: unknown): tool is RegisteredTool;
28
28
  */
29
29
  export declare function createWrappedTool(originalTool: RegisteredTool, wrappedFunction: ToolCallback): RegisteredTool;
30
30
  export declare function isZ4Schema(schema: unknown): boolean;
31
+ export declare function isZodRawShapeCompat(schema: unknown): schema is Record<string, unknown>;
31
32
  export declare function getObjectShape(schema: unknown): Record<string, unknown> | undefined;
32
33
  export declare function getLiteralValue(schema: unknown): unknown;
33
34
  //# sourceMappingURL=mcp-sdk-compat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-sdk-compat.d.ts","sourceRoot":"","sources":["../../src/extensions/mcp-sdk-compat.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAK5D,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,CAAA;AAEpD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,CAQlE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,CAKxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,cAAc,CAMrE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,GAAG,cAAc,CAM7G;AAyBD,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAKnD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CA6BnF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAkCxD"}
1
+ {"version":3,"file":"mcp-sdk-compat.d.ts","sourceRoot":"","sources":["../../src/extensions/mcp-sdk-compat.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAK5D,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,CAAA;AAEpD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,CAQlE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,CAKxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,cAAc,CAMrE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,GAAG,cAAc,CAM7G;AAyBD,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAKnD;AAaD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEtF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CA6BnF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAkCxD"}
@@ -30,7 +30,8 @@ __webpack_require__.d(__webpack_exports__, {
30
30
  getToolFunction: ()=>getToolFunction,
31
31
  getToolFunctionKey: ()=>getToolFunctionKey,
32
32
  hasToolFunction: ()=>hasToolFunction,
33
- isZ4Schema: ()=>isZ4Schema
33
+ isZ4Schema: ()=>isZ4Schema,
34
+ isZodRawShapeCompat: ()=>isZodRawShapeCompat
34
35
  });
35
36
  function getToolFunction(tool) {
36
37
  if ('handler' in tool && 'function' == typeof tool.handler) return tool.handler;
@@ -57,6 +58,12 @@ function isZ4Schema(schema) {
57
58
  if (!schema || 'object' != typeof schema) return false;
58
59
  return !!schema._zod;
59
60
  }
61
+ function isZodTypeLike(value) {
62
+ return !!value && 'object' == typeof value && 'parse' in value && 'function' == typeof value.parse && 'safeParse' in value && 'function' == typeof value.safeParse;
63
+ }
64
+ function isZodRawShapeCompat(schema) {
65
+ return !!schema && 'object' == typeof schema && Object.values(schema).some(isZodTypeLike);
66
+ }
60
67
  function getObjectShape(schema) {
61
68
  if (!schema || 'object' != typeof schema) return;
62
69
  let rawShape;
@@ -98,6 +105,7 @@ exports.getToolFunction = __webpack_exports__.getToolFunction;
98
105
  exports.getToolFunctionKey = __webpack_exports__.getToolFunctionKey;
99
106
  exports.hasToolFunction = __webpack_exports__.hasToolFunction;
100
107
  exports.isZ4Schema = __webpack_exports__.isZ4Schema;
108
+ exports.isZodRawShapeCompat = __webpack_exports__.isZodRawShapeCompat;
101
109
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
102
110
  "createWrappedTool",
103
111
  "getLiteralValue",
@@ -105,7 +113,8 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
105
113
  "getToolFunction",
106
114
  "getToolFunctionKey",
107
115
  "hasToolFunction",
108
- "isZ4Schema"
116
+ "isZ4Schema",
117
+ "isZodRawShapeCompat"
109
118
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
110
119
  Object.defineProperty(exports, '__esModule', {
111
120
  value: true
@@ -23,6 +23,12 @@ function isZ4Schema(schema) {
23
23
  if (!schema || 'object' != typeof schema) return false;
24
24
  return !!schema._zod;
25
25
  }
26
+ function isZodTypeLike(value) {
27
+ return !!value && 'object' == typeof value && 'parse' in value && 'function' == typeof value.parse && 'safeParse' in value && 'function' == typeof value.safeParse;
28
+ }
29
+ function isZodRawShapeCompat(schema) {
30
+ return !!schema && 'object' == typeof schema && Object.values(schema).some(isZodTypeLike);
31
+ }
26
32
  function getObjectShape(schema) {
27
33
  if (!schema || 'object' != typeof schema) return;
28
34
  let rawShape;
@@ -57,4 +63,4 @@ function getLiteralValue(schema) {
57
63
  const directValue = schema.value;
58
64
  if (void 0 !== directValue) return directValue;
59
65
  }
60
- export { createWrappedTool, getLiteralValue, getObjectShape, getToolFunction, getToolFunctionKey, hasToolFunction, isZ4Schema };
66
+ export { createWrappedTool, getLiteralValue, getObjectShape, getToolFunction, getToolFunctionKey, hasToolFunction, isZ4Schema, isZodRawShapeCompat };
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version = "0.10.2";
1
+ export declare const version = "0.10.3";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -26,7 +26,7 @@ __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
27
  version: ()=>version
28
28
  });
29
- const version = '0.10.2';
29
+ const version = '0.10.3';
30
30
  exports.version = __webpack_exports__.version;
31
31
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
32
32
  "version"
package/dist/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
- const version = '0.10.2';
1
+ const version = '0.10.3';
2
2
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/mcp",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "bugs": {
5
5
  "url": "https://github.com/PostHog/posthog-js/issues"
6
6
  },
@@ -28,7 +28,7 @@
28
28
  "module": "dist/index.mjs",
29
29
  "types": "dist/index.d.ts",
30
30
  "dependencies": {
31
- "@posthog/core": "^1.46.1"
31
+ "@posthog/core": "^1.46.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@babel/preset-env": "^7.27.1",
@@ -39,7 +39,7 @@
39
39
  "@types/node": "^20.0.0",
40
40
  "jest": "29.7.0",
41
41
  "zod": "^3.25.0",
42
- "posthog-node": "^5.47.2",
42
+ "posthog-node": "^5.47.4",
43
43
  "@posthog-tooling/tsconfig-base": "1.1.1"
44
44
  },
45
45
  "peerDependencies": {
@@ -0,0 +1,23 @@
1
+ export interface AnalyticsInjectableJsonSchema {
2
+ additionalProperties?: boolean
3
+ allOf?: unknown
4
+ anyOf?: unknown
5
+ oneOf?: unknown
6
+ properties?: Record<string, unknown>
7
+ required?: string[]
8
+ type?: string
9
+ }
10
+
11
+ export function hasAnalyticsParameter(
12
+ schema: AnalyticsInjectableJsonSchema | undefined,
13
+ parameterName: string
14
+ ): boolean {
15
+ return !!schema?.properties && Object.prototype.hasOwnProperty.call(schema.properties, parameterName)
16
+ }
17
+
18
+ export function canInjectAnalyticsParameter(
19
+ schema: AnalyticsInjectableJsonSchema | undefined,
20
+ parameterName: string
21
+ ): boolean {
22
+ return !hasAnalyticsParameter(schema, parameterName) && !schema?.oneOf && !schema?.allOf && !schema?.anyOf
23
+ }
@@ -4,21 +4,16 @@
4
4
  // Licensed under the MIT License: https://github.com/agentcathq/agentcat-typescript-sdk/blob/main/LICENSE
5
5
 
6
6
  import type { MCPAnalyticsOptions } from '../types'
7
+ import {
8
+ canInjectAnalyticsParameter,
9
+ hasAnalyticsParameter,
10
+ type AnalyticsInjectableJsonSchema,
11
+ } from './analytics-parameters'
7
12
  import { DEFAULT_CONTEXT_PARAMETER_DESCRIPTION } from './constants'
8
13
  import { log } from './logger'
9
14
 
10
- interface JsonSchema {
11
- additionalProperties?: boolean
12
- allOf?: unknown
13
- anyOf?: unknown
14
- oneOf?: unknown
15
- properties?: Record<string, unknown>
16
- required?: string[]
17
- type?: string
18
- }
19
-
20
15
  export interface ContextInjectableTool {
21
- inputSchema?: JsonSchema
16
+ inputSchema?: AnalyticsInjectableJsonSchema
22
17
  name?: string
23
18
  [key: string]: unknown
24
19
  }
@@ -48,17 +43,14 @@ export function addContextParameterToTool<TTool extends ContextInjectableTool>(
48
43
  // Create a shallow copy of the tool to avoid modifying the original
49
44
  const modifiedTool = { ...tool }
50
45
  const toolName = tool.name || 'unknown'
51
- const schema = modifiedTool.inputSchema as JsonSchema | undefined
52
-
53
- // Check if tool already has context parameter - skip to avoid collision
54
- if (schema?.properties?.context) {
55
- log(`WARN: Tool "${toolName}" already has 'context' parameter. Skipping context injection.`)
56
- return modifiedTool
57
- }
46
+ const schema = modifiedTool.inputSchema as AnalyticsInjectableJsonSchema | undefined
58
47
 
59
- // Skip complex schemas that can't safely have properties added at root level
60
- if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
61
- log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping context injection.`)
48
+ if (!canInjectAnalyticsParameter(schema, 'context')) {
49
+ if (hasAnalyticsParameter(schema, 'context')) {
50
+ log(`WARN: Tool "${toolName}" already has 'context' parameter. Skipping context injection.`)
51
+ } else {
52
+ log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping context injection.`)
53
+ }
62
54
  return modifiedTool
63
55
  }
64
56
 
@@ -77,9 +69,9 @@ export function addContextParameterToTool<TTool extends ContextInjectableTool>(
77
69
  const contextDescription = contextDescriptionOverride || DEFAULT_CONTEXT_PARAMETER_DESCRIPTION
78
70
 
79
71
  // Deep copy the inputSchema to avoid mutations
80
- modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema)) as JsonSchema
72
+ modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema)) as AnalyticsInjectableJsonSchema
81
73
 
82
- const inputSchema = modifiedTool.inputSchema as JsonSchema
74
+ const inputSchema = modifiedTool.inputSchema as AnalyticsInjectableJsonSchema
83
75
 
84
76
  // Ensure properties object exists
85
77
  if (!inputSchema.properties) {
@@ -4,24 +4,19 @@
4
4
  // Licensed under the MIT License: https://github.com/agentcathq/agentcat-typescript-sdk/blob/main/LICENSE
5
5
 
6
6
  import { uuidv7 } from '@posthog/core'
7
+ import {
8
+ canInjectAnalyticsParameter,
9
+ hasAnalyticsParameter,
10
+ type AnalyticsInjectableJsonSchema,
11
+ } from './analytics-parameters'
7
12
  import { DEFAULT_CONVERSATION_ID_DESCRIPTION } from './constants'
8
13
  import { log } from './logger'
9
14
  import { GET_MORE_TOOLS_NAME } from './tools'
10
15
 
11
16
  export const CONVERSATION_ID_PARAM_NAME = 'conversation_id'
12
17
 
13
- interface JsonSchema {
14
- additionalProperties?: boolean
15
- allOf?: unknown
16
- anyOf?: unknown
17
- oneOf?: unknown
18
- properties?: Record<string, unknown>
19
- required?: string[]
20
- type?: string
21
- }
22
-
23
18
  export interface ConversationIdInjectableTool {
24
- inputSchema?: JsonSchema
19
+ inputSchema?: AnalyticsInjectableJsonSchema
25
20
  name?: string
26
21
  [key: string]: unknown
27
22
  }
@@ -29,17 +24,16 @@ export interface ConversationIdInjectableTool {
29
24
  export function addConversationIdToTool<TTool extends ConversationIdInjectableTool>(tool: TTool): TTool {
30
25
  const modifiedTool = { ...tool }
31
26
  const toolName = tool.name || 'unknown'
32
- const schema = modifiedTool.inputSchema as JsonSchema | undefined
33
-
34
- if (schema?.properties?.[CONVERSATION_ID_PARAM_NAME]) {
35
- log(
36
- `WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`
37
- )
38
- return modifiedTool
39
- }
40
-
41
- if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
42
- log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`)
27
+ const schema = modifiedTool.inputSchema as AnalyticsInjectableJsonSchema | undefined
28
+
29
+ if (!canInjectAnalyticsParameter(schema, CONVERSATION_ID_PARAM_NAME)) {
30
+ if (hasAnalyticsParameter(schema, CONVERSATION_ID_PARAM_NAME)) {
31
+ log(
32
+ `WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`
33
+ )
34
+ } else {
35
+ log(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`)
36
+ }
43
37
  return modifiedTool
44
38
  }
45
39
 
@@ -51,9 +45,9 @@ export function addConversationIdToTool<TTool extends ConversationIdInjectableTo
51
45
  }
52
46
  }
53
47
 
54
- modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema)) as JsonSchema
48
+ modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema)) as AnalyticsInjectableJsonSchema
55
49
 
56
- const inputSchema = modifiedTool.inputSchema as JsonSchema
50
+ const inputSchema = modifiedTool.inputSchema as AnalyticsInjectableJsonSchema
57
51
 
58
52
  if (!inputSchema.properties) {
59
53
  inputSchema.properties = {}
@@ -11,11 +11,19 @@ import type {
11
11
  RegisteredTool,
12
12
  ToolCallback,
13
13
  } from '../types'
14
+ import { canInjectAnalyticsParameter } from './analytics-parameters'
14
15
  import { stripConversationId } from './conversation-id'
16
+ import { isContextEnabled } from './context-parameters'
15
17
  import { MCPAnalyticsEventType } from './event-types'
16
18
  import { getServerTrackingData } from './internal'
17
19
  import { log } from './logger'
18
- import { createWrappedTool, getToolFunction, hasToolFunction } from './mcp-sdk-compat'
20
+ import {
21
+ createWrappedTool,
22
+ getObjectShape,
23
+ getToolFunction,
24
+ hasToolFunction,
25
+ isZodRawShapeCompat,
26
+ } from './mcp-sdk-compat'
19
27
  import { handleReportMissing, resolveMissingCapabilityToolName } from './tools'
20
28
  import {
21
29
  handleInitializeRequest,
@@ -44,6 +52,41 @@ function isCallbackUpdate(value: unknown): value is { callback: ToolCallback } {
44
52
  return !!value && typeof value === 'object' && 'callback' in value && typeof value.callback === 'function'
45
53
  }
46
54
 
55
+ function analyticsOwnsParameter(inputSchema: unknown, parameterName: string): boolean {
56
+ if (!inputSchema || typeof inputSchema !== 'object') {
57
+ return canInjectAnalyticsParameter(undefined, parameterName)
58
+ }
59
+
60
+ if (isZodRawShapeCompat(inputSchema)) {
61
+ return canInjectAnalyticsParameter({ properties: inputSchema }, parameterName)
62
+ }
63
+
64
+ const shape = getObjectShape(inputSchema)
65
+ if (shape) {
66
+ return canInjectAnalyticsParameter({ properties: shape }, parameterName)
67
+ }
68
+
69
+ const schema = inputSchema as Record<string, unknown>
70
+ if ('_def' in schema || '_zod' in schema || '~standard' in schema) {
71
+ // The MCP SDK advertises non-object schemas as an empty object schema.
72
+ return canInjectAnalyticsParameter(undefined, parameterName)
73
+ }
74
+
75
+ return canInjectAnalyticsParameter(schema, parameterName)
76
+ }
77
+
78
+ function stripOwnedAnalyticsArguments(
79
+ args: unknown,
80
+ ownership: { context: boolean; conversationId: boolean }
81
+ ): unknown {
82
+ let cleanedArgs = args
83
+ if (ownership.context && cleanedArgs && typeof cleanedArgs === 'object' && 'context' in cleanedArgs) {
84
+ const { context: _context, ...rest } = cleanedArgs
85
+ cleanedArgs = rest
86
+ }
87
+ return ownership.conversationId ? stripConversationId(cleanedArgs) : cleanedArgs
88
+ }
89
+
47
90
  function addTracingToToolRegistry(
48
91
  tools: Record<string, RegisteredTool>,
49
92
  server: HighLevelMCPServerLike
@@ -78,7 +121,10 @@ function setupListenerToRegisteredTools(server: HighLevelMCPServerLike): void {
78
121
  return Reflect.set(target, property, value)
79
122
  }
80
123
 
81
- const nextValue = addTracingToToolCallbackInternal(value, property, server)
124
+ // The MCP SDK's registry copy is currently stale after update(), but keep this lookup lazy so
125
+ // ownership follows the current schema once the registry reflects live tool state.
126
+ const getCurrentInputSchema = () => value.inputSchema
127
+ const nextValue = addTracingToToolCallbackInternal(value, property, server, getCurrentInputSchema)
82
128
 
83
129
  if (typeof nextValue.update === 'function') {
84
130
  const originalUpdate = nextValue.update
@@ -89,7 +135,8 @@ function setupListenerToRegisteredTools(server: HighLevelMCPServerLike): void {
89
135
  const wrappedTool = addTracingToToolCallbackInternal(
90
136
  { callback: updateObj.callback },
91
137
  property,
92
- server
138
+ server,
139
+ getCurrentInputSchema
93
140
  )
94
141
  updateObj.callback = getToolFunction(wrappedTool)
95
142
  }
@@ -141,12 +188,12 @@ function setupListenerToRegisteredTools(server: HighLevelMCPServerLike): void {
141
188
  function addTracingToToolCallbackInternal(
142
189
  tool: RegisteredTool,
143
190
  toolName: string,
144
- server: HighLevelMCPServerLike
191
+ server: HighLevelMCPServerLike,
192
+ getCurrentInputSchema: () => unknown = () => tool.inputSchema
145
193
  ): RegisteredTool {
146
194
  const originalCallback = getToolFunction(tool)
147
- const missingToolName = resolveMissingCapabilityToolName(
148
- getServerTrackingData(server.server as MCPServerLike)?.options
149
- )
195
+ const options = getServerTrackingData(server.server as MCPServerLike)?.options
196
+ const missingToolName = resolveMissingCapabilityToolName(options)
150
197
 
151
198
  if (wrappedCallbacks.has(originalCallback)) {
152
199
  log(`Tool ${toolName} callback already wrapped, skipping re-wrap`)
@@ -170,15 +217,17 @@ function addTracingToToolCallbackInternal(
170
217
  extra = params[0] as CompatibleRequestHandlerExtra
171
218
  }
172
219
 
173
- const removeContextFromArgs = (input: unknown): unknown => {
174
- if (input && typeof input === 'object' && 'context' in input) {
175
- const { context: _context, ...rest } = input
176
- return rest
177
- }
178
- return input
179
- }
180
-
181
- const cleanedArgs = toolName === missingToolName ? args : stripConversationId(removeContextFromArgs(args))
220
+ const inputSchema = getCurrentInputSchema()
221
+ const cleanedArgs = stripOwnedAnalyticsArguments(args, {
222
+ context:
223
+ toolName !== missingToolName &&
224
+ isContextEnabled(options?.context) &&
225
+ analyticsOwnsParameter(inputSchema, 'context'),
226
+ conversationId:
227
+ toolName !== missingToolName &&
228
+ options?.enableConversationId === true &&
229
+ analyticsOwnsParameter(inputSchema, 'conversation_id'),
230
+ })
182
231
 
183
232
  try {
184
233
  if (cleanedArgs === undefined) {
@@ -97,6 +97,21 @@ export function isZ4Schema(schema: unknown): boolean {
97
97
  return !!(schema as ZodV4Internal)._zod
98
98
  }
99
99
 
100
+ function isZodTypeLike(value: unknown): boolean {
101
+ return (
102
+ !!value &&
103
+ typeof value === 'object' &&
104
+ 'parse' in value &&
105
+ typeof value.parse === 'function' &&
106
+ 'safeParse' in value &&
107
+ typeof value.safeParse === 'function'
108
+ )
109
+ }
110
+
111
+ export function isZodRawShapeCompat(schema: unknown): schema is Record<string, unknown> {
112
+ return !!schema && typeof schema === 'object' && Object.values(schema).some(isZodTypeLike)
113
+ }
114
+
100
115
  export function getObjectShape(schema: unknown): Record<string, unknown> | undefined {
101
116
  if (!schema || typeof schema !== 'object') {
102
117
  return
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '0.10.2'
1
+ export const version = '0.10.3'