@posthog/mcp 0.0.9 → 0.1.16

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,237 @@
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
+ cacheToolDescriptions: ()=>cacheToolDescriptions,
28
+ captureToolCall: ()=>captureToolCall,
29
+ instrumentInitializeHandler: ()=>instrumentInitializeHandler,
30
+ instrumentToolsListHandler: ()=>instrumentToolsListHandler
31
+ });
32
+ const types_js_namespaceObject = require("@modelcontextprotocol/sdk/types.js");
33
+ const external_context_parameters_js_namespaceObject = require("./context-parameters.js");
34
+ const external_conversation_id_js_namespaceObject = require("./conversation-id.js");
35
+ const external_capture_js_namespaceObject = require("./capture.js");
36
+ const external_event_types_js_namespaceObject = require("./event-types.js");
37
+ const external_exceptions_js_namespaceObject = require("./exceptions.js");
38
+ const external_intent_js_namespaceObject = require("./intent.js");
39
+ const external_internal_js_namespaceObject = require("./internal.js");
40
+ const external_logger_js_namespaceObject = require("./logger.js");
41
+ const external_mcp_payloads_js_namespaceObject = require("./mcp-payloads.js");
42
+ const external_session_js_namespaceObject = require("./session.js");
43
+ const external_tools_js_namespaceObject = require("./tools.js");
44
+ const external_tracing_helpers_js_namespaceObject = require("./tracing-helpers.js");
45
+ async function captureToolCall(params) {
46
+ const { server, data, request, extra, execute, eventType, explicitContextIntent, takeCapturedError } = params;
47
+ const conversation = (0, external_conversation_id_js_namespaceObject.resolveConversationId)(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
48
+ const downstreamRequest = conversation.conversationId ? (0, external_conversation_id_js_namespaceObject.cloneRequestWithoutConversationId)(request) : request;
49
+ const startTime = new Date();
50
+ const event = await prepareToolCallEvent(server, data, request, downstreamRequest, extra, startTime, conversation, eventType ?? external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpToolsCall);
51
+ if (event && explicitContextIntent) (0, external_intent_js_namespaceObject.setExplicitContextIntent)(event, explicitContextIntent);
52
+ let result;
53
+ try {
54
+ result = await execute(downstreamRequest);
55
+ } catch (error) {
56
+ publishFailedToolEvent(server, event, error, startTime, conversation);
57
+ throw error;
58
+ }
59
+ const finalResult = applyConversationPromptBack(event, result, conversation);
60
+ publishSuccessfulToolEvent(server, event, finalResult, startTime, takeCapturedError);
61
+ return finalResult;
62
+ }
63
+ async function prepareToolCallEvent(server, data, request, downstreamRequest, extra, startTime, conversation, eventType) {
64
+ try {
65
+ const sessionId = (0, external_session_js_namespaceObject.getServerSessionId)(server, extra);
66
+ await (0, external_internal_js_namespaceObject.handleIdentify)(server, data, sessionId, request, extra);
67
+ const toolName = request.params?.name;
68
+ const event = {
69
+ sessionId,
70
+ conversationId: conversation.conversationId,
71
+ resourceName: toolName || 'Unknown Tool Name',
72
+ parameters: (0, external_mcp_payloads_js_namespaceObject.buildCapturedMcpParameters)(downstreamRequest),
73
+ eventType,
74
+ timestamp: startTime,
75
+ toolDescription: toolName ? data.toolDescriptions.get(toolName) : void 0
76
+ };
77
+ await (0, external_tracing_helpers_js_namespaceObject.applyResolvedMetadata)(event, data, request, extra);
78
+ (0, external_intent_js_namespaceObject.setEventIntent)(event, await (0, external_intent_js_namespaceObject.resolveToolCallIntent)(data, request, extra));
79
+ return event;
80
+ } catch (error) {
81
+ (0, external_logger_js_namespaceObject.log)(`Warning: PostHog MCP analytics instrumentation failed for tool ${request.params?.name}, the tool will still run - ${error}`);
82
+ return null;
83
+ }
84
+ }
85
+ function applyConversationPromptBack(event, result, conversation) {
86
+ if (!conversation.minted) return result;
87
+ if ((0, external_conversation_id_js_namespaceObject.canInjectConversationIdPromptBack)(result)) return (0, external_conversation_id_js_namespaceObject.injectConversationIdPromptBack)(result, conversation.conversationId);
88
+ if (event) event.conversationId = void 0;
89
+ return result;
90
+ }
91
+ function publishSuccessfulToolEvent(server, event, result, startTime, takeCapturedError) {
92
+ if (!event) return;
93
+ try {
94
+ if ((0, external_tracing_helpers_js_namespaceObject.isToolResultError)(result)) {
95
+ event.isError = true;
96
+ const capturedError = takeCapturedError?.();
97
+ event.error = (0, external_exceptions_js_namespaceObject.captureException)(capturedError ?? result);
98
+ } else event.isError = false;
99
+ event.response = result;
100
+ event.duration = Date.now() - startTime.getTime();
101
+ (0, external_capture_js_namespaceObject.captureEvent)(server, event);
102
+ } catch (error) {
103
+ (0, external_logger_js_namespaceObject.log)(`Warning: PostHog MCP analytics failed to publish tool event - ${error}`);
104
+ }
105
+ }
106
+ function publishFailedToolEvent(server, event, error, startTime, conversation) {
107
+ if (!event) return;
108
+ try {
109
+ if (conversation.minted) event.conversationId = void 0;
110
+ event.isError = true;
111
+ event.error = (0, external_exceptions_js_namespaceObject.captureException)(error);
112
+ event.duration = Date.now() - startTime.getTime();
113
+ (0, external_capture_js_namespaceObject.captureEvent)(server, event);
114
+ } catch (publishError) {
115
+ (0, external_logger_js_namespaceObject.log)(`Warning: PostHog MCP analytics failed to publish failed tool event - ${publishError}`);
116
+ }
117
+ }
118
+ const listToolsTracingSetup = new WeakMap();
119
+ function instrumentToolsListHandler(server) {
120
+ if (!server._capabilities?.tools) return;
121
+ if (listToolsTracingSetup.get(server)) return;
122
+ const originalListToolsHandler = server._requestHandlers.get('tools/list');
123
+ if (!originalListToolsHandler) return;
124
+ try {
125
+ server.setRequestHandler(types_js_namespaceObject.ListToolsRequestSchema, async (request, extra)=>await handleListToolsRequest(server, originalListToolsHandler, request, extra));
126
+ listToolsTracingSetup.set(server, true);
127
+ } catch (error) {
128
+ (0, external_logger_js_namespaceObject.log)(`Warning: Failed to override list tools handler - ${error}`);
129
+ }
130
+ }
131
+ async function handleListToolsRequest(server, originalListToolsHandler, request, extra) {
132
+ const data = (0, external_internal_js_namespaceObject.getServerTrackingData)(server);
133
+ const startTime = new Date();
134
+ const event = {
135
+ sessionId: (0, external_session_js_namespaceObject.getServerSessionId)(server, extra),
136
+ parameters: (0, external_mcp_payloads_js_namespaceObject.buildCapturedMcpParameters)(request),
137
+ eventType: external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpToolsList,
138
+ timestamp: startTime
139
+ };
140
+ if (data) await (0, external_tracing_helpers_js_namespaceObject.applyResolvedMetadata)(event, data, request, extra);
141
+ const tools = await getTracedToolsList(server, originalListToolsHandler, request, extra, event);
142
+ if (!data) {
143
+ (0, external_logger_js_namespaceObject.log)('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
144
+ return {
145
+ tools
146
+ };
147
+ }
148
+ if (0 === tools.length) {
149
+ (0, external_logger_js_namespaceObject.log)('Warning: No tools found in the original list. This is likely due to the tools not being registered before PostHog MCP analytics.instrument().');
150
+ event.error = (0, external_exceptions_js_namespaceObject.captureException)('No tools were sent to MCP client.');
151
+ event.isError = true;
152
+ event.duration = Date.now() - startTime.getTime();
153
+ (0, external_capture_js_namespaceObject.captureEvent)(server, event);
154
+ return {
155
+ tools
156
+ };
157
+ }
158
+ event.response = {
159
+ tools
160
+ };
161
+ event.listedToolNames = collectListedToolNames(tools);
162
+ event.isError = false;
163
+ event.duration = Date.now() - startTime.getTime();
164
+ (0, external_capture_js_namespaceObject.captureEvent)(server, event);
165
+ return {
166
+ tools
167
+ };
168
+ }
169
+ function collectListedToolNames(tools) {
170
+ if (!tools || 0 === tools.length) return;
171
+ const names = tools.map((tool)=>tool?.name).filter((name)=>'string' == typeof name);
172
+ return names.length > 0 ? names : void 0;
173
+ }
174
+ async function getTracedToolsList(server, originalListToolsHandler, request, extra, event) {
175
+ try {
176
+ const data = (0, external_internal_js_namespaceObject.getServerTrackingData)(server);
177
+ const originalResponse = await originalListToolsHandler(request, extra);
178
+ let tools = originalResponse.tools || [];
179
+ if (data && (0, external_context_parameters_js_namespaceObject.isContextEnabled)(data.options.context)) tools = (0, external_context_parameters_js_namespaceObject.addContextParameterToTools)(tools, (0, external_context_parameters_js_namespaceObject.getContextDescription)(data.options.context));
180
+ if (data?.options.enableConversationId) tools = (0, external_conversation_id_js_namespaceObject.addConversationIdToTools)(tools);
181
+ if (data?.options.reportMissing) {
182
+ const alreadyPresent = tools.some((tool)=>tool?.name === external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME);
183
+ if (!alreadyPresent) tools.push((0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)());
184
+ }
185
+ if (data) cacheToolDescriptions(data.toolDescriptions, tools);
186
+ return tools;
187
+ } catch (error) {
188
+ (0, external_logger_js_namespaceObject.log)(`Warning: Original list tools handler failed, this suggests an error PostHog MCP analytics did not cause - ${error}`);
189
+ event.error = (0, external_exceptions_js_namespaceObject.captureException)(error);
190
+ event.isError = true;
191
+ event.duration = event.timestamp ? Date.now() - event.timestamp.getTime() : 0;
192
+ (0, external_capture_js_namespaceObject.captureEvent)(server, event);
193
+ throw error;
194
+ }
195
+ }
196
+ function cacheToolDescriptions(cache, tools) {
197
+ if (!tools) return;
198
+ for (const tool of tools)if (tool?.name && 'string' == typeof tool.description) cache.set(tool.name, tool.description);
199
+ }
200
+ function instrumentInitializeHandler(server) {
201
+ const originalInitializeHandler = server._requestHandlers.get('initialize');
202
+ if (!originalInitializeHandler) return;
203
+ server.setRequestHandler(types_js_namespaceObject.InitializeRequestSchema, async (request, extra)=>{
204
+ const data = (0, external_internal_js_namespaceObject.getServerTrackingData)(server);
205
+ if (!data) {
206
+ (0, external_logger_js_namespaceObject.log)('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
207
+ return await originalInitializeHandler(request, extra);
208
+ }
209
+ const sessionId = (0, external_session_js_namespaceObject.getServerSessionId)(server, extra);
210
+ await (0, external_internal_js_namespaceObject.handleIdentify)(server, data, sessionId, request, extra);
211
+ const event = {
212
+ sessionId,
213
+ resourceName: request.params?.name || 'Unknown Tool Name',
214
+ eventType: external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpInitialize,
215
+ parameters: (0, external_mcp_payloads_js_namespaceObject.buildCapturedMcpParameters)(request),
216
+ timestamp: new Date()
217
+ };
218
+ await (0, external_tracing_helpers_js_namespaceObject.applyResolvedMetadata)(event, data, request, extra);
219
+ const result = await originalInitializeHandler(request, extra);
220
+ event.response = result;
221
+ (0, external_capture_js_namespaceObject.captureEvent)(server, event);
222
+ return result;
223
+ });
224
+ }
225
+ exports.cacheToolDescriptions = __webpack_exports__.cacheToolDescriptions;
226
+ exports.captureToolCall = __webpack_exports__.captureToolCall;
227
+ exports.instrumentInitializeHandler = __webpack_exports__.instrumentInitializeHandler;
228
+ exports.instrumentToolsListHandler = __webpack_exports__.instrumentToolsListHandler;
229
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
230
+ "cacheToolDescriptions",
231
+ "captureToolCall",
232
+ "instrumentInitializeHandler",
233
+ "instrumentToolsListHandler"
234
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
235
+ Object.defineProperty(exports, '__esModule', {
236
+ value: true
237
+ });
@@ -0,0 +1,194 @@
1
+ import { InitializeRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
2
+ import { addContextParameterToTools, getContextDescription, isContextEnabled } from "./context-parameters.mjs";
3
+ import { addConversationIdToTools, canInjectConversationIdPromptBack, cloneRequestWithoutConversationId, injectConversationIdPromptBack, resolveConversationId } from "./conversation-id.mjs";
4
+ import { captureEvent } from "./capture.mjs";
5
+ import { MCPAnalyticsEventType } from "./event-types.mjs";
6
+ import { captureException } from "./exceptions.mjs";
7
+ import { resolveToolCallIntent, setEventIntent, setExplicitContextIntent } from "./intent.mjs";
8
+ import { getServerTrackingData, handleIdentify } from "./internal.mjs";
9
+ import { log } from "./logger.mjs";
10
+ import { buildCapturedMcpParameters } from "./mcp-payloads.mjs";
11
+ import { getServerSessionId } from "./session.mjs";
12
+ import { GET_MORE_TOOLS_NAME, getReportMissingToolDescriptor } from "./tools.mjs";
13
+ import { applyResolvedMetadata, isToolResultError } from "./tracing-helpers.mjs";
14
+ async function captureToolCall(params) {
15
+ const { server, data, request, extra, execute, eventType, explicitContextIntent, takeCapturedError } = params;
16
+ const conversation = resolveConversationId(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
17
+ const downstreamRequest = conversation.conversationId ? cloneRequestWithoutConversationId(request) : request;
18
+ const startTime = new Date();
19
+ const event = await prepareToolCallEvent(server, data, request, downstreamRequest, extra, startTime, conversation, eventType ?? MCPAnalyticsEventType.mcpToolsCall);
20
+ if (event && explicitContextIntent) setExplicitContextIntent(event, explicitContextIntent);
21
+ let result;
22
+ try {
23
+ result = await execute(downstreamRequest);
24
+ } catch (error) {
25
+ publishFailedToolEvent(server, event, error, startTime, conversation);
26
+ throw error;
27
+ }
28
+ const finalResult = applyConversationPromptBack(event, result, conversation);
29
+ publishSuccessfulToolEvent(server, event, finalResult, startTime, takeCapturedError);
30
+ return finalResult;
31
+ }
32
+ async function prepareToolCallEvent(server, data, request, downstreamRequest, extra, startTime, conversation, eventType) {
33
+ try {
34
+ const sessionId = getServerSessionId(server, extra);
35
+ await handleIdentify(server, data, sessionId, request, extra);
36
+ const toolName = request.params?.name;
37
+ const event = {
38
+ sessionId,
39
+ conversationId: conversation.conversationId,
40
+ resourceName: toolName || 'Unknown Tool Name',
41
+ parameters: buildCapturedMcpParameters(downstreamRequest),
42
+ eventType,
43
+ timestamp: startTime,
44
+ toolDescription: toolName ? data.toolDescriptions.get(toolName) : void 0
45
+ };
46
+ await applyResolvedMetadata(event, data, request, extra);
47
+ setEventIntent(event, await resolveToolCallIntent(data, request, extra));
48
+ return event;
49
+ } catch (error) {
50
+ log(`Warning: PostHog MCP analytics instrumentation failed for tool ${request.params?.name}, the tool will still run - ${error}`);
51
+ return null;
52
+ }
53
+ }
54
+ function applyConversationPromptBack(event, result, conversation) {
55
+ if (!conversation.minted) return result;
56
+ if (canInjectConversationIdPromptBack(result)) return injectConversationIdPromptBack(result, conversation.conversationId);
57
+ if (event) event.conversationId = void 0;
58
+ return result;
59
+ }
60
+ function publishSuccessfulToolEvent(server, event, result, startTime, takeCapturedError) {
61
+ if (!event) return;
62
+ try {
63
+ if (isToolResultError(result)) {
64
+ event.isError = true;
65
+ const capturedError = takeCapturedError?.();
66
+ event.error = captureException(capturedError ?? result);
67
+ } else event.isError = false;
68
+ event.response = result;
69
+ event.duration = Date.now() - startTime.getTime();
70
+ captureEvent(server, event);
71
+ } catch (error) {
72
+ log(`Warning: PostHog MCP analytics failed to publish tool event - ${error}`);
73
+ }
74
+ }
75
+ function publishFailedToolEvent(server, event, error, startTime, conversation) {
76
+ if (!event) return;
77
+ try {
78
+ if (conversation.minted) event.conversationId = void 0;
79
+ event.isError = true;
80
+ event.error = captureException(error);
81
+ event.duration = Date.now() - startTime.getTime();
82
+ captureEvent(server, event);
83
+ } catch (publishError) {
84
+ log(`Warning: PostHog MCP analytics failed to publish failed tool event - ${publishError}`);
85
+ }
86
+ }
87
+ const listToolsTracingSetup = new WeakMap();
88
+ function instrumentToolsListHandler(server) {
89
+ if (!server._capabilities?.tools) return;
90
+ if (listToolsTracingSetup.get(server)) return;
91
+ const originalListToolsHandler = server._requestHandlers.get('tools/list');
92
+ if (!originalListToolsHandler) return;
93
+ try {
94
+ server.setRequestHandler(ListToolsRequestSchema, async (request, extra)=>await handleListToolsRequest(server, originalListToolsHandler, request, extra));
95
+ listToolsTracingSetup.set(server, true);
96
+ } catch (error) {
97
+ log(`Warning: Failed to override list tools handler - ${error}`);
98
+ }
99
+ }
100
+ async function handleListToolsRequest(server, originalListToolsHandler, request, extra) {
101
+ const data = getServerTrackingData(server);
102
+ const startTime = new Date();
103
+ const event = {
104
+ sessionId: getServerSessionId(server, extra),
105
+ parameters: buildCapturedMcpParameters(request),
106
+ eventType: MCPAnalyticsEventType.mcpToolsList,
107
+ timestamp: startTime
108
+ };
109
+ if (data) await applyResolvedMetadata(event, data, request, extra);
110
+ const tools = await getTracedToolsList(server, originalListToolsHandler, request, extra, event);
111
+ if (!data) {
112
+ log('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
113
+ return {
114
+ tools
115
+ };
116
+ }
117
+ if (0 === tools.length) {
118
+ log('Warning: No tools found in the original list. This is likely due to the tools not being registered before PostHog MCP analytics.instrument().');
119
+ event.error = captureException('No tools were sent to MCP client.');
120
+ event.isError = true;
121
+ event.duration = Date.now() - startTime.getTime();
122
+ captureEvent(server, event);
123
+ return {
124
+ tools
125
+ };
126
+ }
127
+ event.response = {
128
+ tools
129
+ };
130
+ event.listedToolNames = collectListedToolNames(tools);
131
+ event.isError = false;
132
+ event.duration = Date.now() - startTime.getTime();
133
+ captureEvent(server, event);
134
+ return {
135
+ tools
136
+ };
137
+ }
138
+ function collectListedToolNames(tools) {
139
+ if (!tools || 0 === tools.length) return;
140
+ const names = tools.map((tool)=>tool?.name).filter((name)=>'string' == typeof name);
141
+ return names.length > 0 ? names : void 0;
142
+ }
143
+ async function getTracedToolsList(server, originalListToolsHandler, request, extra, event) {
144
+ try {
145
+ const data = getServerTrackingData(server);
146
+ const originalResponse = await originalListToolsHandler(request, extra);
147
+ let tools = originalResponse.tools || [];
148
+ if (data && isContextEnabled(data.options.context)) tools = addContextParameterToTools(tools, getContextDescription(data.options.context));
149
+ if (data?.options.enableConversationId) tools = addConversationIdToTools(tools);
150
+ if (data?.options.reportMissing) {
151
+ const alreadyPresent = tools.some((tool)=>tool?.name === GET_MORE_TOOLS_NAME);
152
+ if (!alreadyPresent) tools.push(getReportMissingToolDescriptor());
153
+ }
154
+ if (data) cacheToolDescriptions(data.toolDescriptions, tools);
155
+ return tools;
156
+ } catch (error) {
157
+ log(`Warning: Original list tools handler failed, this suggests an error PostHog MCP analytics did not cause - ${error}`);
158
+ event.error = captureException(error);
159
+ event.isError = true;
160
+ event.duration = event.timestamp ? Date.now() - event.timestamp.getTime() : 0;
161
+ captureEvent(server, event);
162
+ throw error;
163
+ }
164
+ }
165
+ function cacheToolDescriptions(cache, tools) {
166
+ if (!tools) return;
167
+ for (const tool of tools)if (tool?.name && 'string' == typeof tool.description) cache.set(tool.name, tool.description);
168
+ }
169
+ function instrumentInitializeHandler(server) {
170
+ const originalInitializeHandler = server._requestHandlers.get('initialize');
171
+ if (!originalInitializeHandler) return;
172
+ server.setRequestHandler(InitializeRequestSchema, async (request, extra)=>{
173
+ const data = getServerTrackingData(server);
174
+ if (!data) {
175
+ log('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
176
+ return await originalInitializeHandler(request, extra);
177
+ }
178
+ const sessionId = getServerSessionId(server, extra);
179
+ await handleIdentify(server, data, sessionId, request, extra);
180
+ const event = {
181
+ sessionId,
182
+ resourceName: request.params?.name || 'Unknown Tool Name',
183
+ eventType: MCPAnalyticsEventType.mcpInitialize,
184
+ parameters: buildCapturedMcpParameters(request),
185
+ timestamp: new Date()
186
+ };
187
+ await applyResolvedMetadata(event, data, request, extra);
188
+ const result = await originalInitializeHandler(request, extra);
189
+ event.response = result;
190
+ captureEvent(server, event);
191
+ return result;
192
+ });
193
+ }
194
+ export { cacheToolDescriptions, captureToolCall, instrumentInitializeHandler, instrumentToolsListHandler };
@@ -0,0 +1,10 @@
1
+ import type { CompatibleRequestHandlerExtra, MCPAnalyticsData, MCPAnalyticsIntentSource, MCPRequestLike, McpEvent } from '../types';
2
+ interface ResolvedIntent {
3
+ intent: string;
4
+ source: MCPAnalyticsIntentSource;
5
+ }
6
+ export declare function resolveToolCallIntent(data: MCPAnalyticsData, request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra): Promise<ResolvedIntent | null>;
7
+ export declare function setEventIntent(event: McpEvent, resolvedIntent: ResolvedIntent | null): void;
8
+ export declare function setExplicitContextIntent(event: McpEvent, context: string): void;
9
+ export {};
10
+ //# sourceMappingURL=intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../src/extensions/intent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,EACd,QAAQ,EACT,MAAM,UAAU,CAAA;AAIjB,UAAU,cAAc;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,wBAAwB,CAAA;CACjC;AAkCD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAOhC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAO3F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQ/E"}
@@ -0,0 +1,84 @@
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
+ setExplicitContextIntent: ()=>setExplicitContextIntent,
28
+ resolveToolCallIntent: ()=>resolveToolCallIntent,
29
+ setEventIntent: ()=>setEventIntent
30
+ });
31
+ const external_context_parameters_js_namespaceObject = require("./context-parameters.js");
32
+ const external_logger_js_namespaceObject = require("./logger.js");
33
+ function getContextArgument(request) {
34
+ const context = request.params?.arguments?.context;
35
+ return 'string' == typeof context && context.trim() ? context : void 0;
36
+ }
37
+ function normalizeIntent(intent) {
38
+ if ('string' != typeof intent) return null;
39
+ const trimmed = intent.trim();
40
+ return trimmed ? trimmed : null;
41
+ }
42
+ async function runIntentFallback(data, request, extra) {
43
+ if (!data.options.intentFallback) return null;
44
+ try {
45
+ const intent = normalizeIntent(await data.options.intentFallback(request, extra));
46
+ return intent ? {
47
+ intent,
48
+ source: 'inferred'
49
+ } : null;
50
+ } catch (error) {
51
+ (0, external_logger_js_namespaceObject.log)(`intentFallback callback error: ${error}`);
52
+ return null;
53
+ }
54
+ }
55
+ async function resolveToolCallIntent(data, request, extra) {
56
+ const contextArgument = getContextArgument(request);
57
+ if ((0, external_context_parameters_js_namespaceObject.isContextEnabled)(data.options.context) && request.params?.name !== 'get_more_tools' && contextArgument) return {
58
+ intent: contextArgument,
59
+ source: 'context_parameter'
60
+ };
61
+ return await runIntentFallback(data, request, extra);
62
+ }
63
+ function setEventIntent(event, resolvedIntent) {
64
+ if (!resolvedIntent) return;
65
+ event.userIntent = resolvedIntent.intent;
66
+ event.userIntentSource = resolvedIntent.source;
67
+ }
68
+ function setExplicitContextIntent(event, context) {
69
+ const intent = normalizeIntent(context);
70
+ if (!intent) return;
71
+ event.userIntent = intent;
72
+ event.userIntentSource = 'context_parameter';
73
+ }
74
+ exports.resolveToolCallIntent = __webpack_exports__.resolveToolCallIntent;
75
+ exports.setEventIntent = __webpack_exports__.setEventIntent;
76
+ exports.setExplicitContextIntent = __webpack_exports__.setExplicitContextIntent;
77
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
78
+ "resolveToolCallIntent",
79
+ "setEventIntent",
80
+ "setExplicitContextIntent"
81
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
82
+ Object.defineProperty(exports, '__esModule', {
83
+ value: true
84
+ });
@@ -0,0 +1,44 @@
1
+ import { isContextEnabled } from "./context-parameters.mjs";
2
+ import { log } from "./logger.mjs";
3
+ function getContextArgument(request) {
4
+ const context = request.params?.arguments?.context;
5
+ return 'string' == typeof context && context.trim() ? context : void 0;
6
+ }
7
+ function normalizeIntent(intent) {
8
+ if ('string' != typeof intent) return null;
9
+ const trimmed = intent.trim();
10
+ return trimmed ? trimmed : null;
11
+ }
12
+ async function runIntentFallback(data, request, extra) {
13
+ if (!data.options.intentFallback) return null;
14
+ try {
15
+ const intent = normalizeIntent(await data.options.intentFallback(request, extra));
16
+ return intent ? {
17
+ intent,
18
+ source: 'inferred'
19
+ } : null;
20
+ } catch (error) {
21
+ log(`intentFallback callback error: ${error}`);
22
+ return null;
23
+ }
24
+ }
25
+ async function resolveToolCallIntent(data, request, extra) {
26
+ const contextArgument = getContextArgument(request);
27
+ if (isContextEnabled(data.options.context) && request.params?.name !== 'get_more_tools' && contextArgument) return {
28
+ intent: contextArgument,
29
+ source: 'context_parameter'
30
+ };
31
+ return await runIntentFallback(data, request, extra);
32
+ }
33
+ function setEventIntent(event, resolvedIntent) {
34
+ if (!resolvedIntent) return;
35
+ event.userIntent = resolvedIntent.intent;
36
+ event.userIntentSource = resolvedIntent.source;
37
+ }
38
+ function setExplicitContextIntent(event, context) {
39
+ const intent = normalizeIntent(context);
40
+ if (!intent) return;
41
+ event.userIntent = intent;
42
+ event.userIntentSource = 'context_parameter';
43
+ }
44
+ export { resolveToolCallIntent, setEventIntent, setExplicitContextIntent };
@@ -0,0 +1,32 @@
1
+ import type { CompatibleRequestHandlerExtra, MCPAnalyticsData, MCPRequestLike, MCPServerLike, UserIdentity } from '../types';
2
+ /**
3
+ * Bounded LRU cache for session identities, capped at `maxSize` entries so a
4
+ * long-lived server can't accumulate identities for unboundedly many sessions.
5
+ * One instance lives on each server's tracking data — it is NOT shared across
6
+ * server instances, so identities never bleed between servers.
7
+ */
8
+ export declare class IdentityCache {
9
+ private readonly _cache;
10
+ private readonly _maxSize;
11
+ constructor(maxSize?: number);
12
+ get(sessionId: string): UserIdentity | undefined;
13
+ set(sessionId: string, identity: UserIdentity): void;
14
+ has(sessionId: string): boolean;
15
+ size(): number;
16
+ }
17
+ export declare function getServerTrackingData(server: MCPServerLike): MCPAnalyticsData | undefined;
18
+ export declare function setServerTrackingData(server: MCPServerLike, data: MCPAnalyticsData): void;
19
+ export declare function areIdentitiesEqual(a: UserIdentity, b: UserIdentity): boolean;
20
+ export declare function mergeIdentities(previous: UserIdentity | undefined, next: UserIdentity): UserIdentity;
21
+ /**
22
+ * Resolves the optional `identify` callback, dedupes against the server's identity
23
+ * cache, and publishes an `$identify` event only when the identity has materially changed.
24
+ */
25
+ export declare function handleIdentify(server: MCPServerLike, data: MCPAnalyticsData, sessionId: string, request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra): Promise<void>;
26
+ /**
27
+ * Resolves the `eventProperties` callback. Returns null when no callback is
28
+ * configured, or when it returns nullish or throws — a throw never propagates
29
+ * into the tool path.
30
+ */
31
+ export declare function resolveEventProperties(data: MCPAnalyticsData, request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra): Promise<Record<string, unknown> | null>;
32
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/extensions/internal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,cAAc,EACd,aAAa,EAEb,YAAY,EACb,MAAM,UAAU,CAAA;AAKjB;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,OAAO,SAAO;IAI1B,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAWhD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAapD,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B,IAAI,IAAI,MAAM;CAGf;AAID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,SAAS,CAEzF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEzF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CA4B5E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,CAapG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAUzC"}