@posthog/mcp 0.0.9 → 0.1.17

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.
Files changed (138) hide show
  1. package/LICENSE +307 -3
  2. package/README.md +182 -90
  3. package/dist/extensions/capture.d.ts +13 -0
  4. package/dist/extensions/capture.d.ts.map +1 -0
  5. package/dist/extensions/capture.js +80 -0
  6. package/dist/extensions/capture.mjs +46 -0
  7. package/dist/extensions/compatibility.d.ts +23 -0
  8. package/dist/extensions/compatibility.d.ts.map +1 -0
  9. package/dist/extensions/compatibility.js +113 -0
  10. package/dist/extensions/compatibility.mjs +67 -0
  11. package/dist/extensions/constants.d.ts +39 -0
  12. package/dist/extensions/constants.d.ts.map +1 -0
  13. package/dist/extensions/constants.js +86 -0
  14. package/dist/extensions/constants.mjs +37 -0
  15. package/dist/extensions/context-parameters.d.ts +31 -0
  16. package/dist/extensions/context-parameters.d.ts.map +1 -0
  17. package/dist/extensions/context-parameters.js +93 -0
  18. package/dist/extensions/context-parameters.mjs +50 -0
  19. package/dist/extensions/conversation-id.d.ts +52 -0
  20. package/dist/extensions/conversation-id.d.ts.map +1 -0
  21. package/dist/extensions/conversation-id.js +164 -0
  22. package/dist/extensions/conversation-id.mjs +103 -0
  23. package/dist/extensions/event-types.d.ts +21 -0
  24. package/dist/extensions/event-types.d.ts.map +1 -0
  25. package/dist/extensions/event-types.js +47 -0
  26. package/dist/extensions/event-types.mjs +13 -0
  27. package/dist/extensions/exceptions.d.ts +13 -0
  28. package/dist/extensions/exceptions.d.ts.map +1 -0
  29. package/dist/extensions/exceptions.js +58 -0
  30. package/dist/extensions/exceptions.mjs +24 -0
  31. package/dist/extensions/ids.d.ts +13 -0
  32. package/dist/extensions/ids.d.ts.map +1 -0
  33. package/dist/extensions/ids.js +55 -0
  34. package/dist/extensions/ids.mjs +18 -0
  35. package/dist/extensions/instrument-highlevel.d.ts +3 -0
  36. package/dist/extensions/instrument-highlevel.d.ts.map +1 -0
  37. package/dist/extensions/instrument-highlevel.js +229 -0
  38. package/dist/extensions/instrument-highlevel.mjs +195 -0
  39. package/dist/extensions/instrument-lowlevel.d.ts +8 -0
  40. package/dist/extensions/instrument-lowlevel.d.ts.map +1 -0
  41. package/dist/extensions/instrument-lowlevel.js +85 -0
  42. package/dist/extensions/instrument-lowlevel.mjs +51 -0
  43. package/dist/extensions/instrumentation.d.ts +59 -0
  44. package/dist/extensions/instrumentation.d.ts.map +1 -0
  45. package/dist/extensions/instrumentation.js +237 -0
  46. package/dist/extensions/instrumentation.mjs +194 -0
  47. package/dist/extensions/intent.d.ts +10 -0
  48. package/dist/extensions/intent.d.ts.map +1 -0
  49. package/dist/extensions/intent.js +84 -0
  50. package/dist/extensions/intent.mjs +44 -0
  51. package/dist/extensions/internal.d.ts +32 -0
  52. package/dist/extensions/internal.d.ts.map +1 -0
  53. package/dist/extensions/internal.js +158 -0
  54. package/dist/extensions/internal.mjs +106 -0
  55. package/dist/extensions/logger.d.ts +14 -0
  56. package/dist/extensions/logger.d.ts.map +1 -0
  57. package/dist/extensions/logger.js +47 -0
  58. package/dist/extensions/logger.mjs +10 -0
  59. package/dist/extensions/mcp-payloads.d.ts +5 -0
  60. package/dist/extensions/mcp-payloads.d.ts.map +1 -0
  61. package/dist/extensions/mcp-payloads.js +91 -0
  62. package/dist/extensions/mcp-payloads.mjs +54 -0
  63. package/dist/extensions/mcp-sdk-compat.d.ts +33 -0
  64. package/dist/extensions/mcp-sdk-compat.d.ts.map +1 -0
  65. package/dist/extensions/mcp-sdk-compat.js +112 -0
  66. package/dist/extensions/mcp-sdk-compat.mjs +60 -0
  67. package/dist/extensions/posthog-events.d.ts +14 -0
  68. package/dist/extensions/posthog-events.d.ts.map +1 -0
  69. package/dist/extensions/posthog-events.js +143 -0
  70. package/dist/extensions/posthog-events.mjs +109 -0
  71. package/dist/extensions/sanitization.d.ts +10 -0
  72. package/dist/extensions/sanitization.d.ts.map +1 -0
  73. package/dist/extensions/sanitization.js +96 -0
  74. package/dist/extensions/sanitization.mjs +62 -0
  75. package/dist/extensions/session.d.ts +20 -0
  76. package/dist/extensions/session.d.ts.map +1 -0
  77. package/dist/extensions/session.js +113 -0
  78. package/dist/extensions/session.mjs +67 -0
  79. package/dist/extensions/sink.d.ts +44 -0
  80. package/dist/extensions/sink.d.ts.map +1 -0
  81. package/dist/extensions/sink.js +102 -0
  82. package/dist/extensions/sink.mjs +65 -0
  83. package/dist/extensions/tools.d.ts +9 -0
  84. package/dist/extensions/tools.d.ts.map +1 -0
  85. package/dist/extensions/tools.js +79 -0
  86. package/dist/extensions/tools.mjs +39 -0
  87. package/dist/extensions/tracing-helpers.d.ts +29 -0
  88. package/dist/extensions/tracing-helpers.d.ts.map +1 -0
  89. package/dist/extensions/tracing-helpers.js +59 -0
  90. package/dist/extensions/tracing-helpers.mjs +16 -0
  91. package/dist/extensions/truncation.d.ts +25 -0
  92. package/dist/extensions/truncation.d.ts.map +1 -0
  93. package/dist/extensions/truncation.js +277 -0
  94. package/dist/extensions/truncation.mjs +228 -0
  95. package/dist/index.d.ts +36 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +132 -0
  98. package/dist/index.mjs +83 -2929
  99. package/dist/types.d.ts +220 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +18 -0
  102. package/dist/types.mjs +0 -0
  103. package/dist/version.d.ts +2 -0
  104. package/dist/version.d.ts.map +1 -0
  105. package/dist/version.js +36 -0
  106. package/dist/version.mjs +2 -0
  107. package/package.json +55 -87
  108. package/src/extensions/capture.ts +68 -0
  109. package/src/extensions/compatibility.ts +138 -0
  110. package/src/extensions/constants.ts +48 -0
  111. package/src/extensions/context-parameters.ts +119 -0
  112. package/src/extensions/conversation-id.ts +177 -0
  113. package/src/extensions/event-types.ts +21 -0
  114. package/src/extensions/exceptions.ts +83 -0
  115. package/src/extensions/ids.ts +32 -0
  116. package/src/extensions/instrument-highlevel.ts +297 -0
  117. package/src/extensions/instrument-lowlevel.ts +83 -0
  118. package/src/extensions/instrumentation.ts +415 -0
  119. package/src/extensions/intent.ts +78 -0
  120. package/src/extensions/internal.ts +193 -0
  121. package/src/extensions/logger.ts +27 -0
  122. package/src/extensions/mcp-payloads.ts +98 -0
  123. package/src/extensions/mcp-sdk-compat.ts +160 -0
  124. package/src/extensions/posthog-events.ts +212 -0
  125. package/src/extensions/sanitization.ts +121 -0
  126. package/src/extensions/session.ts +117 -0
  127. package/src/extensions/sink.ts +130 -0
  128. package/src/extensions/tools.ts +50 -0
  129. package/src/extensions/tracing-helpers.ts +51 -0
  130. package/src/extensions/truncation.ts +453 -0
  131. package/src/index.ts +174 -0
  132. package/src/types.ts +244 -0
  133. package/src/version.ts +1 -0
  134. package/dist/index.cjs +0 -2937
  135. package/dist/index.cjs.map +0 -1
  136. package/dist/index.d.cts +0 -264
  137. package/dist/index.d.mts +0 -263
  138. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,220 @@
