Skip to content

Commit 4b65165

Browse files
authored
Merge branch 'main' into hypeship/classify-tool-errors
2 parents b9aa34d + 4bc4a43 commit 4b65165

2 files changed

Lines changed: 33 additions & 5 deletions

File tree

‎src/lib/mcp/analytics.ts‎

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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).
3434
const 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
});

‎src/lib/mcp/tools/playwright.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ export function registerPlaywrightTool(server: McpServer) {
5656
],
5757
};
5858
} catch (error) {
59+
// No normal API response came back -- the session was gone, unleased, the request
60+
// was rejected, or it timed out. Distinct from code that ran and threw, which comes
61+
// back as a 200 with success: false so the agent can read the failure and adjust.
5962
return {
6063
content: [
6164
{
@@ -70,6 +73,7 @@ export function registerPlaywrightTool(server: McpServer) {
7073
),
7174
},
7275
],
76+
isError: true,
7377
};
7478
}
7579
},

0 commit comments

Comments
 (0)