@posthog/mcp 0.0.3 → 0.0.5

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/dist/index.d.cts CHANGED
@@ -23,6 +23,7 @@ interface MCPAnalyticsOptions {
23
23
  apiKey?: string | null;
24
24
  context?: boolean | MCPAnalyticsContextOptions;
25
25
  enableAITracing?: boolean;
26
+ enableConversationId?: boolean;
26
27
  enableTracing?: boolean;
27
28
  eventProperties?: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => JsonRecord | null | Promise<JsonRecord | null>;
28
29
  eventTags?: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Record<string, string> | null | Promise<Record<string, string> | null>;
@@ -92,6 +93,7 @@ declare const PostHogMCPAnalyticsProperty: {
92
93
  readonly AiTraceId: "$ai_trace_id";
93
94
  readonly ClientName: "$mcp_client_name";
94
95
  readonly ClientVersion: "$mcp_client_version";
96
+ readonly ConversationId: "$mcp_conversation_id";
95
97
  readonly DurationMs: "$mcp_duration_ms";
96
98
  readonly IsError: "$mcp_is_error";
97
99
  readonly Intent: "$mcp_intent";
@@ -103,6 +105,7 @@ declare const PostHogMCPAnalyticsProperty: {
103
105
  readonly ServerVersion: "$mcp_server_version";
104
106
  readonly SessionId: "$session_id";
105
107
  readonly Source: "$mcp_source";
108
+ readonly ToolDescription: "$mcp_tool_description";
106
109
  readonly ToolName: "$mcp_tool_name";
107
110
  };
108
111
  type PostHogMCPAnalyticsProperty = (typeof PostHogMCPAnalyticsProperty)[keyof typeof PostHogMCPAnalyticsProperty];
package/dist/index.d.mts CHANGED
@@ -22,6 +22,7 @@ interface MCPAnalyticsOptions {
22
22
  apiKey?: string | null;
23
23
  context?: boolean | MCPAnalyticsContextOptions;
24
24
  enableAITracing?: boolean;
25
+ enableConversationId?: boolean;
25
26
  enableTracing?: boolean;
26
27
  eventProperties?: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => JsonRecord | null | Promise<JsonRecord | null>;
27
28
  eventTags?: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Record<string, string> | null | Promise<Record<string, string> | null>;
@@ -91,6 +92,7 @@ declare const PostHogMCPAnalyticsProperty: {
91
92
  readonly AiTraceId: "$ai_trace_id";
92
93
  readonly ClientName: "$mcp_client_name";
93
94
  readonly ClientVersion: "$mcp_client_version";
95
+ readonly ConversationId: "$mcp_conversation_id";
94
96
  readonly DurationMs: "$mcp_duration_ms";
95
97
  readonly IsError: "$mcp_is_error";
96
98
  readonly Intent: "$mcp_intent";
@@ -102,6 +104,7 @@ declare const PostHogMCPAnalyticsProperty: {
102
104
  readonly ServerVersion: "$mcp_server_version";
103
105
  readonly SessionId: "$session_id";
104
106
  readonly Source: "$mcp_source";
107
+ readonly ToolDescription: "$mcp_tool_description";
105
108
  readonly ToolName: "$mcp_tool_name";
106
109
  };
107
110
  type PostHogMCPAnalyticsProperty = (typeof PostHogMCPAnalyticsProperty)[keyof typeof PostHogMCPAnalyticsProperty];
package/dist/index.mjs CHANGED
@@ -349,6 +349,7 @@ function getRequestResourceName(request) {
349
349
  //#endregion
350
350
  //#region src/modules/constants.ts
351
351
  const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION = `Explain why you are calling this tool and how it fits into the user's overall goal. This parameter is used for analytics and user intent tracking. YOU MUST provide 15-25 words (count carefully). NEVER use first person ('I', 'we', 'you') - maintain third-person perspective. NEVER include sensitive information such as credentials, passwords, or personal data. Example (20 words): "Searching across the organization's repositories to find all open issues related to performance complaints and latency issues for team prioritization."`;
352
+ const DEFAULT_CONVERSATION_ID_DESCRIPTION = "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.";
352
353
  const POSTHOG_MCP_ANALYTICS_SOURCE = "posthog_mcp_analytics";
353
354
  const PostHogMCPAnalyticsEvent = {
354
355
  AiSpan: "$ai_span",
@@ -375,6 +376,7 @@ const PostHogMCPAnalyticsProperty = {
375
376
  AiTraceId: "$ai_trace_id",
376
377
  ClientName: "$mcp_client_name",
377
378
  ClientVersion: "$mcp_client_version",
379
+ ConversationId: "$mcp_conversation_id",
378
380
  DurationMs: "$mcp_duration_ms",
379
381
  IsError: "$mcp_is_error",
380
382
  Intent: "$mcp_intent",
@@ -386,6 +388,7 @@ const PostHogMCPAnalyticsProperty = {
386
388
  ServerVersion: "$mcp_server_version",
387
389
  SessionId: "$session_id",
388
390
  Source: "$mcp_source",
391
+ ToolDescription: "$mcp_tool_description",
389
392
  ToolName: "$mcp_tool_name"
390
393
  };
391
394
  //#endregion
@@ -420,6 +423,7 @@ function buildCaptureEvent(event, options) {
420
423
  [PostHogMCPAnalyticsProperty.SessionId]: event.sessionId,
421
424
  [PostHogMCPAnalyticsProperty.Source]: POSTHOG_MCP_ANALYTICS_SOURCE
422
425
  };
426
+ addConversationIdProperty(event, properties);
423
427
  addCommonEventProperties(event, properties);
424
428
  addTraceReferenceProperties(event, properties, options);
425
429
  addCustomEventProperties(event, properties);
@@ -445,11 +449,15 @@ function addTraceReferenceProperties(event, properties, options) {
445
449
  properties[PostHogMCPAnalyticsProperty.AiTraceId] = getAITraceId(event);
446
450
  properties[PostHogMCPAnalyticsProperty.AiSpanId] = getAISpanId(event);
447
451
  }
452
+ function addConversationIdProperty(event, properties) {
453
+ if (event.conversationId !== void 0 && event.conversationId !== "") properties[PostHogMCPAnalyticsProperty.ConversationId] = event.conversationId;
454
+ }
448
455
  function addCommonEventProperties(event, properties) {
449
456
  if (event.resourceName) {
450
457
  properties[PostHogMCPAnalyticsProperty.ResourceName] = event.resourceName;
451
458
  if (event.eventType === MCPAnalyticsEventType.mcpToolsCall) properties[PostHogMCPAnalyticsProperty.ToolName] = event.resourceName;
452
459
  }
460
+ if (event.toolDescription && event.eventType === MCPAnalyticsEventType.mcpToolsCall) properties[PostHogMCPAnalyticsProperty.ToolDescription] = event.toolDescription;
453
461
  if (event.duration !== void 0) properties[PostHogMCPAnalyticsProperty.DurationMs] = event.duration;
454
462
  if (event.serverName) properties[PostHogMCPAnalyticsProperty.ServerName] = event.serverName;
455
463
  if (event.serverVersion) properties[PostHogMCPAnalyticsProperty.ServerVersion] = event.serverVersion;
@@ -476,6 +484,7 @@ function buildExceptionEvent(event) {
476
484
  $exception_source: "backend",
477
485
  [PostHogMCPAnalyticsProperty.SessionId]: event.sessionId
478
486
  };
487
+ addConversationIdProperty(event, properties);
479
488
  if (event.error) {
480
489
  if (event.error.message) properties.$exception_message = event.error.message;
481
490
  if (event.error.type) properties.$exception_type = event.error.type;
@@ -485,6 +494,7 @@ function buildExceptionEvent(event) {
485
494
  properties[PostHogMCPAnalyticsProperty.ResourceName] = event.resourceName;
486
495
  if (event.eventType === MCPAnalyticsEventType.mcpToolsCall) properties[PostHogMCPAnalyticsProperty.ToolName] = event.resourceName;
487
496
  }
497
+ if (event.toolDescription && event.eventType === MCPAnalyticsEventType.mcpToolsCall) properties[PostHogMCPAnalyticsProperty.ToolDescription] = event.toolDescription;
488
498
  if (event.serverName) properties[PostHogMCPAnalyticsProperty.ServerName] = event.serverName;
489
499
  if (event.serverVersion) properties[PostHogMCPAnalyticsProperty.ServerVersion] = event.serverVersion;
490
500
  if (event.clientName) properties[PostHogMCPAnalyticsProperty.ClientName] = event.clientName;
@@ -509,6 +519,7 @@ function buildAISpanEvent(event) {
509
519
  [PostHogMCPAnalyticsProperty.SessionId]: event.sessionId,
510
520
  [PostHogMCPAnalyticsProperty.Source]: POSTHOG_MCP_ANALYTICS_SOURCE
511
521
  };
522
+ addConversationIdProperty(event, properties);
512
523
  if (event.duration !== void 0) properties[PostHogMCPAnalyticsProperty.AiLatency] = event.duration / 1e3;
513
524
  if (event.isError && event.error) properties.$ai_error = event.error;
514
525
  if (event.parameters !== void 0) properties[PostHogMCPAnalyticsProperty.AiInputState] = event.parameters;
@@ -543,6 +554,7 @@ const PROTECTED_FIELDS = new Set([
543
554
  "identifyActorName",
544
555
  "identifyData",
545
556
  "resourceName",
557
+ "toolDescription",
546
558
  "eventType",
547
559
  "actorId",
548
560
  "tags",
@@ -720,7 +732,7 @@ function sanitizeParameters(obj) {
720
732
  }
721
733
  //#endregion
722
734
  //#region package.json
723
- var version = "0.0.3";
735
+ var version = "0.0.5";
724
736
  //#endregion
725
737
  //#region src/modules/session.ts
726
738
  function newSessionId() {
@@ -1180,12 +1192,14 @@ function publishEvent(server, eventInput) {
1180
1192
  identifyActorName: sessionInfo.identifyActorName,
1181
1193
  identifyActorData: sessionInfo.identifyActorData,
1182
1194
  resourceName: eventInput.resourceName,
1195
+ toolDescription: eventInput.toolDescription,
1183
1196
  parameters: eventInput.parameters,
1184
1197
  response: eventInput.response,
1185
1198
  userIntent: eventInput.userIntent,
1186
1199
  userIntentSource: eventInput.userIntentSource,
1187
1200
  isError: eventInput.isError,
1188
1201
  error: eventInput.error,
1202
+ conversationId: eventInput.conversationId,
1189
1203
  redactionFn: eventInput.redactionFn,
1190
1204
  tags: eventInput.tags,
1191
1205
  properties: eventInput.properties
@@ -1922,6 +1936,112 @@ function setupMCPAnalyticsTools(server) {
1922
1936
  }
1923
1937
  }
1924
1938
  //#endregion
1939
+ //#region src/modules/conversation-id.ts
1940
+ const CONVERSATION_ID_PARAM_NAME = "conversation_id";
1941
+ function addConversationIdToTool(tool) {
1942
+ const modifiedTool = { ...tool };
1943
+ const toolName = tool.name || "unknown";
1944
+ const schema = modifiedTool.inputSchema;
1945
+ if (schema?.properties?.["conversation_id"]) {
1946
+ writeToLog(`WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`);
1947
+ return modifiedTool;
1948
+ }
1949
+ if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
1950
+ writeToLog(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`);
1951
+ return modifiedTool;
1952
+ }
1953
+ if (!modifiedTool.inputSchema) modifiedTool.inputSchema = {
1954
+ type: "object",
1955
+ properties: {},
1956
+ required: []
1957
+ };
1958
+ modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema));
1959
+ const inputSchema = modifiedTool.inputSchema;
1960
+ if (!inputSchema.properties) inputSchema.properties = {};
1961
+ if (inputSchema.additionalProperties === false) inputSchema.additionalProperties = void 0;
1962
+ inputSchema.properties[CONVERSATION_ID_PARAM_NAME] = {
1963
+ type: "string",
1964
+ description: DEFAULT_CONVERSATION_ID_DESCRIPTION
1965
+ };
1966
+ return modifiedTool;
1967
+ }
1968
+ function addConversationIdToTools(tools) {
1969
+ return tools.map((tool) => {
1970
+ if (tool.name === "get_more_tools") return tool;
1971
+ return addConversationIdToTool(tool);
1972
+ });
1973
+ }
1974
+ /**
1975
+ * Decides which conversation_id to use for a tool call:
1976
+ * - disabled or get_more_tools → none
1977
+ * - agent supplied a value → use it
1978
+ * - agent omitted → mint a UUID
1979
+ */
1980
+ function resolveConversationId(enabled, args, toolName) {
1981
+ if (!enabled || toolName === "get_more_tools") return {
1982
+ minted: false,
1983
+ conversationId: void 0
1984
+ };
1985
+ const supplied = extractConversationId(args);
1986
+ if (supplied) return {
1987
+ minted: false,
1988
+ conversationId: supplied
1989
+ };
1990
+ return {
1991
+ minted: true,
1992
+ conversationId: randomUUID()
1993
+ };
1994
+ }
1995
+ /**
1996
+ * Predicate matching the same eligibility checks injectConversationIdPromptBack uses,
1997
+ * exposed so callers can pre-decide whether the prompt-back will actually land
1998
+ * (and clear event.conversationId if not, to avoid orphan ids in analytics).
1999
+ */
2000
+ function canInjectConversationIdPromptBack(result) {
2001
+ if (!(result && typeof result === "object")) return false;
2002
+ const resultObj = result;
2003
+ if (resultObj.isError === true) return false;
2004
+ return Array.isArray(resultObj.content);
2005
+ }
2006
+ function extractConversationId(args) {
2007
+ if (!(args && typeof args === "object")) return;
2008
+ const value = args[CONVERSATION_ID_PARAM_NAME];
2009
+ if (typeof value !== "string") return;
2010
+ const trimmed = value.trim();
2011
+ return trimmed.length > 0 ? trimmed : void 0;
2012
+ }
2013
+ function cloneRequestWithoutConversationId(request) {
2014
+ if (!request.params || typeof request.params !== "object") return request;
2015
+ const args = request.params.arguments;
2016
+ if (!(args && typeof args === "object")) return request;
2017
+ return {
2018
+ ...request,
2019
+ params: {
2020
+ ...request.params,
2021
+ arguments: stripConversationId(args)
2022
+ }
2023
+ };
2024
+ }
2025
+ function stripConversationId(args) {
2026
+ if (!args || typeof args !== "object" || !("conversation_id" in args)) return args;
2027
+ const { [CONVERSATION_ID_PARAM_NAME]: _omit, ...rest } = args;
2028
+ return rest;
2029
+ }
2030
+ function buildConversationIdPromptBack(conversationId) {
2031
+ return {
2032
+ type: "text",
2033
+ text: `[SERVER]: Reuse conversation_id=${conversationId} on every subsequent tool call in this conversation. Required for the server to correlate calls and provide context-aware results.`
2034
+ };
2035
+ }
2036
+ function injectConversationIdPromptBack(result, conversationId) {
2037
+ if (!canInjectConversationIdPromptBack(result)) return result;
2038
+ const resultObj = result;
2039
+ return {
2040
+ ...resultObj,
2041
+ content: [...resultObj.content, buildConversationIdPromptBack(conversationId)]
2042
+ };
2043
+ }
2044
+ //#endregion
1925
2045
  //#region src/modules/intent.ts
1926
2046
  function getContextArgument$2(request) {
1927
2047
  const context = request.params?.arguments?.context;
@@ -2017,9 +2137,11 @@ async function getTracedToolsList(server, originalListToolsHandler, request, ext
2017
2137
  const data = getServerTrackingData(server);
2018
2138
  let tools = (await originalListToolsHandler(request, extra)).tools || [];
2019
2139
  if (data && isContextEnabled(data.options.context)) tools = addContextParameterToTools(tools, getContextDescription(data.options.context));
2140
+ if (data?.options.enableConversationId) tools = addConversationIdToTools(tools);
2020
2141
  if (data?.options.reportMissing) {
2021
2142
  if (!tools.some((tool) => tool?.name === "get_more_tools")) tools.push(getReportMissingToolDescriptor());
2022
2143
  }
2144
+ if (data) cacheToolDescriptions(data.toolDescriptions, tools);
2023
2145
  return tools;
2024
2146
  } catch (error) {
2025
2147
  writeToLog(`Warning: Original list tools handler failed, this suggests an error PostHog MCP analytics did not cause - ${error}`);
@@ -2101,30 +2223,39 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
2101
2223
  writeToLog("Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called track(server, options) before using tool calls.");
2102
2224
  return await originalCallToolHandler?.(request, extra);
2103
2225
  }
2226
+ const conversation = resolveConversationId(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
2227
+ const downstreamRequest = conversation.conversationId ? cloneRequestWithoutConversationId(request) : request;
2228
+ const toolName = request.params?.name;
2104
2229
  const event = {
2105
2230
  sessionId: getServerSessionId(server, extra),
2106
- resourceName: request.params?.name || "Unknown Tool Name",
2107
- parameters: buildCapturedMcpParameters(request),
2231
+ conversationId: conversation.conversationId,
2232
+ resourceName: toolName || "Unknown Tool Name",
2233
+ parameters: buildCapturedMcpParameters(downstreamRequest),
2108
2234
  eventType: MCPAnalyticsEventType.mcpToolsCall,
2109
2235
  timestamp: /* @__PURE__ */ new Date(),
2236
+ toolDescription: toolName ? data.toolDescriptions.get(toolName) : void 0,
2110
2237
  redactionFn: data.options.redactSensitiveInformation
2111
2238
  };
2112
2239
  try {
2113
2240
  await handleIdentify(server, data, request, extra);
2114
2241
  await applyResolvedMetadata$1(event, data, request, extra);
2115
2242
  setEventIntent(event, await resolveToolCallIntent(data, request, extra));
2116
- const result = await executeToolCall(server, originalCallToolHandler, request, extra, event);
2243
+ const result = await executeToolCall(server, originalCallToolHandler, downstreamRequest, extra, event);
2117
2244
  if (isToolResultError$1(result)) {
2118
2245
  event.isError = true;
2119
2246
  event.error = captureException(result);
2120
2247
  } else event.isError = false;
2121
- event.response = result;
2248
+ let finalResult = result;
2249
+ if (conversation.minted) if (canInjectConversationIdPromptBack(result)) finalResult = injectConversationIdPromptBack(result, conversation.conversationId);
2250
+ else event.conversationId = void 0;
2251
+ event.response = finalResult;
2122
2252
  event.duration = getEventDuration(event);
2123
2253
  publishEvent(server, event);
2124
- return result;
2254
+ return finalResult;
2125
2255
  } catch (error) {
2126
2256
  event.isError = true;
2127
2257
  event.error = captureException(error);
2258
+ if (conversation.minted) event.conversationId = void 0;
2128
2259
  event.duration = getEventDuration(event);
2129
2260
  publishEvent(server, event);
2130
2261
  throw error;
@@ -2156,6 +2287,10 @@ function getContextArgument$1(request) {
2156
2287
  function getEventDuration(event) {
2157
2288
  return event.timestamp ? Date.now() - event.timestamp.getTime() : 0;
2158
2289
  }
2290
+ function cacheToolDescriptions(cache, tools) {
2291
+ if (!tools) return;
2292
+ for (const tool of tools) if (tool?.name && typeof tool.description === "string") cache.set(tool.name, tool.description);
2293
+ }
2159
2294
  //#endregion
2160
2295
  //#region src/modules/mcp-sdk-compat.ts
2161
2296
  /**
@@ -2243,7 +2378,8 @@ function addTracingToToolRegistry(tools, server) {
2243
2378
  }
2244
2379
  function setupListenerToRegisteredTools(server) {
2245
2380
  try {
2246
- if (!getServerTrackingData(server.server)) {
2381
+ const data = getServerTrackingData(server.server);
2382
+ if (!data) {
2247
2383
  writeToLog("Warning: Cannot setup listener - no tracking data found");
2248
2384
  return;
2249
2385
  }
@@ -2251,6 +2387,7 @@ function setupListenerToRegisteredTools(server) {
2251
2387
  set(target, property, value) {
2252
2388
  try {
2253
2389
  if (typeof property === "string" && value && typeof value === "object" && hasToolFunction(value)) {
2390
+ if (typeof value.description === "string") data.toolDescriptions.set(property, value.description);
2254
2391
  if (value[MCP_ANALYTICS_PROCESSED]) {
2255
2392
  writeToLog(`Tool ${String(property)} already processed, skipping proxy wrapping`);
2256
2393
  return Reflect.set(target, property, value);
@@ -2316,14 +2453,14 @@ function addTracingToToolCallbackInternal(tool, toolName, _server) {
2316
2453
  args = void 0;
2317
2454
  extra = params[0];
2318
2455
  }
2319
- const removeContextFromArgs = (args) => {
2320
- if (args && typeof args === "object" && "context" in args) {
2321
- const { context: _context, ...argsWithoutContext } = args;
2322
- return argsWithoutContext;
2456
+ const removeContextFromArgs = (input) => {
2457
+ if (input && typeof input === "object" && "context" in input) {
2458
+ const { context: _context, ...rest } = input;
2459
+ return rest;
2323
2460
  }
2324
- return args;
2461
+ return input;
2325
2462
  };
2326
- const cleanedArgs = toolName === "get_more_tools" ? args : removeContextFromArgs(args);
2463
+ const cleanedArgs = toolName === "get_more_tools" ? args : stripConversationId(removeContextFromArgs(args));
2327
2464
  try {
2328
2465
  if (cleanedArgs === void 0) return await originalCallback(extra);
2329
2466
  return await originalCallback(cleanedArgs, extra);
@@ -2357,26 +2494,31 @@ function createToolsCallWrapper(originalHandler, server) {
2357
2494
  }
2358
2495
  async function handleWrappedToolsCall(originalHandler, server, request, extra) {
2359
2496
  const startTime = /* @__PURE__ */ new Date();
2360
- const tracing = await initializeToolCallEvent(server, request, extra, startTime);
2497
+ const conversation = resolveConversationId(getServerTrackingData(server)?.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
2498
+ const tracing = await initializeToolCallEvent(server, request, conversation.conversationId ? cloneRequestWithoutConversationId(request) : request, extra, startTime, conversation);
2361
2499
  if (request?.params?.name === "get_more_tools") return await executeReportMissingTool(server, request, tracing, startTime);
2362
2500
  return await executeOriginalTool(originalHandler, server, request, extra, tracing, startTime);
2363
2501
  }
2364
- async function initializeToolCallEvent(server, request, extra, startTime) {
2502
+ async function initializeToolCallEvent(server, request, downstreamRequest, extra, startTime, conversation) {
2365
2503
  try {
2366
2504
  const data = getServerTrackingData(server);
2367
2505
  if (!data) {
2368
2506
  writeToLog("Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called track(server, options) before using tool calls.");
2369
2507
  return {
2370
2508
  event: null,
2509
+ mintedConversationId: void 0,
2371
2510
  shouldPublishEvent: false
2372
2511
  };
2373
2512
  }
2513
+ const toolName = request.params?.name;
2374
2514
  const event = {
2375
2515
  sessionId: getServerSessionId(server, extra),
2376
- resourceName: request.params?.name || "Unknown Tool",
2377
- parameters: buildCapturedMcpParameters(request),
2516
+ conversationId: conversation.conversationId,
2517
+ resourceName: toolName || "Unknown Tool",
2518
+ parameters: buildCapturedMcpParameters(downstreamRequest),
2378
2519
  eventType: MCPAnalyticsEventType.mcpToolsCall,
2379
2520
  timestamp: startTime,
2521
+ toolDescription: toolName ? data.toolDescriptions.get(toolName) : void 0,
2380
2522
  redactionFn: data.options.redactSensitiveInformation
2381
2523
  };
2382
2524
  await handleIdentify(server, data, request, extra);
@@ -2385,12 +2527,14 @@ async function initializeToolCallEvent(server, request, extra, startTime) {
2385
2527
  setEventIntent(event, await resolveToolCallIntent(data, request, extra));
2386
2528
  return {
2387
2529
  event,
2530
+ mintedConversationId: conversation.minted ? conversation.conversationId : void 0,
2388
2531
  shouldPublishEvent: true
2389
2532
  };
2390
2533
  } catch (error) {
2391
2534
  writeToLog(`Warning: PostHog MCP analytics tracing failed for tool ${request.params?.name}, falling back to original handler - ${error}`);
2392
2535
  return {
2393
2536
  event: null,
2537
+ mintedConversationId: void 0,
2394
2538
  shouldPublishEvent: false
2395
2539
  };
2396
2540
  }
@@ -2418,14 +2562,20 @@ async function executeReportMissingTool(server, request, tracing, startTime) {
2418
2562
  async function executeOriginalTool(originalHandler, server, request, extra, tracing, startTime) {
2419
2563
  try {
2420
2564
  const result = await originalHandler(request, extra);
2421
- publishSuccessfulToolEvent(server, tracing, result, startTime, {
2565
+ let finalResult = result;
2566
+ if (tracing.mintedConversationId) {
2567
+ if (canInjectConversationIdPromptBack(result)) finalResult = injectConversationIdPromptBack(result, tracing.mintedConversationId);
2568
+ else if (tracing.event) tracing.event.conversationId = void 0;
2569
+ }
2570
+ publishSuccessfulToolEvent(server, tracing, finalResult, startTime, {
2422
2571
  capturedError: extra?.__mcp_analytics_error,
2423
2572
  clearCapturedError: () => {
2424
2573
  if (extra) extra.__mcp_analytics_error = void 0;
2425
2574
  }
2426
2575
  });
2427
- return result;
2576
+ return finalResult;
2428
2577
  } catch (error) {
2578
+ if (tracing.mintedConversationId && tracing.event) tracing.event.conversationId = void 0;
2429
2579
  publishFailedToolEvent(server, tracing, error, startTime);
2430
2580
  throw error;
2431
2581
  }
@@ -2458,16 +2608,20 @@ function publishFailedToolEvent(server, tracing, error, startTime) {
2458
2608
  }
2459
2609
  function setupTracking(server) {
2460
2610
  try {
2461
- getServerTrackingData(server.server);
2611
+ const mcpAnalyticsData = getServerTrackingData(server.server);
2462
2612
  setupToolsCallHandlerWrapping(server);
2463
2613
  setupInitializeTracing(server);
2464
2614
  server._registeredTools = addTracingToToolRegistry(server._registeredTools, server);
2615
+ if (mcpAnalyticsData) seedToolDescriptionsFromRegistry(mcpAnalyticsData.toolDescriptions, server._registeredTools);
2465
2616
  setupListToolsTracing(server);
2466
2617
  setupListenerToRegisteredTools(server);
2467
2618
  } catch (error) {
2468
2619
  writeToLog(`Warning: Failed to setup tool call tracing - ${error}`);
2469
2620
  }
2470
2621
  }
2622
+ function seedToolDescriptionsFromRegistry(cache, tools) {
2623
+ for (const [name, tool] of Object.entries(tools)) if (typeof tool?.description === "string") cache.set(name, tool.description);
2624
+ }
2471
2625
  //#endregion
2472
2626
  //#region src/index.ts
2473
2627
  /**
@@ -2603,6 +2757,7 @@ function buildTrackingData(lowLevelServer, options) {
2603
2757
  sessionId: newSessionId(),
2604
2758
  lastActivity: /* @__PURE__ */ new Date(),
2605
2759
  identifiedSessions: /* @__PURE__ */ new Map(),
2760
+ toolDescriptions: /* @__PURE__ */ new Map(),
2606
2761
  sessionInfo: getSessionInfo(lowLevelServer, void 0),
2607
2762
  options: {
2608
2763
  reportMissing: options.reportMissing ?? false,
@@ -2616,7 +2771,8 @@ function buildTrackingData(lowLevelServer, options) {
2616
2771
  eventProperties: options.eventProperties,
2617
2772
  host: options.host,
2618
2773
  posthogClient: options.posthogClient,
2619
- posthogOptions: options.posthogOptions
2774
+ posthogOptions: options.posthogOptions,
2775
+ enableConversationId: options.enableConversationId ?? false
2620
2776
  },
2621
2777
  sessionSource: "generated"
2622
2778
  };