1
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
+ import type { ErrorTracking } from '@posthog/core';
3
+ import type { MCPAnalyticsEventType } from './extensions/event-types';
4
+ import type { IdentityCache } from './extensions/internal';
5
+ import type { PostHogCaptureEvent } from './extensions/posthog-events';
6
+ import type { McpEventSink } from './extensions/sink';
7
+ import type { LoggerFn } from './extensions/logger';
8
+ export type JsonRecord = Record<string, unknown>;
9
+ /** PostHog error-tracking properties (`$exception_list`). Re-exported from `@posthog/core`. */
10
+ export type ErrorProperties = ErrorTracking.ErrorProperties;
11
+ /** A single parsed stack frame. Re-exported from `@posthog/core`. */
12
+ export type StackFrame = ErrorTracking.StackFrame;
13
+ export interface MCPRequestParamsLike {
14
+ arguments?: JsonRecord;
15
+ name?: string;
16
+ [key: string]: unknown;
17
+ }
18
+ export interface MCPRequestLike {
19
+ id?: number | string;
20
+ jsonrpc?: string;
21
+ method?: string;
22
+ params?: MCPRequestParamsLike;
23
+ [key: string]: unknown;
24
+ }
25
+ /** Handle returned by `instrument()` — the analytics surface for an instrumented server. */
26
+ export interface McpAnalytics {
27
+ /**
28
+ * Capture a custom event for this server. The `event` name is required and sent
29
+ * verbatim (a customer event, so it is not `$`-prefixed). Resolves once the event
30
+ * has been processed. Use for domain-specific actions that aren't auto-captured
31
+ * (user feedback, workflow milestones, etc).
32
+ */
33
+ capture(eventData: CaptureEventData): Promise<void>;
34
+ }
35
+ export interface MCPAnalyticsOptions {
36
+ /**
37
+ * Optional STDIO-safe log sink for SDK-internal warnings. Receives single string messages.
38
+ * Defaults to a no-op since MCP STDIO transports cannot use console.
39
+ */
40
+ logger?: LoggerFn;
41
+ /** Enable the `get_more_tools` virtual tool so agents can report missing functionality. */
42
+ reportMissing?: boolean;
43
+ /** Enables the `conversation_id` tool parameter + prompt-back loop. */
44
+ enableConversationId?: boolean;
45
+ /**
46
+ * Emit a `$exception` event alongside any failed tool call. Defaults to `true`.
47
+ * Set to `false` if you handle error tracking elsewhere and don't want MCP errors
48
+ * fanning out into PostHog error tracking.
49
+ */
50
+ enableExceptionAutocapture?: boolean;
51
+ /** Inject a required `context` parameter on every tool to capture user intent. */
52
+ context?: boolean | MCPAnalyticsContextOptions;
53
+ /**
54
+ * Identify the calling user. Returning a non-null value sets `distinct_id` and `$set`
55
+ * on subsequent events for the session. Object form is treated as a static identity.
56
+ */
57
+ identify?: ((request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise<UserIdentity | null>) | UserIdentity | null;
58
+ /**
59
+ * Called when a tool is invoked without an explicit `context` argument. Return a short
60
+ * intent string to record as `$mcp_intent` with `$mcp_intent_source = "inferred"`.
61
+ */
62
+ intentFallback?: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => MaybePromise<string | null | undefined>;
63
+ /**
64
+ * Inspect, modify, or drop each event right before it is sent to PostHog
65
+ * (matching posthog-node's `beforeSend`). Receives the fully-built capture
66
+ * payload — event name, `distinct_id`, and `properties` — and runs once per
67
+ * emitted event, including the `$exception` sibling of a failed tool call.
68
+ *
69
+ * Return the (possibly mutated) event to send it, or `null`/`undefined` to
70
+ * drop it. Use this to redact sensitive values, add or remove properties, or
71
+ * suppress specific events. A throw drops that event.
72
+ */
73
+ beforeSend?: BeforeSendFn;
74
+ /**
75
+ * Attach extra event properties on every auto-captured event. Spread into the PostHog
76
+ * event properties as-is; values must be JSON-serializable.
77
+ */
78
+ eventProperties?: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => JsonRecord | null | Promise<JsonRecord | null>;
79
+ }
80
+ export interface MCPAnalyticsContextOptions {
81
+ description?: string;
82
+ }
83
+ export type MaybePromise<T> = T | Promise<T>;
84
+ export type MCPAnalyticsIntentSource = 'context_parameter' | 'inferred';
85
+ export type ToolCallback = ((args: unknown, extra: CompatibleRequestHandlerExtra) => CallToolResult | Promise<CallToolResult>) | ((extra: CompatibleRequestHandlerExtra) => CallToolResult | Promise<CallToolResult>);
86
+ export type RegisteredTool = {
87
+ description?: string;
88
+ inputSchema?: unknown;
89
+ update?: (...args: unknown[]) => unknown;
90
+ } & ({
91
+ callback: ToolCallback;
92
+ handler?: never;
93
+ } | {
94
+ handler: ToolCallback;
95
+ callback?: never;
96
+ });
97
+ /**
98
+ * Hook invoked for every event just before it is handed to `posthog.capture()`.
99
+ * Return the event (optionally mutated) to send it, or a nullish value to drop it.
100
+ */
101
+ export type BeforeSendFn = (event: PostHogCaptureEvent) => MaybePromise<PostHogCaptureEvent | null | undefined>;
102
+ export interface Event {
103
+ actorId?: string;
104
+ clientName?: string;
105
+ clientVersion?: string;
106
+ conversationId?: string;
107
+ duration?: number;
108
+ error?: ErrorProperties | null;
109
+ eventId?: string;
110
+ eventType: MCPAnalyticsEventType;
111
+ groups?: Record<string, string>;
112
+ /**
113
+ * Explicit PostHog event name. When set (via `capture(server, { event })`) it
114
+ * overrides the built-in name derived from `eventType`, so callers can emit any
115
+ * event name. User-supplied names are sent verbatim (not `$`-prefixed).
116
+ */
117
+ eventName?: string;
118
+ id: string;
119
+ /** Resolved person properties for the session, written to `$set`. */
120
+ identifyActorData?: JsonRecord;
121
+ /** Resolved distinct id for the session (from `identify().distinctId`). */
122
+ identifyActorGivenId?: string;
123
+ ipAddress?: string;
124
+ isError?: boolean;
125
+ listedToolNames?: string[];
126
+ parameters?: unknown;
127
+ properties?: JsonRecord | null;
128
+ resourceName?: string;
129
+ response?: unknown;
130
+ sdkLanguage?: string;
131
+ sdkVersion?: string;
132
+ serverName?: string;
133
+ serverVersion?: string;
134
+ sessionId: string;
135
+ timestamp: Date;
136
+ toolDescription?: string;
137
+ userIntent?: string;
138
+ userIntentSource?: MCPAnalyticsIntentSource;
139
+ }
140
+ /** A partially-built MCP event as it flows through the SDK before capture. */
141
+ export type McpEvent = Partial<Event>;
142
+ export interface CompatibleRequestHandlerExtra {
143
+ headers?: Record<string, string | string[]>;
144
+ sessionId?: string;
145
+ [key: string]: unknown;
146
+ }
147
+ export interface ServerClientInfoLike {
148
+ name?: string;
149
+ version?: string;
150
+ }
151
+ export interface HighLevelMCPServerLike {
152
+ _registeredTools: {
153
+ [name: string]: RegisteredTool;
154
+ };
155
+ registerTool?(name: string, config: {
156
+ description?: string;
157
+ inputSchema?: unknown;
158
+ }, handler: ToolCallback): void;
159
+ server: MCPServerLike;
160
+ tool?(name: string, cb: ToolCallback): void;
161
+ tool?(name: string, paramsSchema: unknown, cb: ToolCallback): void;
162
+ tool?(name: string, description: string, paramsSchema: unknown, cb: ToolCallback): void;
163
+ }
164
+ export interface MCPServerLike {
165
+ _requestHandlers: Map<string, (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise<unknown>>;
166
+ _serverInfo?: ServerClientInfoLike;
167
+ getClientVersion(): ServerClientInfoLike | undefined;
168
+ setRequestHandler(schema: unknown, handler: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise<unknown>): void;
169
+ }
170
+ export interface UserIdentity {
171
+ /**
172
+ * The person's distinct id (becomes `distinct_id`). Same concept as
173
+ * posthog-node's `identify({ distinctId })`.
174
+ */
175
+ distinctId: string;
176
+ /**
177
+ * Person properties, written to `$set` (e.g. `{ name, email, plan }`) — the
178
+ * same `properties` you'd pass to posthog-node's `identify`.
179
+ */
180
+ properties?: JsonRecord;
181
+ /**
182
+ * PostHog group memberships as `{ groupType: groupKey }`. Stamped onto every
183
+ * event for the session as `$groups`, so callers never hand-write the
184
+ * `$groups` dollar-key themselves.
185
+ */
186
+ groups?: Record<string, string>;
187
+ }
188
+ export interface SessionInfo {
189
+ clientName?: string;
190
+ clientVersion?: string;
191
+ identifyActorData?: JsonRecord;
192
+ identifyActorGivenId?: string;
193
+ identifyActorGroups?: Record<string, string>;
194
+ ipAddress?: string;
195
+ sdkLanguage?: string;
196
+ sdkVersion?: string;
197
+ serverName?: string;
198
+ serverVersion?: string;
199
+ }
200
+ export interface MCPAnalyticsData {
201
+ sink: McpEventSink | undefined;
202
+ identifiedSessions: IdentityCache;
203
+ lastActivity: Date;
204
+ lastMcpSessionId?: string;
205
+ options: MCPAnalyticsOptions;
206
+ sessionId: string;
207
+ sessionInfo: SessionInfo;
208
+ sessionSource: 'generated' | 'mcp';
209
+ toolDescriptions: Map<string, string>;
210
+ }
211
+ export interface CaptureEventData {
212
+ /**
213
+ * PostHog event name (required). Sent verbatim — a custom event is a
214
+ * customer-defined event, so it is NOT `$`-prefixed.
215
+ */
216
+ event: string;
217
+ /** Event properties, spread onto the PostHog event. Values must be JSON-serializable. */
218
+ properties?: JsonRecord;
219
+ }
220
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.r = (exports1)=>{
5
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
6
+ value: 'Module'
7
+ });
8
+ Object.defineProperty(exports1, '__esModule', {
9
+ value: true
10
+ });
11
+ };
12
+ })();
13
+ var __webpack_exports__ = {};
14
+ __webpack_require__.r(__webpack_exports__);
15
+ for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
16
+ Object.defineProperty(exports, '__esModule', {
17
+ value: true
18
+ });
package/dist/types.mjs ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ export declare const version = "0.1.17";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAA"}
@@ -0,0 +1,36 @@
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
+ version: ()=>version
28
+ });
29
+ const version = '0.1.17';
30
+ exports.version = __webpack_exports__.version;
31
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
32
+ "version"
33
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
34
+ Object.defineProperty(exports, '__esModule', {
35
+ value: true
36
+ });
@@ -0,0 +1,2 @@
1
+ const version = '0.1.17';
2
+ export { version };
package/package.json CHANGED
@@ -1,105 +1,73 @@
1
1
  {
2
2
  "name": "@posthog/mcp",
3
- "version": "0.0.9",
4
- "description": "PostHog SDK for MCP servers",
5
- "type": "module",
6
- "main": "dist/index.cjs",
7
- "module": "dist/index.mjs",
8
- "types": "dist/index.d.mts",
9
- "exports": {
10
- ".": {
11
- "import": {
12
- "types": "./dist/index.d.mts",
13
- "default": "./dist/index.mjs"
14
- },
15
- "require": {
16
- "types": "./dist/index.d.cts",
17
- "default": "./dist/index.cjs"
18
- }
19
- }
20
- },
21
- "scripts": {
22
- "build": "tsdown",
23
- "dev": "tsdown --watch",
24
- "test": "vitest",
25
- "test:compatibility": "vitest run src/tests/mcp-version-compatibility.test.ts",
26
- "check": "ultracite check --error-on-warnings .",
27
- "fix": "ultracite fix .",
28
- "typecheck": "tsgo --noEmit",
29
- "typecheck:tsc6": "tsc6 --noEmit",
30
- "bump": "changeset version",
31
- "prepare": "husky",
32
- "verify": "pnpm check && pnpm typecheck && pnpm test --no-watch && pnpm build",
33
- "prepublishOnly": "pnpm verify"
34
- },
35
- "keywords": [
36
- "ai-agents",
37
- "analytics",
38
- "mcp",
39
- "mcp-server",
40
- "model-context-protocol",
41
- "observability",
42
- "posthog"
43
- ],
44
- "author": "PostHog",
45
- "license": "MIT",
3
+ "version": "0.1.17",
4
+ "description": "PostHog SDK for Model Context Protocol (MCP) servers — tracks tool usage, intent, and identity",
46
5
  "repository": {
47
6
  "type": "git",
48
- "url": "git+https://github.com/PostHog/mcp-analytics.git"
7
+ "url": "git+https://github.com/PostHog/posthog-js.git",
8
+ "directory": "packages/mcp"
49
9
  },
50
- "bugs": {
51
- "url": "https://github.com/PostHog/mcp-analytics/issues"
10
+ "engines": {
11
+ "node": "^20.20.0 || >=22.22.0"
52
12
  },
53
- "homepage": "https://github.com/PostHog/mcp-analytics#readme",
54
13
  "files": [
14
+ "src",
55
15
  "dist",
56
- "README.md",
57
- "LICENSE"
16
+ "!src/__tests__"
58
17
  ],
59
- "publishConfig": {
60
- "access": "public"
18
+ "license": "MIT",
19
+ "author": {
20
+ "name": "PostHog",
21
+ "email": "engineering@posthog.com",
22
+ "url": "https://posthog.com"
61
23
  },
62
- "engines": {
63
- "node": ">=22.22.0"
24
+ "main": "dist/index.js",
25
+ "module": "dist/index.mjs",
26
+ "types": "dist/index.d.ts",
27
+ "dependencies": {
28
+ "@posthog/core": "1.30.12"
64
29
  },
65
- "packageManager": "pnpm@10.33.2",
66
30
  "devDependencies": {
67
- "@biomejs/biome": "2.4.14",
68
- "@changesets/cli": "^2.29.8",
69
- "@modelcontextprotocol/sdk": "~1.24.2",
70
- "@types/node": "^22.15.21",
71
- "@typescript/native-preview": "beta",
72
- "@vitest/coverage-v8": "^4.0.14",
73
- "@vitest/ui": "^4.0.14",
74
- "husky": "^9.1.7",
75
- "tsdown": "^0.21.10",
76
- "typescript": "npm:@typescript/typescript6@^6.0.0",
77
- "ultracite": "7.6.3",
78
- "vitest": "^4.0.14",
79
- "zod": "^3.25 || ^4.0"
31
+ "@babel/preset-env": "^7.27.1",
32
+ "@babel/preset-typescript": "^7.27.1",
33
+ "@modelcontextprotocol/sdk": "~1.29.0",
34
+ "@rslib/core": "0.10.6",
35
+ "@types/jest": "^29.5.14",
36
+ "@types/node": "^20.0.0",
37
+ "jest": "29.7.0",
38
+ "zod": "^3.25.0",
39
+ "posthog-node": "5.36.6",
40
+ "@posthog-tooling/tsconfig-base": "1.1.1"
80
41
  },
81
42
  "peerDependencies": {
82
- "@modelcontextprotocol/sdk": ">=1.11"
43
+ "@modelcontextprotocol/sdk": ">=1.26.0",
44
+ "posthog-node": "^5.0.0"
83
45
  },
84
- "pnpm": {
85
- "overrides": {
86
- "js-yaml": ">=4.1.1",
87
- "read-yaml-file": "^2.1.0",
88
- "tmp": ">=0.2.4",
89
- "vite": ">=6.4.1",
90
- "body-parser": ">=2.2.1",
91
- "brace-expansion": "2.0.2"
92
- },
93
- "overridesComments": {
94
- "js-yaml": "Fixes GHSA-mh29-5h37-fv8m (prototype pollution in merge) - via @changesets/cli",
95
- "read-yaml-file": "v1 uses yaml.safeLoad which was removed in js-yaml 4 — force v2 which uses yaml.load - via @changesets/cli",
96
- "tmp": "Fixes GHSA-52f5-9888-hmc6 (symlink attack) - via @changesets/cli",
97
- "vite": "Fixes GHSA-93m4-6634-74q7 and other vite security issues - via vitest",
98
- "body-parser": "Fixes GHSA-wqch-xfxh-vrr4 (DoS via url encoding) - via @modelcontextprotocol/sdk",
99
- "brace-expansion": "Fixes GHSA-v6h2-p8h4-qcjw (ReDoS vulnerability) - via eslint"
46
+ "keywords": [
47
+ "posthog",
48
+ "mcp",
49
+ "model-context-protocol",
50
+ "analytics",
51
+ "llm"
52
+ ],
53
+ "exports": {
54
+ ".": {
55
+ "types": "./dist/index.d.ts",
56
+ "import": "./dist/index.mjs",
57
+ "require": "./dist/index.js",
58
+ "default": "./dist/index.js"
100
59
  }
101
60
  },
102
- "dependencies": {
103
- "posthog-node": "^5.33.3"
61
+ "scripts": {
62
+ "clean": "rimraf dist coverage",
63
+ "lint": "eslint src",
64
+ "lint:fix": "eslint src --fix",
65
+ "generate-version": "node -p \"'export const version = \\'' + require('./package.json').version + '\\''\" > src/version.ts",
66
+ "pretest:unit": "pnpm generate-version",
67
+ "test:unit": "jest",
68
+ "prebuild": "pnpm generate-version",
69
+ "build": "rslib build",
70
+ "dev": "rslib build -w",
71
+ "package": "pnpm pack --out $PACKAGE_DEST/%s.tgz"
104
72
  }
105
- }
73
+ }
@@ -0,0 +1,68 @@
1
+ import type { MCPServerLike, McpEvent } from '../types'
2
+ import { MCPAnalyticsEventType } from './event-types'
3
+ import { getServerTrackingData } from './internal'
4
+ import { log } from './logger'
5
+ import { getSessionInfo } from './session'
6
+
7
+ /**
8
+ * Materializes an `McpEvent` against the server's tracking data + session info,
9
+ * then hands it to the `McpEventSink` (wrapping the user's posthog-node client) for the
10
+ * sanitize/truncate/beforeSend pipeline and capture. No-ops if the server isn't tracked or
11
+ * no PostHog client is attached — not passing `posthog` is how you turn capture off.
12
+ *
13
+ * Returns the sink's capture promise so the user-facing `capture()` can await it.
14
+ * Auto-capture callers (tool calls, listings, identify) intentionally ignore the
15
+ * return value, keeping the tool path isolated from analytics latency/errors.
16
+ */
17
+ export function captureEvent(server: MCPServerLike, eventInput: McpEvent): Promise<void> | undefined {
18
+ const data = getServerTrackingData(server)
19
+ if (!data) {
20
+ log('Warning: Server tracking data not found. Event will not be published.')
21
+ return
22
+ }
23
+
24
+ const sink = data.sink
25
+ if (!sink) {
26
+ return
27
+ }
28
+
29
+ const sessionInfo = getSessionInfo(server, data, eventInput.sessionId)
30
+
31
+ const duration =
32
+ eventInput.duration || (eventInput.timestamp ? Date.now() - eventInput.timestamp.getTime() : undefined)
33
+
34
+ const fullEvent: McpEvent = {
35
+ id: eventInput.id || '',
36
+ sessionId: eventInput.sessionId || data.sessionId,
37
+ eventType: eventInput.eventType || MCPAnalyticsEventType.custom,
38
+ eventName: eventInput.eventName,
39
+ timestamp: eventInput.timestamp || new Date(),
40
+ duration,
41
+ ipAddress: sessionInfo.ipAddress,
42
+ sdkLanguage: sessionInfo.sdkLanguage,
43
+ sdkVersion: sessionInfo.sdkVersion,
44
+ serverName: sessionInfo.serverName,
45
+ serverVersion: sessionInfo.serverVersion,
46
+ clientName: sessionInfo.clientName,
47
+ clientVersion: sessionInfo.clientVersion,
48
+ identifyActorGivenId: sessionInfo.identifyActorGivenId,
49
+ identifyActorData: sessionInfo.identifyActorData,
50
+ groups: sessionInfo.identifyActorGroups,
51
+ resourceName: eventInput.resourceName,
52
+ toolDescription: eventInput.toolDescription,
53
+ listedToolNames: eventInput.listedToolNames,
54
+ parameters: eventInput.parameters,
55
+ response: eventInput.response,
56
+ userIntent: eventInput.userIntent,
57
+ userIntentSource: eventInput.userIntentSource,
58
+ isError: eventInput.isError,
59
+ error: eventInput.error,
60
+ conversationId: eventInput.conversationId,
61
+ properties: eventInput.properties,
62
+ }
63
+
64
+ return sink.capture(fullEvent, {
65
+ enableExceptionAutocapture: data.options.enableExceptionAutocapture ?? true,
66
+ beforeSend: data.options.beforeSend,
67
+ })
68
+ }
@@ -0,0 +1,138 @@
1
+ import type { HighLevelMCPServerLike, MCPServerLike } from '../types'
2
+ import { log } from './logger'
3
+
4
+ type ServerRecord = Record<string, unknown>
5
+
6
+ /**
7
+ * PostHog MCP analytics Compatibility Module
8
+ *
9
+ * This module ensures compatibility with Model Context Protocol TypeScript SDK.
10
+ * PostHog MCP analytics only supports MCP SDK version 1.11 and above.
11
+ *
12
+ * Version 1.11+ is required because it introduced stable APIs for:
13
+ * - Tool registration and handling
14
+ * - Request handler access patterns
15
+ * - Client version detection
16
+ * - Server info structure
17
+ */
18
+
19
+ // Function to log compatibility information
20
+ export function logCompatibilityWarning(): void {
21
+ log(
22
+ 'PostHog MCP analytics SDK Compatibility: This version only supports Model Context Protocol TypeScript SDK v1.11 and above. Please upgrade if using an older version.'
23
+ )
24
+ }
25
+
26
+ // Check if server has high-level structure (wrapper with .server property)
27
+ export function isHighLevelServer(server: unknown): server is ServerRecord & { server: ServerRecord } {
28
+ return (
29
+ !!server && typeof server === 'object' && 'server' in server && !!server.server && typeof server.server === 'object'
30
+ )
31
+ }
32
+
33
+ // Check if server has low-level structure (no .server property)
34
+ export function isLowLevelServer(server: unknown): server is ServerRecord {
35
+ return !!server && typeof server === 'object' && !('server' in server)
36
+ }
37
+
38
+ // Type guard function that validates server compatibility and returns typed server
39
+ export function isCompatibleServerType(server: unknown): MCPServerLike | HighLevelMCPServerLike {
40
+ if (!server || typeof server !== 'object') {
41
+ logCompatibilityWarning()
42
+ throw new Error(
43
+ "PostHog MCP analytics SDK compatibility error: Server must be an object. Ensure you're using MCP SDK v1.11 or higher."
44
+ )
45
+ }
46
+
47
+ if (isHighLevelServer(server)) {
48
+ // Validate high-level server requirements
49
+ if (!server._registeredTools || typeof server._registeredTools !== 'object') {
50
+ logCompatibilityWarning()
51
+ throw new Error(
52
+ 'PostHog MCP analytics SDK compatibility error: High-level server must have _registeredTools object. This requires MCP SDK v1.11 or higher.'
53
+ )
54
+ }
55
+ if (typeof server.tool !== 'function') {
56
+ logCompatibilityWarning()
57
+ throw new Error(
58
+ 'PostHog MCP analytics SDK compatibility error: High-level server must have tool() method. This requires MCP SDK v1.11 or higher.'
59
+ )
60
+ }
61
+
62
+ // Validate the underlying low-level server
63
+ const targetServer = server.server
64
+ validateLowLevelServer(targetServer)
65
+
66
+ return server as unknown as HighLevelMCPServerLike
67
+ }
68
+ // Direct low-level server validation
69
+ validateLowLevelServer(server)
70
+ return server as MCPServerLike
71
+ }
72
+
73
+ // Helper function to validate low-level server requirements
74
+ function validateLowLevelServer(server: unknown): void {
75
+ if (!server || typeof server !== 'object') {
76
+ logCompatibilityWarning()
77
+ throw new Error(
78
+ "PostHog MCP analytics SDK compatibility error: Server must be an object. Ensure you're using MCP SDK v1.11 or higher."
79
+ )
80
+ }
81
+
82
+ const serverRecord = server as ServerRecord
83
+
84
+ if (typeof serverRecord.setRequestHandler !== 'function') {
85
+ logCompatibilityWarning()
86
+ throw new Error(
87
+ 'PostHog MCP analytics SDK compatibility error: Server must have a setRequestHandler method. This requires MCP SDK v1.11 or higher.'
88
+ )
89
+ }
90
+
91
+ if (!(serverRecord._requestHandlers && serverRecord._requestHandlers instanceof Map)) {
92
+ logCompatibilityWarning()
93
+ throw new Error(
94
+ 'PostHog MCP analytics SDK compatibility error: Server._requestHandlers is not accessible. This requires MCP SDK v1.11 or higher.'
95
+ )
96
+ }
97
+
98
+ // Validate that _requestHandlers contains functions with compatible signatures
99
+ if (typeof serverRecord._requestHandlers.get !== 'function') {
100
+ logCompatibilityWarning()
101
+ throw new Error(
102
+ 'PostHog MCP analytics SDK compatibility error: Server._requestHandlers must be a Map with a get method. This requires MCP SDK v1.11 or higher.'
103
+ )
104
+ }
105
+
106
+ if (typeof serverRecord.getClientVersion !== 'function') {
107
+ logCompatibilityWarning()
108
+ throw new Error(
109
+ 'PostHog MCP analytics SDK compatibility error: Server.getClientVersion must be a function. This requires MCP SDK v1.11 or higher.'
110
+ )
111
+ }
112
+
113
+ if (
114
+ !serverRecord._serverInfo ||
115
+ typeof serverRecord._serverInfo !== 'object' ||
116
+ !('name' in serverRecord._serverInfo)
117
+ ) {
118
+ logCompatibilityWarning()
119
+ throw new Error(
120
+ 'PostHog MCP analytics SDK compatibility error: Server._serverInfo is not accessible or missing name. This requires MCP SDK v1.11 or higher.'
121
+ )
122
+ }
123
+ }
124
+
125
+ export function getMCPCompatibleErrorMessage(error: unknown): string {
126
+ if (error instanceof Error) {
127
+ try {
128
+ return JSON.stringify(error, Object.getOwnPropertyNames(error))
129
+ } catch {
130
+ return 'Unknown error'
131
+ }
132
+ } else if (typeof error === 'string') {
133
+ return error
134
+ } else if (typeof error === 'object' && error !== null) {
135
+ return JSON.stringify(error)
136
+ }
137
+ return 'Unknown error'
138
+ }