@posthog/mcp 0.0.7 → 0.0.9

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/LICENSE CHANGED
@@ -1,6 +1,7 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 MCPcat
3
+ Copyright (c) 2025-2026 MCPcat
4
+ Copyright (c) 2026 PostHog
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,11 +1,12 @@
1
- # PostHog MCP
1
+ # PostHog MCP Analytics
2
2
 
3
- TypeScript SDK for instrumenting Model Context Protocol servers with PostHog analytics.
3
+ TypeScript SDK for instrumenting Model Context Protocol (MCP) servers with PostHog analytics.
4
4
 
5
- > Warning:
5
+ > [!WARNING]
6
6
  > This package is in very early access and is not suitable for production use yet.
7
7
  > The API, event names, PostHog property schema, tracing behavior, and release process may change without notice while we dogfood the SDK.
8
8
  > We publish in public because PostHog builds in public, but you should treat `0.0.x` releases as experimental.
9
+ > We do no promise that this will eventually be shipped as a PostHog product. We are using it internally for our MCP for testing purposes.
9
10
 
10
11
  The initial goal is to help MCP server owners understand tool usage, agent intent, client/session metadata, errors, and feedback without hand-rolling MCP-specific analytics.
11
12
 
@@ -18,17 +19,17 @@ pnpm add @posthog/mcp
18
19
  ## Usage
19
20
 
20
21
  ```ts
21
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
- import { track } from "@posthog/mcp";
22
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js"
23
+ import { track } from "@posthog/mcp"
23
24
 
24
- const server = new Server({ name: "my-mcp-server", version: "1.0.0" });
25
+ const server = new Server({ name: "my-mcp-server", version: "1.0.0" })
25
26
 
26
27
  track(server, {
27
28
  apiKey: process.env.POSTHOG_API_KEY,
28
29
  context: true,
29
30
  enableAITracing: true,
30
31
  host: "https://us.i.posthog.com",
31
- });
32
+ })
32
33
  ```
33
34
 
34
35
  With `context: true`, the SDK adds a required `context` argument to every tool call, strips it before invoking your handler, and captures it as `$mcp_intent` on PostHog events.
@@ -43,10 +44,10 @@ track(server, {
43
44
  apiKey: process.env.POSTHOG_API_KEY,
44
45
  context: true,
45
46
  intentFallback: (request) => {
46
- const toolName = request.params?.name;
47
- return toolName ? `Calling ${toolName}` : undefined;
47
+ const toolName = request.params?.name
48
+ return toolName ? `Calling ${toolName}` : undefined
48
49
  },
49
- });
50
+ })
50
51
  ```
51
52
 
52
53
  With `enableAITracing: true`, tool calls also emit `$ai_span` events with `$ai_trace_id` and `$ai_span_id`.
@@ -60,7 +61,7 @@ When `enableConversationId: true` is passed to `track()`, the SDK injects an opt
60
61
  track(server, {
61
62
  apiKey: process.env.POSTHOG_API_KEY,
62
63
  enableConversationId: true,
63
- });
64
+ })
64
65
  ```
65
66
 
66
67
  **Caveats:**
@@ -73,14 +74,14 @@ The SDK sends events through `posthog-node`, so it uses the same PostHog ingesti
73
74
  If your application already owns a PostHog client, pass it in instead:
74
75
 
75
76
  ```ts
76
- import { PostHog } from "posthog-node";
77
- import { track } from "@posthog/mcp";
77
+ import { PostHog } from "posthog-node"
78
+ import { track } from "@posthog/mcp"
78
79
 
79
- const posthog = new PostHog(process.env.POSTHOG_API_KEY ?? "");
80
+ const posthog = new PostHog(process.env.POSTHOG_API_KEY ?? "")
80
81
 
81
82
  track(server, {
82
83
  posthogClient: posthog,
83
- });
84
+ })
84
85
  ```
85
86
 
86
87
  ## Event schema
@@ -143,4 +144,4 @@ Release approval requests are posted in Slack to `#approvals-client-libraries`.
143
144
 
144
145
  ## Attribution
145
146
 
