@posthog/mcp 0.0.8 → 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.8";
740
+ var version = "0.0.9";
741
741
  //#endregion
742
742
  //#region src/modules/session.ts
743
743
  function newSessionId() {
@@ -1875,9 +1875,10 @@ function getReportMissingToolDescriptor() {
1875
1875
  required: ["context"]
1876
1876
  },
1877
1877
  annotations: {
1878
+ title: "Get More Tools",
1878
1879
  readOnlyHint: true,
1879
- idempotentHint: false,
1880
- openWorldHint: false,
1880
+ openWorldHint: true,
1881
+ idempotentHint: true,
1881
1882
  destructiveHint: false
1882
1883
  }
1883
1884
  };
@@ -2513,7 +2514,7 @@ async function handleWrappedToolsCall(originalHandler, server, request, extra) {
2513
2514
  const startTime = /* @__PURE__ */ new Date();
2514
2515
  const conversation = resolveConversationId(getServerTrackingData(server)?.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
2515
2516
  const tracing = await initializeToolCallEvent(server, request, conversation.conversationId ? cloneRequestWithoutConversationId(request) : request, extra, startTime, conversation);
2516
- 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);
2517
2518
  return await executeOriginalTool(originalHandler, server, request, extra, tracing, startTime);
2518
2519
  }
2519
2520
  async function initializeToolCallEvent(server, request, downstreamRequest, extra, startTime, conversation) {
@@ -2562,10 +2563,10 @@ async function applyResolvedMetadata(event, data, request, extra) {
2562
2563
  const resolvedProperties = await resolveEventProperties(data, request, extra);
2563
2564
  if (resolvedProperties) event.properties = resolvedProperties;
2564
2565
  }
2565
- async function executeReportMissingTool(server, request, tracing, startTime) {
2566
+ function executeReportMissingTool(server, request, tracing, startTime) {
2566
2567
  try {
2567
2568
  const context = getContextArgument(request) || "";
2568
- const result = await handleReportMissing({ context });
2569
+ const result = handleReportMissing({ context });
2569
2570
  publishSuccessfulToolEvent(server, tracing, result, startTime, {
2570
2571
  userIntent: context,
2571
2572
  userIntentSource: "context_parameter"