@posthog/mcp 0.16.1 → 0.16.2

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/README.md CHANGED
@@ -282,6 +282,21 @@ when `tools/list` and `tools/call` reach different server replicas.
282
282
  both advertises both tools. Like `get_more_tools`, a real tool that already uses the configured name
283
283
  wins: the SDK warns, skips injection, and delegates calls to the real handler.
284
284
 
285
+ On a paginated catalogue (a `tools/list` response with a `nextCursor`), `instrument()` injects
286
+ `send_feedback` on the first page only — the page every client reads, including clients that never
287
+ follow `nextCursor` — so a compliant client's concatenated list carries it once. "First page" means
288
+ a `tools/list` request with no cursor; an empty string is a valid cursor, so `cursor: ""` is a
289
+ continuation page. Hosts using `prepareToolList()` directly own this rule themselves: pass
290
+ `collectFeedback: true` only for the first page.
291
+
292
+ Name collisions are detected on the first page only. A real tool named `send_feedback` (or
293
+ `get_more_tools`) on the first page wins: the SDK warns, skips injection, and forwards its calls. A
294
+ real tool that only appears on a **later** page is not detected up front — the SDK's virtual tool is
295
+ injected and intercepts calls to the name, so the real tool is shadowed and a concatenated listing
296
+ carries the name twice. The SDK logs a warning when a client fetches the colliding page, but the fix
297
+ is yours: rename the SDK's tools with `collectFeedback: { toolName: "..." }` and the
298
+ `missingCapabilityToolName` option.
299
+
285
300
  ### If you switched to `instrument(server.server)`
286
301
 
287
302
  Before v2 support landed, the compatibility gate rejected high-level v2 servers, and the usual
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"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"}
@@ -388,14 +388,15 @@ async function getTracedToolsList(server, originalListToolsHandler, request, ext
388
388
  if (feedbackOptions) {
389
389
  const feedbackToolName = feedbackOptions.toolName ?? external_feedback_js_namespaceObject.SEND_FEEDBACK_TOOL_NAME;
390
390
  const alreadyPresent = tools.some((tool)=>tool?.name === feedbackToolName);
391
- if (alreadyPresent) data.logger(`Warning: Cannot inject agent-feedback tool "${feedbackToolName}" because a real tool already uses that name. The real tool will not be intercepted.`);
392
- else {
391
+ const isFirstPage = request.params?.cursor == null;
392
+ if (isFirstPage && alreadyPresent) data.logger(`Warning: Cannot inject agent-feedback tool "${feedbackToolName}" because a real tool already uses that name. The real tool will not be intercepted. To collect feedback alongside it, rename the SDK's tool with collectFeedback: { toolName: "..." }.`);
393
+ else if (isFirstPage) {
393
394
  const virtualTool = (0, external_feedback_js_namespaceObject.getFeedbackToolDescriptor)(feedbackOptions);
394
395
  tools.push(virtualTool);
395
396
  cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, [
396
397
  virtualTool
397
398
  ]);
398
- }
399
+ } else if (alreadyPresent) data.logger(`Warning: A real tool "${feedbackToolName}" on a later tools/list page is shadowed by the SDK's agent-feedback tool. Its calls will be intercepted. Rename the SDK's tool with collectFeedback: { toolName: "..." } to keep both.`);
399
400
  }
