@@ -29,15 +29,17 @@ const posthog = projectToken
2929// Every property this integration sends. An allow-list rather than a deny-list so a
3030// property the pinned SDK doesn't emit today — a renamed payload field, a new one —
3131// can't start flowing on an upgrade. Deliberately absent: $mcp_parameters and
32- // $mcp_response (call payloads), $mcp_error_message (the text a failed tool returned),
33- // and $mcp_intent / $mcp_intent_source (agent-written, and intent capture is off ).
32+ // $mcp_response (call payloads), and $mcp_error_message (the text a failed tool
33+ // returned ).
3434const SENT_PROPERTIES = new Set < string > ( [
3535 "$groups" ,
3636 "$process_person_profile" ,
3737 PostHogMCPAnalyticsProperty . ClientName ,
3838 PostHogMCPAnalyticsProperty . ClientVersion ,
3939 PostHogMCPAnalyticsProperty . DurationMs ,
4040 PostHogMCPAnalyticsProperty . ErrorType ,
41+ PostHogMCPAnalyticsProperty . Intent ,
42+ PostHogMCPAnalyticsProperty . IntentSource ,
4143 PostHogMCPAnalyticsProperty . IsError ,
4244 PostHogMCPAnalyticsProperty . ListedToolNames ,
4345 PostHogMCPAnalyticsProperty . ProtocolVersion ,
@@ -51,6 +53,18 @@ const SENT_PROPERTIES = new Set<string>([
5153 PostHogMCPAnalyticsProperty . ToolName ,
5254] ) ;
5355
56+ const INTENT_ARGUMENT_DESCRIPTION =
57+ "Why this tool is being called and how it fits the user's overall goal, in 15-25 words, " +
58+ "third person. Used for product analytics. Never restate argument values, and never " +
59+ "include credentials, tokens, URLs, file contents, or personal data. Example: " +
60+ '"Inspecting a running browser session to diagnose a checkout automation that stopped ' +
61+ 'responding partway through the flow."' ;
62+
63+ // Intent is the only free-form text this captures, and an agent writes it. Long enough for
64+ // the 15-25 words asked for, short enough that a client ignoring the instruction can't
65+ // stream a payload or a prompt into an event property.
66+ const INTENT_MAX_LENGTH = 300 ;
67+
5468/**
5569 * Captures every tool call, tools/list, and initialize handled by the server as a
5670 * `$mcp_*` PostHog event. No-op when POSTHOG_PROJECT_TOKEN is unset.
@@ -59,9 +73,11 @@ export function instrumentMcpAnalytics(server: McpServer) {
5973 if ( ! posthog ) return ;
6074
6175 instrument ( server , posthog , {
62- // Intent capture injects a required `context` argument into every tool schema.
63- // Left off so the public tool surface is unchanged.
64- context : false ,
76+ // Adds a required `context` argument to every advertised tool, which the agent fills
77+ // with why it is making the call. Recorded as $mcp_intent. The description replaces
78+ // the SDK default: it repeats per tool in every tools/list response, so it stays
79+ // short, and it names the arguments agents must not copy into it.
80+ context : { description : INTENT_ARGUMENT_DESCRIPTION } ,
6581 // A failed tool call otherwise fans out into a second `$exception` event whose
6682 // `$exception_list` is built from the text the tool returned.
6783 enableExceptionAutocapture : false ,
@@ -86,6 +102,14 @@ export function instrumentMcpAnalytics(server: McpServer) {
86102 if ( ! SENT_PROPERTIES . has ( key ) ) delete properties [ key ] ;
87103 }
88104
105+ const intent = properties [ PostHogMCPAnalyticsProperty . Intent ] ;
106+ if ( typeof intent === "string" && intent . length > INTENT_MAX_LENGTH ) {
107+ properties [ PostHogMCPAnalyticsProperty . Intent ] = intent . slice (
108+ 0 ,
109+ INTENT_MAX_LENGTH ,
110+ ) ;
111+ }
112+
89113 return event ;
90114 } ,
91115 } ) ;
0 commit comments