146
- This SDK started from a duplicated copy of the MIT-licensed [MCPcat TypeScript SDK](https://github.com/MCPCat/mcpcat-typescript-sdk). We are grateful for their work on MCP server instrumentation patterns, especially tool-call tracing, context capture, and MCP SDK compatibility handling.
147
+ This SDK started as a fork from [mcpcat.io](https://mcpcat.io)'s [MCPcat TypeScript SDK](https://github.com/MCPCat/mcpcat-typescript-sdk). We are grateful for their work on MCP server instrumentation patterns, especially tool-call tracing, context capture, and MCP SDK compatibility handling.
package/dist/index.cjs CHANGED
@@ -296,7 +296,7 @@ async function handleIdentify(server, data, request, extra) {
296
296
  redactionFn: data.options.redactSensitiveInformation
297
297
  };
298
298
  try {
299
- const identityResult = await data.options.identify(request, extra);
299
+ const identityResult = typeof data.options.identify === "function" ? await data.options.identify(request, extra) : data.options.identify;
300
300
  if (identityResult) {
301
301
  const currentSessionId = data.sessionId;
302
302
  const previousIdentity = _globalIdentityCache.get(currentSessionId);
@@ -737,7 +737,7 @@ function sanitizeParameters(obj) {
737
737
  }
738
738
  //#endregion
739
739
  //#region package.json
740
- var version = "0.0.7";
740
+ var version = "0.0.9";
741
741
  //#endregion
742
742
  //#region src/modules/session.ts
743
743
  function newSessionId() {
@@ -1873,6 +1873,13 @@ function getReportMissingToolDescriptor() {
1873
1873
  description: "A description of your goal and what kind of tool would help accomplish it."
1874
1874
  } },
1875
1875
  required: ["context"]
1876
+ },
1877
+ annotations: {
1878
+ title: "Get More Tools",
1879
+ readOnlyHint: true,
1880
+ openWorldHint: true,
1881
+ idempotentHint: true,
1882
+ destructiveHint: false
1876
1883
  }
1877
1884
  };
1878
1885
  }
@@ -1928,9 +1935,8 @@ function setupMCPAnalyticsTools(server) {
1928
1935
  return { tools };
1929
1936
  }
1930
1937
  if (isContextEnabled(data.options.context)) tools = addContextParameterToTools(tools, getContextDescription(data.options.context));
1931
- if (data.options.reportMissing) {
1932
- if (!tools.some((tool) => tool?.name === "get_more_tools")) tools.push(getReportMissingToolDescriptor());
1933
- }
1938
+ if (data.options.reportMissing) if (tools.some((tool) => tool?.name === "get_more_tools")) writeToLog("Warning: report_missing tool already present in tools list. Skipping addition. This is likely due to the server already including a report_missing tool. If you want to rely on the PostHog MCP Analytics report_missing tool, you should disable the server's report_missing tool.");
1939
+ else tools.push(getReportMissingToolDescriptor());
1934
1940
  event.response = { tools };
1935
1941
  event.isError = false;
1936
1942
  event.duration = event.timestamp && Date.now() - event.timestamp.getTime() || 0;
@@ -2508,7 +2514,7 @@ async function handleWrappedToolsCall(originalHandler, server, request, extra) {
2508
2514
  const startTime = /* @__PURE__ */ new Date();
2509
2515
  const conversation = resolveConversationId(getServerTrackingData(server)?.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
2510
2516
  const tracing = await initializeToolCallEvent(server, request, conversation.conversationId ? cloneRequestWithoutConversationId(request) : request, extra, startTime, conversation);
2511
- if (request?.params?.name === "get_more_tools") return await executeReportMissingTool(server, request, tracing, startTime);
2517
+ if (request?.params?.name === "get_more_tools") return executeReportMissingTool(server, request, tracing, startTime);
2512
2518
  return await executeOriginalTool(originalHandler, server, request, extra, tracing, startTime);
2513
2519
  }
2514
2520
  async function initializeToolCallEvent(server, request, downstreamRequest, extra, startTime, conversation) {
@@ -2557,10 +2563,10 @@ async function applyResolvedMetadata(event, data, request, extra) {
2557
2563
  const resolvedProperties = await resolveEventProperties(data, request, extra);
2558
2564
  if (resolvedProperties) event.properties = resolvedProperties;
2559
2565
  }
2560
- async function executeReportMissingTool(server, request, tracing, startTime) {
2566
+ function executeReportMissingTool(server, request, tracing, startTime) {
2561
2567
  try {
2562
2568
  const context = getContextArgument(request) || "";
2563
- const result = await handleReportMissing({ context });
2569
+ const result = handleReportMissing({ context });
2564
2570
  publishSuccessfulToolEvent(server, tracing, result, startTime, {
2565
2571
  userIntent: context,
2566
2572
  userIntentSource: "context_parameter"