400
401
  if ((0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(data.options.captureModel)) tools = (0, external_model_parameters_js_namespaceObject.addModelParameterToTools)(tools, (0, external_model_parameters_js_namespaceObject.getModelDescription)(data.options.captureModel), data.logger);
401
402
  if (data.options.enableConversationId) {
@@ -346,14 +346,15 @@ async function getTracedToolsList(server, originalListToolsHandler, request, ext
346
346
  if (feedbackOptions) {
347
347
  const feedbackToolName = feedbackOptions.toolName ?? SEND_FEEDBACK_TOOL_NAME;
348
348
  const alreadyPresent = tools.some((tool)=>tool?.name === feedbackToolName);
349
- if (alreadyPresent) data.logger(`Warning: Cannot inject agent-feedback tool "${feedbackToolName}" because a real tool already uses that name. The real tool will not be intercepted.`);
350
- else {
349
+ const isFirstPage = request.params?.cursor == null;
350
+ if (isFirstPage && alreadyPresent) data.logger(`Warning: Cannot inject agent-feedback tool "${feedbackToolName}" because a real tool already uses that name. The real tool will not be intercepted. To collect feedback alongside it, rename the SDK's tool with collectFeedback: { toolName: "..." }.`);
351
+ else if (isFirstPage) {
351
352
  const virtualTool = getFeedbackToolDescriptor(feedbackOptions);
352
353
  tools.push(virtualTool);
353
354
  cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, [
354
355
  virtualTool
355
356
  ]);
356
- }
357
+ } else if (alreadyPresent) data.logger(`Warning: A real tool "${feedbackToolName}" on a later tools/list page is shadowed by the SDK's agent-feedback tool. Its calls will be intercepted. Rename the SDK's tool with collectFeedback: { toolName: "..." } to keep both.`);
357
358
  }
358
359
  if (isCaptureModelEnabled(data.options.captureModel)) tools = addModelParameterToTools(tools, getModelDescription(data.options.captureModel), data.logger);
359
360
  if (data.options.enableConversationId) {
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version = "0.16.1";
1
+ export declare const version = "0.16.2";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -27,7 +27,7 @@ var __webpack_require__ = {};
27
27
  })();
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
- const version = '0.16.1';
30
+ const version = '0.16.2';
31
31
  __webpack_require__.d(__webpack_exports__, {}, {
32
32
  version: version
33
33
  });
package/dist/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
- const version = '0.16.1';
1
+ const version = '0.16.2';
2
2
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/mcp",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
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.53.3"
31
+ "@posthog/core": "^1.54.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@babel/preset-env": "^7.27.1",
@@ -53,7 +53,7 @@
53
53
  "@vitest/coverage-v8": "^1.6.1",
54
54
  "vitest": "^1.6.1",
55
55
  "@posthog-tooling/tsconfig-base": "1.1.1",
56
- "posthog-node": "^5.52.1"
56
+ "posthog-node": "^5.52.4"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@modelcontextprotocol/sdk": ">=1.26.0",
@@ -91,8 +91,8 @@
91
91
  "pretest:unit": "pnpm generate-version",
92
92
  "test:unit": "vitest run",
93
93
  "test:integration": "pnpm test:integration:sdk-v1 && pnpm test:integration:sdk-v2 && pnpm test:integration:nest-v1 && pnpm test:integration:nest-v2",
94
- "test:integration:sdk-v1": "node harness/dual-era/matrix.mjs --major v1 && node harness/dual-era/probe-late-handlers.mjs --major v1 && node harness/dual-era/probe-pagination.mjs --major v1 && node harness/dual-era/probe-mcp-apps.mjs --major v1",
95
- "test:integration:sdk-v2": "node harness/dual-era/matrix.mjs --major v2 && node harness/dual-era/probe-late-handlers.mjs --major v2 && node harness/dual-era/probe-first-call-error.mjs && node harness/dual-era/probe-pagination.mjs --major v2 && node harness/dual-era/probe-mcp-apps.mjs --major v2",
94
+ "test:integration:sdk-v1": "node harness/dual-era/matrix.mjs --major v1 && node harness/dual-era/probe-late-handlers.mjs --major v1 && node harness/dual-era/probe-pagination.mjs --major v1 && node harness/dual-era/probe-feedback.mjs --major v1 && node harness/dual-era/probe-mcp-apps.mjs --major v1",
95
+ "test:integration:sdk-v2": "node harness/dual-era/matrix.mjs --major v2 && node harness/dual-era/probe-late-handlers.mjs --major v2 && node harness/dual-era/probe-first-call-error.mjs && node harness/dual-era/probe-pagination.mjs --major v2 && node harness/dual-era/probe-feedback.mjs --major v2 && node harness/dual-era/probe-mcp-apps.mjs --major v2",
96
96
  "test:integration:nest-v1": "node harness/nest-v1/verify.mjs && LEVEL=low node harness/nest-v1/verify.mjs",
97
97
  "test:integration:nest-v2": "node harness/nest-v2/verify.mjs && LEVEL=low node harness/nest-v2/verify.mjs",
98
98
  "prebuild": "pnpm generate-version",
@@ -845,14 +845,26 @@ async function getTracedToolsList(
845
845
  if (feedbackOptions) {
846
846
  const feedbackToolName = feedbackOptions.toolName ?? SEND_FEEDBACK_TOOL_NAME
847
847
  const alreadyPresent = tools.some((tool) => tool?.name === feedbackToolName)
848
- if (alreadyPresent) {
848
+ // A compliant client concatenates every page into one list, so only the
849
+ // first page — the one every client reads, including clients that never
850
+ // follow `nextCursor` — may carry the virtual tool. Presence, not
851
+ // truthiness: `cursor: ""` is a continuation page.
852
+ const isFirstPage = request.params?.cursor == null
853
+ if (isFirstPage && alreadyPresent) {
849
854
  data.logger(
850
- `Warning: Cannot inject agent-feedback tool "${feedbackToolName}" because a real tool already uses that name. The real tool will not be intercepted.`
855
+ `Warning: Cannot inject agent-feedback tool "${feedbackToolName}" because a real tool already uses that name. The real tool will not be intercepted. To collect feedback alongside it, rename the SDK's tool with collectFeedback: { toolName: "..." }.`
851
856
  )
852
- } else {
857
+ } else if (isFirstPage) {
853
858
  const virtualTool = getFeedbackToolDescriptor(feedbackOptions)
854
859
  tools.push(virtualTool)
855
860
  cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, [virtualTool])
861
+ } else if (alreadyPresent) {
862
+ // Conflicts are only detected on the pages a client actually
863
+ // fetches; a real owner here is already shadowed by the first-page
864
+ // injection, so the host must rename the SDK's tool.
865
+ data.logger(
866
+ `Warning: A real tool "${feedbackToolName}" on a later tools/list page is shadowed by the SDK's agent-feedback tool. Its calls will be intercepted. Rename the SDK's tool with collectFeedback: { toolName: "..." } to keep both.`
867
+ )
856
868
  }
857
869
  }
858
870
 
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '0.16.1'
1
+ export const version = '0.16.2'