@posthog/mcp 0.0.2 → 0.0.4
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/README.md +61 -0
- package/dist/index.cjs +261 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.mts +23 -1
- package/dist/index.mjs +260 -58
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -34,9 +34,40 @@ track(server, {
|
|
|
34
34
|
With `context: true`, the SDK adds a required `context` argument to every tool call, strips it before invoking your handler, and captures it as `$mcp_intent` on PostHog events.
|
|
35
35
|
Captured tool parameters omit the duplicated `context` value and MCP transport internals.
|
|
36
36
|
|
|
37
|
+
Use `intentFallback` when you want a fallback for clients that call tools without the `context` argument.
|
|
38
|
+
This is a consumer-supplied callback — the SDK does no inference of its own; whatever string you return becomes `$mcp_intent`.
|
|
39
|
+
The explicit `context` argument always wins; fallback values are marked with `$mcp_intent_source = "inferred"`.
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
track(server, {
|
|
43
|
+
apiKey: process.env.POSTHOG_API_KEY,
|
|
44
|
+
context: true,
|
|
45
|
+
intentFallback: (request) => {
|
|
46
|
+
const toolName = request.params?.name;
|
|
47
|
+
return toolName ? `Calling ${toolName}` : undefined;
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
37
52
|
With `enableAITracing: true`, tool calls also emit `$ai_span` events with `$ai_trace_id` and `$ai_span_id`.
|
|
38
53
|
The regular `mcp_tool_call` event includes the same trace/span IDs so it can be joined back to the LLM analytics span.
|
|
39
54
|
|
|
55
|
+
### Conversation ID (opt-in)
|
|
56
|
+
|
|
57
|
+
When `enableConversationId: true` is passed to `track()`, the SDK injects an optional `conversation_id` argument into every tool's input schema and tells the agent to reuse the value the server returns. When the agent omits it on a call, the SDK mints a UUID and appends a short text block to the tool's response asking the agent to echo the same `conversation_id` on subsequent calls. The value the agent supplies (or the SDK mints) is captured on PostHog events as `$mcp_conversation_id` — separate from `$session_id`, which is unchanged. Off by default.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
track(server, {
|
|
61
|
+
apiKey: process.env.POSTHOG_API_KEY,
|
|
62
|
+
enableConversationId: true,
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Caveats:**
|
|
67
|
+
|
|
68
|
+
- The prompt-back is appended as a regular `text` content block (the only channel MCP currently offers for server→agent communication). Consumers that surface raw tool-call content to end users will see `[SERVER]: Reuse conversation_id=…` in their UI. If/when the MCP spec grows a server-directives channel (e.g. on `_meta`), the SDK will move there.
|
|
69
|
+
- The captured `$mcp_conversation_id` value is agent-controlled when the agent supplies one — the SDK accepts any non-empty string. Customers wanting to bind it to their own session scheme (chat ID, JWT `jti`, request ID) can do so freely; the trade-off is that nothing prevents a misbehaving agent from sending arbitrary values.
|
|
70
|
+
|
|
40
71
|
The SDK sends events through `posthog-node`, so it uses the same PostHog ingestion client, batching, retry, flush, and shutdown behavior as the existing Node SDK.
|
|
41
72
|
|
|
42
73
|
If your application already owns a PostHog client, pass it in instead:
|
|
@@ -52,6 +83,36 @@ track(server, {
|
|
|
52
83
|
});
|
|
53
84
|
```
|
|
54
85
|
|
|
86
|
+
## Event schema
|
|
87
|
+
|
|
88
|
+
The SDK emits PostHog events using a stable MCP-specific schema.
|
|
89
|
+
The package exports `PostHogMCPAnalyticsEvent`, `PostHogMCPAnalyticsProperty`, and `POSTHOG_MCP_ANALYTICS_SOURCE` constants so product code can query the same contract without hard-coded strings.
|
|
90
|
+
|
|
91
|
+
Canonical event names:
|
|
92
|
+
|
|
93
|
+
- `mcp_tool_call` for each MCP tool call
|
|
94
|
+
- `mcp_tools_list` when clients list available tools
|
|
95
|
+
- `mcp_initialize` when clients initialize a session
|
|
96
|
+
- `$ai_span` for tool-call spans when `enableAITracing: true`
|
|
97
|
+
- `$exception` for captured tool errors
|
|
98
|
+
|
|
99
|
+
Important properties:
|
|
100
|
+
|
|
101
|
+
- `$mcp_source = "posthog_mcp_analytics"`
|
|
102
|
+
- `$mcp_intent` from the `context` argument, or from `intentFallback` when no context was provided
|
|
103
|
+
- `$mcp_intent_source` as `context_parameter` or `inferred`
|
|
104
|
+
- `$mcp_tool_name` and `$mcp_resource_name`
|
|
105
|
+
- `$mcp_parameters` and `$mcp_response`, after redaction and truncation
|
|
106
|
+
- `$mcp_duration_ms`
|
|
107
|
+
- `$mcp_is_error`
|
|
108
|
+
- `$session_id`
|
|
109
|
+
- `$ai_trace_id`, `$ai_span_id`, and `$ai_session_id` when AI tracing is enabled
|
|
110
|
+
|
|
111
|
+
The SDK does not emit `$mcp_context`.
|
|
112
|
+
Use `$mcp_intent` for agent/user intent.
|
|
113
|
+
|
|
114
|
+
See [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) for the full architecture, property catalog, sample queries, and migration notes vs the upstream mcpcat schema.
|
|
115
|
+
|
|
55
116
|
## Development
|
|
56
117
|
|
|
57
118
|
```bash
|
package/dist/index.cjs
CHANGED
|
@@ -120,15 +120,14 @@ function getMCPCompatibleErrorMessage(error) {
|
|
|
120
120
|
return "Unknown error";
|
|
121
121
|
}
|
|
122
122
|
//#endregion
|
|
123
|
-
//#region src/modules/ids.ts
|
|
124
|
-
function newPrefixedId(prefix) {
|
|
125
|
-
return `${prefix}_${(0, node_crypto.randomUUID)()}`;
|
|
126
|
-
}
|
|
127
|
-
function deterministicPrefixedId(prefix, input) {
|
|
128
|
-
return `${prefix}_${(0, node_crypto.createHash)("sha256").update(input).digest("hex").slice(0, 32)}`;
|
|
129
|
-
}
|
|
130
|
-
//#endregion
|
|
131
123
|
//#region src/modules/event-types.ts
|
|
124
|
+
/**
|
|
125
|
+
* Internal SDK event vocabulary.
|
|
126
|
+
*
|
|
127
|
+
* These values are not imported from `@modelcontextprotocol/sdk`; they are the
|
|
128
|
+
* protocol-shaped event types this SDK observes before mapping them to PostHog
|
|
129
|
+
* event names.
|
|
130
|
+
*/
|
|
132
131
|
const MCPAnalyticsEventType = {
|
|
133
132
|
identify: "posthog:identify",
|
|
134
133
|
custom: "posthog:custom",
|
|
@@ -141,6 +140,14 @@ const MCPAnalyticsEventType = {
|
|
|
141
140
|
mcpToolsList: "mcp:tools/list"
|
|
142
141
|
};
|
|
143
142
|
//#endregion
|
|
143
|
+
//#region src/modules/ids.ts
|
|
144
|
+
function newPrefixedId(prefix) {
|
|
145
|
+
return `${prefix}_${(0, node_crypto.randomUUID)()}`;
|
|
146
|
+
}
|
|
147
|
+
function deterministicPrefixedId(prefix, input) {
|
|
148
|
+
return `${prefix}_${(0, node_crypto.createHash)("sha256").update(input).digest("hex").slice(0, 32)}`;
|
|
149
|
+
}
|
|
150
|
+
//#endregion
|
|
144
151
|
//#region src/modules/validation.ts
|
|
145
152
|
const TAG_KEY_REGEX = /^[a-zA-Z0-9$_.:\- ]+$/;
|
|
146
153
|
const MAX_TAG_KEY_LENGTH = 32;
|
|
@@ -343,7 +350,21 @@ function getRequestResourceName(request) {
|
|
|
343
350
|
//#endregion
|
|
344
351
|
//#region src/modules/constants.ts
|
|
345
352
|
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."`;
|
|
353
|
+
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.";
|
|
346
354
|
const POSTHOG_MCP_ANALYTICS_SOURCE = "posthog_mcp_analytics";
|
|
355
|
+
const PostHogMCPAnalyticsEvent = {
|
|
356
|
+
AiSpan: "$ai_span",
|
|
357
|
+
Custom: "mcp_custom",
|
|
358
|
+
Exception: "$exception",
|
|
359
|
+
Identify: "$identify",
|
|
360
|
+
Initialize: "mcp_initialize",
|
|
361
|
+
PromptGet: "mcp_prompt_get",
|
|
362
|
+
PromptsList: "mcp_prompts_list",
|
|
363
|
+
ResourceRead: "mcp_resource_read",
|
|
364
|
+
ResourcesList: "mcp_resources_list",
|
|
365
|
+
ToolCall: "mcp_tool_call",
|
|
366
|
+
ToolsList: "mcp_tools_list"
|
|
367
|
+
};
|
|
347
368
|
const PostHogMCPAnalyticsProperty = {
|
|
348
369
|
AiInputState: "$ai_input_state",
|
|
349
370
|
AiIsError: "$ai_is_error",
|
|
@@ -356,9 +377,11 @@ const PostHogMCPAnalyticsProperty = {
|
|
|
356
377
|
AiTraceId: "$ai_trace_id",
|
|
357
378
|
ClientName: "$mcp_client_name",
|
|
358
379
|
ClientVersion: "$mcp_client_version",
|
|
380
|
+
ConversationId: "$mcp_conversation_id",
|
|
359
381
|
DurationMs: "$mcp_duration_ms",
|
|
360
382
|
IsError: "$mcp_is_error",
|
|
361
383
|
Intent: "$mcp_intent",
|
|
384
|
+
IntentSource: "$mcp_intent_source",
|
|
362
385
|
Parameters: "$mcp_parameters",
|
|
363
386
|
ResourceName: "$mcp_resource_name",
|
|
364
387
|
Response: "$mcp_response",
|
|
@@ -370,8 +393,17 @@ const PostHogMCPAnalyticsProperty = {
|
|
|
370
393
|
};
|
|
371
394
|
//#endregion
|
|
372
395
|
//#region src/modules/posthog-events.ts
|
|
373
|
-
const
|
|
374
|
-
|
|
396
|
+
const BUILT_IN_EVENT_NAME_BY_TYPE = {
|
|
397
|
+
[MCPAnalyticsEventType.custom]: PostHogMCPAnalyticsEvent.Custom,
|
|
398
|
+
[MCPAnalyticsEventType.identify]: PostHogMCPAnalyticsEvent.Identify,
|
|
399
|
+
[MCPAnalyticsEventType.mcpInitialize]: PostHogMCPAnalyticsEvent.Initialize,
|
|
400
|
+
[MCPAnalyticsEventType.mcpPromptsGet]: PostHogMCPAnalyticsEvent.PromptGet,
|
|
401
|
+
[MCPAnalyticsEventType.mcpPromptsList]: PostHogMCPAnalyticsEvent.PromptsList,
|
|
402
|
+
[MCPAnalyticsEventType.mcpResourcesList]: PostHogMCPAnalyticsEvent.ResourcesList,
|
|
403
|
+
[MCPAnalyticsEventType.mcpResourcesRead]: PostHogMCPAnalyticsEvent.ResourceRead,
|
|
404
|
+
[MCPAnalyticsEventType.mcpToolsCall]: PostHogMCPAnalyticsEvent.ToolCall,
|
|
405
|
+
[MCPAnalyticsEventType.mcpToolsList]: PostHogMCPAnalyticsEvent.ToolsList
|
|
406
|
+
};
|
|
375
407
|
function getDistinctId(event) {
|
|
376
408
|
return event.identifyActorGivenId || event.sessionId || "anonymous";
|
|
377
409
|
}
|
|
@@ -386,17 +418,17 @@ function buildPostHogCaptureEvents(event, options = {}) {
|
|
|
386
418
|
}
|
|
387
419
|
function buildCaptureEvent(event, options) {
|
|
388
420
|
const distinctId = getDistinctId(event);
|
|
389
|
-
const eventName = mapEventType(event.eventType);
|
|
390
421
|
const timestamp = getTimestamp(event);
|
|
391
422
|
const properties = {
|
|
392
423
|
[PostHogMCPAnalyticsProperty.SessionId]: event.sessionId,
|
|
393
424
|
[PostHogMCPAnalyticsProperty.Source]: POSTHOG_MCP_ANALYTICS_SOURCE
|
|
394
425
|
};
|
|
426
|
+
addConversationIdProperty(event, properties);
|
|
395
427
|
addCommonEventProperties(event, properties);
|
|
396
428
|
addTraceReferenceProperties(event, properties, options);
|
|
397
429
|
addCustomEventProperties(event, properties);
|
|
398
430
|
return {
|
|
399
|
-
event:
|
|
431
|
+
event: BUILT_IN_EVENT_NAME_BY_TYPE[event.eventType],
|
|
400
432
|
distinct_id: distinctId,
|
|
401
433
|
properties,
|
|
402
434
|
timestamp,
|
|
@@ -417,6 +449,9 @@ function addTraceReferenceProperties(event, properties, options) {
|
|
|
417
449
|
properties[PostHogMCPAnalyticsProperty.AiTraceId] = getAITraceId(event);
|
|
418
450
|
properties[PostHogMCPAnalyticsProperty.AiSpanId] = getAISpanId(event);
|
|
419
451
|
}
|
|
452
|
+
function addConversationIdProperty(event, properties) {
|
|
453
|
+
if (event.conversationId !== void 0 && event.conversationId !== "") properties[PostHogMCPAnalyticsProperty.ConversationId] = event.conversationId;
|
|
454
|
+
}
|
|
420
455
|
function addCommonEventProperties(event, properties) {
|
|
421
456
|
if (event.resourceName) {
|
|
422
457
|
properties[PostHogMCPAnalyticsProperty.ResourceName] = event.resourceName;
|
|
@@ -428,6 +463,7 @@ function addCommonEventProperties(event, properties) {
|
|
|
428
463
|
if (event.clientName) properties[PostHogMCPAnalyticsProperty.ClientName] = event.clientName;
|
|
429
464
|
if (event.clientVersion) properties[PostHogMCPAnalyticsProperty.ClientVersion] = event.clientVersion;
|
|
430
465
|
if (event.userIntent) properties[PostHogMCPAnalyticsProperty.Intent] = event.userIntent;
|
|
466
|
+
if (event.userIntentSource) properties[PostHogMCPAnalyticsProperty.IntentSource] = event.userIntentSource;
|
|
431
467
|
if (event.isError !== void 0) properties[PostHogMCPAnalyticsProperty.IsError] = event.isError;
|
|
432
468
|
if (event.parameters !== void 0) properties[PostHogMCPAnalyticsProperty.Parameters] = event.parameters;
|
|
433
469
|
if (event.response !== void 0) properties[PostHogMCPAnalyticsProperty.Response] = event.response;
|
|
@@ -447,6 +483,7 @@ function buildExceptionEvent(event) {
|
|
|
447
483
|
$exception_source: "backend",
|
|
448
484
|
[PostHogMCPAnalyticsProperty.SessionId]: event.sessionId
|
|
449
485
|
};
|
|
486
|
+
addConversationIdProperty(event, properties);
|
|
450
487
|
if (event.error) {
|
|
451
488
|
if (event.error.message) properties.$exception_message = event.error.message;
|
|
452
489
|
if (event.error.type) properties.$exception_type = event.error.type;
|
|
@@ -461,7 +498,7 @@ function buildExceptionEvent(event) {
|
|
|
461
498
|
if (event.clientName) properties[PostHogMCPAnalyticsProperty.ClientName] = event.clientName;
|
|
462
499
|
if (event.clientVersion) properties[PostHogMCPAnalyticsProperty.ClientVersion] = event.clientVersion;
|
|
463
500
|
return {
|
|
464
|
-
event:
|
|
501
|
+
event: PostHogMCPAnalyticsEvent.Exception,
|
|
465
502
|
distinct_id: distinctId,
|
|
466
503
|
properties,
|
|
467
504
|
timestamp,
|
|
@@ -480,6 +517,7 @@ function buildAISpanEvent(event) {
|
|
|
480
517
|
[PostHogMCPAnalyticsProperty.SessionId]: event.sessionId,
|
|
481
518
|
[PostHogMCPAnalyticsProperty.Source]: POSTHOG_MCP_ANALYTICS_SOURCE
|
|
482
519
|
};
|
|
520
|
+
addConversationIdProperty(event, properties);
|
|
483
521
|
if (event.duration !== void 0) properties[PostHogMCPAnalyticsProperty.AiLatency] = event.duration / 1e3;
|
|
484
522
|
if (event.isError && event.error) properties.$ai_error = event.error;
|
|
485
523
|
if (event.parameters !== void 0) properties[PostHogMCPAnalyticsProperty.AiInputState] = event.parameters;
|
|
@@ -487,27 +525,17 @@ function buildAISpanEvent(event) {
|
|
|
487
525
|
if (event.serverName) properties[PostHogMCPAnalyticsProperty.ServerName] = event.serverName;
|
|
488
526
|
if (event.clientName) properties[PostHogMCPAnalyticsProperty.ClientName] = event.clientName;
|
|
489
527
|
if (event.userIntent) properties[PostHogMCPAnalyticsProperty.Intent] = event.userIntent;
|
|
528
|
+
if (event.userIntentSource) properties[PostHogMCPAnalyticsProperty.IntentSource] = event.userIntentSource;
|
|
490
529
|
if (event.tags) for (const [key, value] of Object.entries(event.tags)) properties[key] = value;
|
|
491
530
|
if (event.properties) for (const [key, value] of Object.entries(event.properties)) properties[key] = value;
|
|
492
531
|
return {
|
|
493
|
-
event:
|
|
532
|
+
event: PostHogMCPAnalyticsEvent.AiSpan,
|
|
494
533
|
distinct_id: distinctId,
|
|
495
534
|
properties,
|
|
496
535
|
timestamp,
|
|
497
536
|
type: "capture"
|
|
498
537
|
};
|
|
499
538
|
}
|
|
500
|
-
function mapEventType(eventType) {
|
|
501
|
-
return {
|
|
502
|
-
[MCPAnalyticsEventType.mcpToolsCall]: "mcp_tool_call",
|
|
503
|
-
[MCPAnalyticsEventType.mcpToolsList]: "mcp_tools_list",
|
|
504
|
-
[MCPAnalyticsEventType.mcpInitialize]: "mcp_initialize",
|
|
505
|
-
[MCPAnalyticsEventType.mcpResourcesRead]: "mcp_resource_read",
|
|
506
|
-
[MCPAnalyticsEventType.mcpResourcesList]: "mcp_resources_list",
|
|
507
|
-
[MCPAnalyticsEventType.mcpPromptsGet]: "mcp_prompt_get",
|
|
508
|
-
[MCPAnalyticsEventType.mcpPromptsList]: "mcp_prompts_list"
|
|
509
|
-
}[eventType] || `mcp_${eventType.replace(MCP_EVENT_PREFIX_REGEX, "").replace(SLASH_REGEX, "_")}`;
|
|
510
|
-
}
|
|
511
539
|
//#endregion
|
|
512
540
|
//#region src/modules/redaction.ts
|
|
513
541
|
/**
|
|
@@ -701,7 +729,7 @@ function sanitizeParameters(obj) {
|
|
|
701
729
|
}
|
|
702
730
|
//#endregion
|
|
703
731
|
//#region package.json
|
|
704
|
-
var version = "0.0.
|
|
732
|
+
var version = "0.0.4";
|
|
705
733
|
//#endregion
|
|
706
734
|
//#region src/modules/session.ts
|
|
707
735
|
function newSessionId() {
|
|
@@ -1085,7 +1113,6 @@ var EventQueue = class {
|
|
|
1085
1113
|
timestamp: new Date(captureEvent.timestamp)
|
|
1086
1114
|
});
|
|
1087
1115
|
writeToLog(`Queued PostHog event ${event.id} | ${event.eventType} | ${event.duration} ms | ${event.identifyActorGivenId || "anonymous"}`);
|
|
1088
|
-
writeToLog(`Event details: ${JSON.stringify(event)}`);
|
|
1089
1116
|
} catch (error) {
|
|
1090
1117
|
writeToLog(`Failed to queue PostHog event ${event.id}: ${getMCPCompatibleErrorMessage(error)}`);
|
|
1091
1118
|
throw error;
|
|
@@ -1148,7 +1175,7 @@ function publishEvent(server, eventInput) {
|
|
|
1148
1175
|
id: eventInput.id || "",
|
|
1149
1176
|
sessionId: eventInput.sessionId || data.sessionId,
|
|
1150
1177
|
apiKey: data.apiKey,
|
|
1151
|
-
eventType: eventInput.eventType ||
|
|
1178
|
+
eventType: eventInput.eventType || MCPAnalyticsEventType.custom,
|
|
1152
1179
|
timestamp: eventInput.timestamp || /* @__PURE__ */ new Date(),
|
|
1153
1180
|
duration,
|
|
1154
1181
|
ipAddress: sessionInfo.ipAddress,
|
|
@@ -1165,8 +1192,10 @@ function publishEvent(server, eventInput) {
|
|
|
1165
1192
|
parameters: eventInput.parameters,
|
|
1166
1193
|
response: eventInput.response,
|
|
1167
1194
|
userIntent: eventInput.userIntent,
|
|
1195
|
+
userIntentSource: eventInput.userIntentSource,
|
|
1168
1196
|
isError: eventInput.isError,
|
|
1169
1197
|
error: eventInput.error,
|
|
1198
|
+
conversationId: eventInput.conversationId,
|
|
1170
1199
|
redactionFn: eventInput.redactionFn,
|
|
1171
1200
|
tags: eventInput.tags,
|
|
1172
1201
|
properties: eventInput.properties
|
|
@@ -1903,6 +1932,155 @@ function setupMCPAnalyticsTools(server) {
|
|
|
1903
1932
|
}
|
|
1904
1933
|
}
|
|
1905
1934
|
//#endregion
|
|
1935
|
+
//#region src/modules/conversation-id.ts
|
|
1936
|
+
const CONVERSATION_ID_PARAM_NAME = "conversation_id";
|
|
1937
|
+
function addConversationIdToTool(tool) {
|
|
1938
|
+
const modifiedTool = { ...tool };
|
|
1939
|
+
const toolName = tool.name || "unknown";
|
|
1940
|
+
const schema = modifiedTool.inputSchema;
|
|
1941
|
+
if (schema?.properties?.["conversation_id"]) {
|
|
1942
|
+
writeToLog(`WARN: Tool "${toolName}" already has '${CONVERSATION_ID_PARAM_NAME}' parameter. Skipping conversation_id injection.`);
|
|
1943
|
+
return modifiedTool;
|
|
1944
|
+
}
|
|
1945
|
+
if (schema?.oneOf || schema?.allOf || schema?.anyOf) {
|
|
1946
|
+
writeToLog(`WARN: Tool "${toolName}" has complex schema (oneOf/allOf/anyOf). Skipping conversation_id injection.`);
|
|
1947
|
+
return modifiedTool;
|
|
1948
|
+
}
|
|
1949
|
+
if (!modifiedTool.inputSchema) modifiedTool.inputSchema = {
|
|
1950
|
+
type: "object",
|
|
1951
|
+
properties: {},
|
|
1952
|
+
required: []
|
|
1953
|
+
};
|
|
1954
|
+
modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema));
|
|
1955
|
+
const inputSchema = modifiedTool.inputSchema;
|
|
1956
|
+
if (!inputSchema.properties) inputSchema.properties = {};
|
|
1957
|
+
if (inputSchema.additionalProperties === false) inputSchema.additionalProperties = void 0;
|
|
1958
|
+
inputSchema.properties[CONVERSATION_ID_PARAM_NAME] = {
|
|
1959
|
+
type: "string",
|
|
1960
|
+
description: DEFAULT_CONVERSATION_ID_DESCRIPTION
|
|
1961
|
+
};
|
|
1962
|
+
return modifiedTool;
|
|
1963
|
+
}
|
|
1964
|
+
function addConversationIdToTools(tools) {
|
|
1965
|
+
return tools.map((tool) => {
|
|
1966
|
+
if (tool.name === "get_more_tools") return tool;
|
|
1967
|
+
return addConversationIdToTool(tool);
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
/**
|
|
1971
|
+
* Decides which conversation_id to use for a tool call:
|
|
1972
|
+
* - disabled or get_more_tools → none
|
|
1973
|
+
* - agent supplied a value → use it
|
|
1974
|
+
* - agent omitted → mint a UUID
|
|
1975
|
+
*/
|
|
1976
|
+
function resolveConversationId(enabled, args, toolName) {
|
|
1977
|
+
if (!enabled || toolName === "get_more_tools") return {
|
|
1978
|
+
minted: false,
|
|
1979
|
+
conversationId: void 0
|
|
1980
|
+
};
|
|
1981
|
+
const supplied = extractConversationId(args);
|
|
1982
|
+
if (supplied) return {
|
|
1983
|
+
minted: false,
|
|
1984
|
+
conversationId: supplied
|
|
1985
|
+
};
|
|
1986
|
+
return {
|
|
1987
|
+
minted: true,
|
|
1988
|
+
conversationId: (0, node_crypto.randomUUID)()
|
|
1989
|
+
};
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* Predicate matching the same eligibility checks injectConversationIdPromptBack uses,
|
|
1993
|
+
* exposed so callers can pre-decide whether the prompt-back will actually land
|
|
1994
|
+
* (and clear event.conversationId if not, to avoid orphan ids in analytics).
|
|
1995
|
+
*/
|
|
1996
|
+
function canInjectConversationIdPromptBack(result) {
|
|
1997
|
+
if (!(result && typeof result === "object")) return false;
|
|
1998
|
+
const resultObj = result;
|
|
1999
|
+
if (resultObj.isError === true) return false;
|
|
2000
|
+
return Array.isArray(resultObj.content);
|
|
2001
|
+
}
|
|
2002
|
+
function extractConversationId(args) {
|
|
2003
|
+
if (!(args && typeof args === "object")) return;
|
|
2004
|
+
const value = args[CONVERSATION_ID_PARAM_NAME];
|
|
2005
|
+
if (typeof value !== "string") return;
|
|
2006
|
+
const trimmed = value.trim();
|
|
2007
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
2008
|
+
}
|
|
2009
|
+
function cloneRequestWithoutConversationId(request) {
|
|
2010
|
+
if (!request.params || typeof request.params !== "object") return request;
|
|
2011
|
+
const args = request.params.arguments;
|
|
2012
|
+
if (!(args && typeof args === "object")) return request;
|
|
2013
|
+
return {
|
|
2014
|
+
...request,
|
|
2015
|
+
params: {
|
|
2016
|
+
...request.params,
|
|
2017
|
+
arguments: stripConversationId(args)
|
|
2018
|
+
}
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
function stripConversationId(args) {
|
|
2022
|
+
if (!args || typeof args !== "object" || !("conversation_id" in args)) return args;
|
|
2023
|
+
const { [CONVERSATION_ID_PARAM_NAME]: _omit, ...rest } = args;
|
|
2024
|
+
return rest;
|
|
2025
|
+
}
|
|
2026
|
+
function buildConversationIdPromptBack(conversationId) {
|
|
2027
|
+
return {
|
|
2028
|
+
type: "text",
|
|
2029
|
+
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.`
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
function injectConversationIdPromptBack(result, conversationId) {
|
|
2033
|
+
if (!canInjectConversationIdPromptBack(result)) return result;
|
|
2034
|
+
const resultObj = result;
|
|
2035
|
+
return {
|
|
2036
|
+
...resultObj,
|
|
2037
|
+
content: [...resultObj.content, buildConversationIdPromptBack(conversationId)]
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
//#endregion
|
|
2041
|
+
//#region src/modules/intent.ts
|
|
2042
|
+
function getContextArgument$2(request) {
|
|
2043
|
+
const context = request.params?.arguments?.context;
|
|
2044
|
+
return typeof context === "string" && context.trim() ? context : void 0;
|
|
2045
|
+
}
|
|
2046
|
+
function normalizeIntent(intent) {
|
|
2047
|
+
if (typeof intent !== "string") return null;
|
|
2048
|
+
const trimmed = intent.trim();
|
|
2049
|
+
return trimmed ? trimmed : null;
|
|
2050
|
+
}
|
|
2051
|
+
async function runIntentFallback(data, request, extra) {
|
|
2052
|
+
if (!data.options.intentFallback) return null;
|
|
2053
|
+
try {
|
|
2054
|
+
const intent = normalizeIntent(await data.options.intentFallback(request, extra));
|
|
2055
|
+
return intent ? {
|
|
2056
|
+
intent,
|
|
2057
|
+
source: "inferred"
|
|
2058
|
+
} : null;
|
|
2059
|
+
} catch (error) {
|
|
2060
|
+
writeToLog(`intentFallback callback error: ${error}`);
|
|
2061
|
+
return null;
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
async function resolveToolCallIntent(data, request, extra) {
|
|
2065
|
+
const contextArgument = getContextArgument$2(request);
|
|
2066
|
+
if (isContextEnabled(data.options.context) && request.params?.name !== "get_more_tools" && contextArgument) return {
|
|
2067
|
+
intent: contextArgument,
|
|
2068
|
+
source: "context_parameter"
|
|
2069
|
+
};
|
|
2070
|
+
return await runIntentFallback(data, request, extra);
|
|
2071
|
+
}
|
|
2072
|
+
function setEventIntent(event, resolvedIntent) {
|
|
2073
|
+
if (!resolvedIntent) return;
|
|
2074
|
+
event.userIntent = resolvedIntent.intent;
|
|
2075
|
+
event.userIntentSource = resolvedIntent.source;
|
|
2076
|
+
}
|
|
2077
|
+
function setExplicitContextIntent(event, context) {
|
|
2078
|
+
const intent = normalizeIntent(context);
|
|
2079
|
+
if (!intent) return;
|
|
2080
|
+
event.userIntent = intent;
|
|
2081
|
+
event.userIntentSource = "context_parameter";
|
|
2082
|
+
}
|
|
2083
|
+
//#endregion
|
|
1906
2084
|
//#region src/modules/tracing.ts
|
|
1907
2085
|
function isToolResultError$1(result) {
|
|
1908
2086
|
return !!result && typeof result === "object" && "isError" in result && result.isError === true;
|
|
@@ -1955,6 +2133,7 @@ async function getTracedToolsList(server, originalListToolsHandler, request, ext
|
|
|
1955
2133
|
const data = getServerTrackingData(server);
|
|
1956
2134
|
let tools = (await originalListToolsHandler(request, extra)).tools || [];
|
|
1957
2135
|
if (data && isContextEnabled(data.options.context)) tools = addContextParameterToTools(tools, getContextDescription(data.options.context));
|
|
2136
|
+
if (data?.options.enableConversationId) tools = addConversationIdToTools(tools);
|
|
1958
2137
|
if (data?.options.reportMissing) {
|
|
1959
2138
|
if (!tools.some((tool) => tool?.name === "get_more_tools")) tools.push(getReportMissingToolDescriptor());
|
|
1960
2139
|
}
|
|
@@ -2039,10 +2218,13 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
2039
2218
|
writeToLog("Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called track(server, options) before using tool calls.");
|
|
2040
2219
|
return await originalCallToolHandler?.(request, extra);
|
|
2041
2220
|
}
|
|
2221
|
+
const conversation = resolveConversationId(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
|
|
2222
|
+
const downstreamRequest = conversation.conversationId ? cloneRequestWithoutConversationId(request) : request;
|
|
2042
2223
|
const event = {
|
|
2043
2224
|
sessionId: getServerSessionId(server, extra),
|
|
2225
|
+
conversationId: conversation.conversationId,
|
|
2044
2226
|
resourceName: request.params?.name || "Unknown Tool Name",
|
|
2045
|
-
parameters: buildCapturedMcpParameters(
|
|
2227
|
+
parameters: buildCapturedMcpParameters(downstreamRequest),
|
|
2046
2228
|
eventType: MCPAnalyticsEventType.mcpToolsCall,
|
|
2047
2229
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2048
2230
|
redactionFn: data.options.redactSensitiveInformation
|
|
@@ -2050,18 +2232,24 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
2050
2232
|
try {
|
|
2051
2233
|
await handleIdentify(server, data, request, extra);
|
|
2052
2234
|
await applyResolvedMetadata$1(event, data, request, extra);
|
|
2053
|
-
|
|
2054
|
-
const result = await executeToolCall(server, originalCallToolHandler,
|
|
2235
|
+
setEventIntent(event, await resolveToolCallIntent(data, request, extra));
|
|
2236
|
+
const result = await executeToolCall(server, originalCallToolHandler, downstreamRequest, extra, event);
|
|
2055
2237
|
if (isToolResultError$1(result)) {
|
|
2056
2238
|
event.isError = true;
|
|
2057
2239
|
event.error = captureException(result);
|
|
2058
|
-
}
|
|
2059
|
-
|
|
2240
|
+
} else event.isError = false;
|
|
2241
|
+
let finalResult = result;
|
|
2242
|
+
if (conversation.minted) if (canInjectConversationIdPromptBack(result)) finalResult = injectConversationIdPromptBack(result, conversation.conversationId);
|
|
2243
|
+
else event.conversationId = void 0;
|
|
2244
|
+
event.response = finalResult;
|
|
2245
|
+
event.duration = getEventDuration(event);
|
|
2060
2246
|
publishEvent(server, event);
|
|
2061
|
-
return
|
|
2247
|
+
return finalResult;
|
|
2062
2248
|
} catch (error) {
|
|
2063
2249
|
event.isError = true;
|
|
2064
2250
|
event.error = captureException(error);
|
|
2251
|
+
if (conversation.minted) event.conversationId = void 0;
|
|
2252
|
+
event.duration = getEventDuration(event);
|
|
2065
2253
|
publishEvent(server, event);
|
|
2066
2254
|
throw error;
|
|
2067
2255
|
}
|
|
@@ -2069,7 +2257,7 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
2069
2257
|
async function executeToolCall(server, originalCallToolHandler, request, extra, event) {
|
|
2070
2258
|
if (request.params?.name === "get_more_tools") {
|
|
2071
2259
|
const context = getContextArgument$1(request) || "";
|
|
2072
|
-
event
|
|
2260
|
+
setExplicitContextIntent(event, context);
|
|
2073
2261
|
return handleReportMissing({ context });
|
|
2074
2262
|
}
|
|
2075
2263
|
if (originalCallToolHandler) return await originalCallToolHandler(request, extra);
|
|
@@ -2085,11 +2273,6 @@ async function applyResolvedMetadata$1(event, data, request, extra) {
|
|
|
2085
2273
|
const resolvedProperties = await resolveEventProperties(data, request, extra);
|
|
2086
2274
|
if (resolvedProperties) event.properties = resolvedProperties;
|
|
2087
2275
|
}
|
|
2088
|
-
function setToolCallContext(event, context, request) {
|
|
2089
|
-
if (!(isContextEnabled(context) && request.params?.name !== "get_more_tools")) return;
|
|
2090
|
-
const contextArgument = getContextArgument$1(request);
|
|
2091
|
-
if (contextArgument) event.userIntent = contextArgument;
|
|
2092
|
-
}
|
|
2093
2276
|
function getContextArgument$1(request) {
|
|
2094
2277
|
const context = request.params?.arguments?.context;
|
|
2095
2278
|
return typeof context === "string" ? context : void 0;
|
|
@@ -2257,14 +2440,14 @@ function addTracingToToolCallbackInternal(tool, toolName, _server) {
|
|
|
2257
2440
|
args = void 0;
|
|
2258
2441
|
extra = params[0];
|
|
2259
2442
|
}
|
|
2260
|
-
const removeContextFromArgs = (
|
|
2261
|
-
if (
|
|
2262
|
-
const { context: _context, ...
|
|
2263
|
-
return
|
|
2443
|
+
const removeContextFromArgs = (input) => {
|
|
2444
|
+
if (input && typeof input === "object" && "context" in input) {
|
|
2445
|
+
const { context: _context, ...rest } = input;
|
|
2446
|
+
return rest;
|
|
2264
2447
|
}
|
|
2265
|
-
return
|
|
2448
|
+
return input;
|
|
2266
2449
|
};
|
|
2267
|
-
const cleanedArgs = toolName === "get_more_tools" ? args : removeContextFromArgs(args);
|
|
2450
|
+
const cleanedArgs = toolName === "get_more_tools" ? args : stripConversationId(removeContextFromArgs(args));
|
|
2268
2451
|
try {
|
|
2269
2452
|
if (cleanedArgs === void 0) return await originalCallback(extra);
|
|
2270
2453
|
return await originalCallback(cleanedArgs, extra);
|
|
@@ -2298,24 +2481,27 @@ function createToolsCallWrapper(originalHandler, server) {
|
|
|
2298
2481
|
}
|
|
2299
2482
|
async function handleWrappedToolsCall(originalHandler, server, request, extra) {
|
|
2300
2483
|
const startTime = /* @__PURE__ */ new Date();
|
|
2301
|
-
const
|
|
2484
|
+
const conversation = resolveConversationId(getServerTrackingData(server)?.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
|
|
2485
|
+
const tracing = await initializeToolCallEvent(server, request, conversation.conversationId ? cloneRequestWithoutConversationId(request) : request, extra, startTime, conversation);
|
|
2302
2486
|
if (request?.params?.name === "get_more_tools") return await executeReportMissingTool(server, request, tracing, startTime);
|
|
2303
2487
|
return await executeOriginalTool(originalHandler, server, request, extra, tracing, startTime);
|
|
2304
2488
|
}
|
|
2305
|
-
async function initializeToolCallEvent(server, request, extra, startTime) {
|
|
2489
|
+
async function initializeToolCallEvent(server, request, downstreamRequest, extra, startTime, conversation) {
|
|
2306
2490
|
try {
|
|
2307
2491
|
const data = getServerTrackingData(server);
|
|
2308
2492
|
if (!data) {
|
|
2309
2493
|
writeToLog("Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called track(server, options) before using tool calls.");
|
|
2310
2494
|
return {
|
|
2311
2495
|
event: null,
|
|
2496
|
+
mintedConversationId: void 0,
|
|
2312
2497
|
shouldPublishEvent: false
|
|
2313
2498
|
};
|
|
2314
2499
|
}
|
|
2315
2500
|
const event = {
|
|
2316
2501
|
sessionId: getServerSessionId(server, extra),
|
|
2502
|
+
conversationId: conversation.conversationId,
|
|
2317
2503
|
resourceName: request.params?.name || "Unknown Tool",
|
|
2318
|
-
parameters: buildCapturedMcpParameters(
|
|
2504
|
+
parameters: buildCapturedMcpParameters(downstreamRequest),
|
|
2319
2505
|
eventType: MCPAnalyticsEventType.mcpToolsCall,
|
|
2320
2506
|
timestamp: startTime,
|
|
2321
2507
|
redactionFn: data.options.redactSensitiveInformation
|
|
@@ -2323,16 +2509,17 @@ async function initializeToolCallEvent(server, request, extra, startTime) {
|
|
|
2323
2509
|
await handleIdentify(server, data, request, extra);
|
|
2324
2510
|
event.sessionId = data.sessionId;
|
|
2325
2511
|
await applyResolvedMetadata(event, data, request, extra);
|
|
2326
|
-
|
|
2327
|
-
if (isContextEnabled(data.options.context) && contextArgument) event.userIntent = contextArgument;
|
|
2512
|
+
setEventIntent(event, await resolveToolCallIntent(data, request, extra));
|
|
2328
2513
|
return {
|
|
2329
2514
|
event,
|
|
2515
|
+
mintedConversationId: conversation.minted ? conversation.conversationId : void 0,
|
|
2330
2516
|
shouldPublishEvent: true
|
|
2331
2517
|
};
|
|
2332
2518
|
} catch (error) {
|
|
2333
2519
|
writeToLog(`Warning: PostHog MCP analytics tracing failed for tool ${request.params?.name}, falling back to original handler - ${error}`);
|
|
2334
2520
|
return {
|
|
2335
2521
|
event: null,
|
|
2522
|
+
mintedConversationId: void 0,
|
|
2336
2523
|
shouldPublishEvent: false
|
|
2337
2524
|
};
|
|
2338
2525
|
}
|
|
@@ -2347,7 +2534,10 @@ async function executeReportMissingTool(server, request, tracing, startTime) {
|
|
|
2347
2534
|
try {
|
|
2348
2535
|
const context = getContextArgument(request) || "";
|
|
2349
2536
|
const result = await handleReportMissing({ context });
|
|
2350
|
-
publishSuccessfulToolEvent(server, tracing, result, startTime, {
|
|
2537
|
+
publishSuccessfulToolEvent(server, tracing, result, startTime, {
|
|
2538
|
+
userIntent: context,
|
|
2539
|
+
userIntentSource: "context_parameter"
|
|
2540
|
+
});
|
|
2351
2541
|
return result;
|
|
2352
2542
|
} catch (error) {
|
|
2353
2543
|
publishFailedToolEvent(server, tracing, error, startTime);
|
|
@@ -2357,14 +2547,20 @@ async function executeReportMissingTool(server, request, tracing, startTime) {
|
|
|
2357
2547
|
async function executeOriginalTool(originalHandler, server, request, extra, tracing, startTime) {
|
|
2358
2548
|
try {
|
|
2359
2549
|
const result = await originalHandler(request, extra);
|
|
2360
|
-
|
|
2550
|
+
let finalResult = result;
|
|
2551
|
+
if (tracing.mintedConversationId) {
|
|
2552
|
+
if (canInjectConversationIdPromptBack(result)) finalResult = injectConversationIdPromptBack(result, tracing.mintedConversationId);
|
|
2553
|
+
else if (tracing.event) tracing.event.conversationId = void 0;
|
|
2554
|
+
}
|
|
2555
|
+
publishSuccessfulToolEvent(server, tracing, finalResult, startTime, {
|
|
2361
2556
|
capturedError: extra?.__mcp_analytics_error,
|
|
2362
2557
|
clearCapturedError: () => {
|
|
2363
2558
|
if (extra) extra.__mcp_analytics_error = void 0;
|
|
2364
2559
|
}
|
|
2365
2560
|
});
|
|
2366
|
-
return
|
|
2561
|
+
return finalResult;
|
|
2367
2562
|
} catch (error) {
|
|
2563
|
+
if (tracing.mintedConversationId && tracing.event) tracing.event.conversationId = void 0;
|
|
2368
2564
|
publishFailedToolEvent(server, tracing, error, startTime);
|
|
2369
2565
|
throw error;
|
|
2370
2566
|
}
|
|
@@ -2375,12 +2571,15 @@ function getContextArgument(request) {
|
|
|
2375
2571
|
}
|
|
2376
2572
|
function publishSuccessfulToolEvent(server, tracing, result, startTime, options = {}) {
|
|
2377
2573
|
if (!(tracing.event && tracing.shouldPublishEvent)) return;
|
|
2378
|
-
if (options.userIntent)
|
|
2574
|
+
if (options.userIntent) {
|
|
2575
|
+
setExplicitContextIntent(tracing.event, options.userIntent);
|
|
2576
|
+
if (options.userIntentSource) tracing.event.userIntentSource = options.userIntentSource;
|
|
2577
|
+
}
|
|
2379
2578
|
if (isToolResultError(result)) {
|
|
2380
2579
|
tracing.event.isError = true;
|
|
2381
2580
|
tracing.event.error = captureException(options.capturedError || result);
|
|
2382
2581
|
options.clearCapturedError?.();
|
|
2383
|
-
}
|
|
2582
|
+
} else tracing.event.isError = false;
|
|
2384
2583
|
tracing.event.response = result;
|
|
2385
2584
|
tracing.event.duration = Date.now() - startTime.getTime();
|
|
2386
2585
|
publishEvent(server, tracing.event);
|
|
@@ -2417,6 +2616,7 @@ function setupTracking(server) {
|
|
|
2417
2616
|
* @param options.enableAITracing - Emits `$ai_span` events for tool calls so MCP activity appears in PostHog LLM analytics. Defaults to false.
|
|
2418
2617
|
* @param options.enableTracing - Enables tracking of tool calls and usage patterns.
|
|
2419
2618
|
* @param options.context - Enables the required "context" parameter on tools to capture user intent. Pass false to disable, or an object with a custom description.
|
|
2619
|
+
* @param options.intentFallback - Optional consumer-supplied callback invoked when a tool call has no explicit `context` argument. Return a short user intent string to capture as `$mcp_intent` (with `$mcp_intent_source = "inferred"`). The SDK does not infer anything on its own — this is purely a slot for your own derivation logic (e.g. a switch on `request.params.name`, an LLM call, etc.). Runs on the hot path of every uncontextualized tool call.
|
|
2420
2620
|
* @param options.identify - Async function to identify users and attach custom data to their sessions.
|
|
2421
2621
|
* @param options.redactSensitiveInformation - Function to redact sensitive data before sending to PostHog.
|
|
2422
2622
|
* @param options.eventTags - Callback invoked on every auto-captured event (tool calls, tool lists, initialize) to attach string key-value tags. Tags are intended to be indexed and queryable in PostHog — use them for structured metadata you'll want to filter or group by (e.g., trace IDs, environments, regions). Tags are validated client-side: keys must be ≤32 chars matching `[a-zA-Z0-9$_.:\- ]`, values must be strings ≤200 chars with no newlines, max 50 entries per event. Invalid entries are silently dropped with a warning logged to `~/posthog-mcp-analytics.log`. If the callback throws or returns null, tags are omitted. Receives the same `(request, extra)` arguments as `identify`.
|
|
@@ -2544,13 +2744,15 @@ function buildTrackingData(lowLevelServer, options) {
|
|
|
2544
2744
|
enableAITracing: options.enableAITracing ?? false,
|
|
2545
2745
|
enableTracing: options.enableTracing ?? true,
|
|
2546
2746
|
context: options.context,
|
|
2747
|
+
intentFallback: options.intentFallback,
|
|
2547
2748
|
identify: options.identify,
|
|
2548
2749
|
redactSensitiveInformation: options.redactSensitiveInformation,
|
|
2549
2750
|
eventTags: options.eventTags,
|
|
2550
2751
|
eventProperties: options.eventProperties,
|
|
2551
2752
|
host: options.host,
|
|
2552
2753
|
posthogClient: options.posthogClient,
|
|
2553
|
-
posthogOptions: options.posthogOptions
|
|
2754
|
+
posthogOptions: options.posthogOptions,
|
|
2755
|
+
enableConversationId: options.enableConversationId ?? false
|
|
2554
2756
|
},
|
|
2555
2757
|
sessionSource: "generated"
|
|
2556
2758
|
};
|
|
@@ -2688,6 +2890,8 @@ function publishResolvedCustomEvent(target, event) {
|
|
|
2688
2890
|
eventQueue.add(event);
|
|
2689
2891
|
}
|
|
2690
2892
|
//#endregion
|
|
2893
|
+
exports.POSTHOG_MCP_ANALYTICS_SOURCE = POSTHOG_MCP_ANALYTICS_SOURCE;
|
|
2894
|
+
exports.PostHogMCPAnalyticsEvent = PostHogMCPAnalyticsEvent;
|
|
2691
2895
|
exports.PostHogMCPAnalyticsProperty = PostHogMCPAnalyticsProperty;
|
|
2692
2896
|
exports.publishCustomEvent = publishCustomEvent;
|
|
2693
2897
|
exports.track = track;
|