@posthog/mcp 0.10.3 → 0.10.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/dist/extensions/analytics-parameters.d.ts +5 -0
- package/dist/extensions/analytics-parameters.d.ts.map +1 -1
- package/dist/extensions/analytics-parameters.js +57 -3
- package/dist/extensions/analytics-parameters.mjs +47 -2
- package/dist/extensions/context-parameters.d.ts +1 -1
- package/dist/extensions/context-parameters.js +1 -1
- package/dist/extensions/context-parameters.mjs +1 -1
- package/dist/extensions/conversation-id.d.ts +0 -6
- package/dist/extensions/conversation-id.d.ts.map +1 -1
- package/dist/extensions/conversation-id.js +3 -18
- package/dist/extensions/conversation-id.mjs +2 -14
- package/dist/extensions/instrument-highlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-highlevel.js +9 -28
- package/dist/extensions/instrument-highlevel.mjs +8 -27
- package/dist/extensions/instrumentation.d.ts +4 -6
- package/dist/extensions/instrumentation.d.ts.map +1 -1
- package/dist/extensions/instrumentation.js +32 -6
- package/dist/extensions/instrumentation.mjs +33 -7
- package/dist/extensions/intent.d.ts +1 -1
- package/dist/extensions/intent.d.ts.map +1 -1
- package/dist/extensions/intent.js +2 -2
- package/dist/extensions/intent.mjs +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +4 -4
- package/src/extensions/analytics-parameters.ts +67 -1
- package/src/extensions/context-parameters.ts +2 -2
- package/src/extensions/conversation-id.ts +1 -20
- package/src/extensions/instrument-highlevel.ts +21 -50
- package/src/extensions/instrumentation.ts +71 -11
- package/src/extensions/intent.ts +7 -1
- package/src/index.ts +1 -0
- package/src/types.ts +6 -0
- package/src/version.ts +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type { ListToolsResult } from '@modelcontextprotocol/sdk/types.js'
|
|
7
7
|
import type {
|
|
8
|
+
AnalyticsParameterOwnership,
|
|
8
9
|
CompatibleRequestHandlerExtra,
|
|
9
10
|
MCPAnalyticsData,
|
|
10
11
|
MCPRequestLike,
|
|
@@ -12,12 +13,12 @@ import type {
|
|
|
12
13
|
McpEvent,
|
|
13
14
|
ServerClientInfoLike,
|
|
14
15
|
} from '../types'
|
|
16
|
+
import { getAnalyticsParameterOwnership, stripOwnedAnalyticsArguments } from './analytics-parameters'
|
|
15
17
|
import { addContextParameterToTools, getContextDescription, isContextEnabled } from './context-parameters'
|
|
16
18
|
import {
|
|
17
19
|
addConversationIdToTools,
|
|
18
20
|
type ConversationIdResolution,
|
|
19
21
|
canInjectConversationIdPromptBack,
|
|
20
|
-
cloneRequestWithoutConversationId,
|
|
21
22
|
injectConversationIdPromptBack,
|
|
22
23
|
resolveConversationId,
|
|
23
24
|
} from './conversation-id'
|
|
@@ -45,11 +46,7 @@ import { applyResolvedMetadata, isToolResultError } from './tracing-helpers'
|
|
|
45
46
|
|
|
46
47
|
type MCPRequestHandler = (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise<unknown>
|
|
47
48
|
|
|
48
|
-
/**
|
|
49
|
-
* Runs the underlying tool. Receives the request with the SDK-injected
|
|
50
|
-
* `conversation_id` stripped; an adapter is free to ignore it (the high-level
|
|
51
|
-
* path strips arguments inside the wrapped callback instead).
|
|
52
|
-
*/
|
|
49
|
+
/** Runs the underlying tool with SDK-owned analytics arguments removed. */
|
|
53
50
|
type ToolExecutor = (downstreamRequest: MCPRequestLike) => Promise<unknown>
|
|
54
51
|
|
|
55
52
|
interface TraceToolCallParams {
|
|
@@ -58,6 +55,8 @@ interface TraceToolCallParams {
|
|
|
58
55
|
request: MCPRequestLike
|
|
59
56
|
extra?: CompatibleRequestHandlerExtra
|
|
60
57
|
execute: ToolExecutor
|
|
58
|
+
/** Optional schema-derived ownership override for adapters with direct registry access. */
|
|
59
|
+
parameterOwnership?: AnalyticsParameterOwnership
|
|
61
60
|
/**
|
|
62
61
|
* Event type to capture. Defaults to a tool call; the `get_more_tools` virtual
|
|
63
62
|
* tool passes `mcpMissingCapability` so it records a capability gap rather than
|
|
@@ -88,15 +87,26 @@ interface TraceToolCallParams {
|
|
|
88
87
|
* throws, and the tool's own errors are always re-thrown to the caller.
|
|
89
88
|
*/
|
|
90
89
|
export async function captureToolCall(params: TraceToolCallParams): Promise<unknown> {
|
|
91
|
-
const {
|
|
92
|
-
|
|
90
|
+
const {
|
|
91
|
+
server,
|
|
92
|
+
data,
|
|
93
|
+
request,
|
|
94
|
+
extra,
|
|
95
|
+
execute,
|
|
96
|
+
parameterOwnership,
|
|
97
|
+
eventType,
|
|
98
|
+
explicitContextIntent,
|
|
99
|
+
takeCapturedError,
|
|
100
|
+
} = params
|
|
101
|
+
|
|
102
|
+
const ownership = getActiveAnalyticsParameterOwnership(data, request.params?.name, parameterOwnership)
|
|
93
103
|
const conversation = resolveConversationId(
|
|
94
|
-
|
|
104
|
+
ownership.conversationId,
|
|
95
105
|
request.params?.arguments,
|
|
96
106
|
request.params?.name,
|
|
97
107
|
resolveMissingCapabilityToolName(data.options)
|
|
98
108
|
)
|
|
99
|
-
const downstreamRequest =
|
|
109
|
+
const downstreamRequest = cloneRequestWithoutOwnedAnalyticsArguments(request, ownership)
|
|
100
110
|
|
|
101
111
|
// Prepare the event in isolation: if identity/metadata/intent resolution
|
|
102
112
|
// throws, we drop instrumentation for this call but still run the tool.
|
|
@@ -109,6 +119,7 @@ export async function captureToolCall(params: TraceToolCallParams): Promise<unkn
|
|
|
109
119
|
extra,
|
|
110
120
|
startTime,
|
|
111
121
|
conversation,
|
|
122
|
+
ownership,
|
|
112
123
|
eventType ?? MCPAnalyticsEventType.mcpToolsCall
|
|
113
124
|
)
|
|
114
125
|
if (event && explicitContextIntent) {
|
|
@@ -128,6 +139,38 @@ export async function captureToolCall(params: TraceToolCallParams): Promise<unkn
|
|
|
128
139
|
return finalResult
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
function getActiveAnalyticsParameterOwnership(
|
|
143
|
+
data: MCPAnalyticsData,
|
|
144
|
+
toolName: string | undefined,
|
|
145
|
+
override?: AnalyticsParameterOwnership
|
|
146
|
+
): AnalyticsParameterOwnership {
|
|
147
|
+
const ownership = override ?? (toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : undefined)
|
|
148
|
+
const isMissingCapabilityTool = toolName === resolveMissingCapabilityToolName(data.options)
|
|
149
|
+
return {
|
|
150
|
+
context: !isMissingCapabilityTool && isContextEnabled(data.options.context) && ownership?.context === true,
|
|
151
|
+
conversationId:
|
|
152
|
+
!isMissingCapabilityTool && data.options.enableConversationId === true && ownership?.conversationId === true,
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function cloneRequestWithoutOwnedAnalyticsArguments(
|
|
157
|
+
request: MCPRequestLike,
|
|
158
|
+
ownership: AnalyticsParameterOwnership
|
|
159
|
+
): MCPRequestLike {
|
|
160
|
+
const args = request.params?.arguments
|
|
161
|
+
const cleanedArgs = stripOwnedAnalyticsArguments(args, ownership)
|
|
162
|
+
if (cleanedArgs === args || !request.params) {
|
|
163
|
+
return request
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
...request,
|
|
167
|
+
params: {
|
|
168
|
+
...request.params,
|
|
169
|
+
arguments: cleanedArgs as typeof request.params.arguments,
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
131
174
|
async function prepareToolCallEvent(
|
|
132
175
|
server: MCPServerLike,
|
|
133
176
|
data: MCPAnalyticsData,
|
|
@@ -136,6 +179,7 @@ async function prepareToolCallEvent(
|
|
|
136
179
|
extra: CompatibleRequestHandlerExtra | undefined,
|
|
137
180
|
startTime: Date,
|
|
138
181
|
conversation: ConversationIdResolution,
|
|
182
|
+
ownership: AnalyticsParameterOwnership,
|
|
139
183
|
eventType: MCPAnalyticsEventType
|
|
140
184
|
): Promise<McpEvent | null> {
|
|
141
185
|
try {
|
|
@@ -159,7 +203,7 @@ async function prepareToolCallEvent(
|
|
|
159
203
|
stampMetaClientInfo(event, request)
|
|
160
204
|
|
|
161
205
|
await applyResolvedMetadata(event, data, request, extra)
|
|
162
|
-
setEventIntent(event, await resolveToolCallIntent(data, request, extra))
|
|
206
|
+
setEventIntent(event, await resolveToolCallIntent(data, request, ownership.context, extra))
|
|
163
207
|
return event
|
|
164
208
|
} catch (error) {
|
|
165
209
|
log(
|
|
@@ -336,6 +380,18 @@ export async function handleListToolsRequest(
|
|
|
336
380
|
return { tools }
|
|
337
381
|
}
|
|
338
382
|
|
|
383
|
+
function cacheToolAnalyticsParameterOwnership(
|
|
384
|
+
cache: Map<string, AnalyticsParameterOwnership>,
|
|
385
|
+
tools: ListToolsResult['tools']
|
|
386
|
+
): void {
|
|
387
|
+
// Merge pages and concurrent enumerations; repeated tool names overwrite stale schemas.
|
|
388
|
+
for (const tool of tools) {
|
|
389
|
+
if (tool?.name) {
|
|
390
|
+
cache.set(tool.name, getAnalyticsParameterOwnership(tool.inputSchema))
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
339
395
|
function collectListedToolNames(tools: ListToolsResult['tools'] | undefined): string[] | undefined {
|
|
340
396
|
if (!tools || tools.length === 0) {
|
|
341
397
|
return
|
|
@@ -356,6 +412,10 @@ async function getTracedToolsList(
|
|
|
356
412
|
const originalResponse = (await originalListToolsHandler(request, extra)) as ListToolsResult
|
|
357
413
|
let tools = originalResponse.tools || []
|
|
358
414
|
|
|
415
|
+
if (data) {
|
|
416
|
+
cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, tools)
|
|
417
|
+
}
|
|
418
|
+
|
|
359
419
|
if (data && isContextEnabled(data.options.context)) {
|
|
360
420
|
tools = addContextParameterToTools(tools, getContextDescription(data.options.context))
|
|
361
421
|
}
|
package/src/extensions/intent.ts
CHANGED
|
@@ -53,10 +53,16 @@ async function runIntentFallback(
|
|
|
53
53
|
export async function resolveToolCallIntent(
|
|
54
54
|
data: MCPAnalyticsData,
|
|
55
55
|
request: MCPRequestLike,
|
|
56
|
+
analyticsOwnsContext: boolean,
|
|
56
57
|
extra?: CompatibleRequestHandlerExtra
|
|
57
58
|
): Promise<ResolvedIntent | null> {
|
|
58
59
|
const contextArgument = getContextArgument(request)
|
|
59
|
-
if (
|
|
60
|
+
if (
|
|
61
|
+
analyticsOwnsContext &&
|
|
62
|
+
isContextEnabled(data.options.context) &&
|
|
63
|
+
request.params?.name !== 'get_more_tools' &&
|
|
64
|
+
contextArgument
|
|
65
|
+
) {
|
|
60
66
|
return { intent: contextArgument, source: 'context_parameter' }
|
|
61
67
|
}
|
|
62
68
|
|
package/src/index.ts
CHANGED
|
@@ -143,6 +143,7 @@ function buildTrackingData(
|
|
|
143
143
|
sessionId: newSessionId(),
|
|
144
144
|
lastActivity: new Date(),
|
|
145
145
|
identifiedSessions: new IdentityCache(),
|
|
146
|
+
toolAnalyticsParameterOwnership: new Map(),
|
|
146
147
|
toolCategories: new Map<string, string>(),
|
|
147
148
|
toolDescriptions: new Map<string, string>(),
|
|
148
149
|
sessionInfo: getSessionInfo(lowLevelServer, undefined),
|
package/src/types.ts
CHANGED
|
@@ -271,6 +271,11 @@ export interface SessionInfo {
|
|
|
271
271
|
serverVersion?: string
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
export interface AnalyticsParameterOwnership {
|
|
275
|
+
context: boolean
|
|
276
|
+
conversationId: boolean
|
|
277
|
+
}
|
|
278
|
+
|
|
274
279
|
export interface MCPAnalyticsData {
|
|
275
280
|
sink: McpEventSink | undefined
|
|
276
281
|
identifiedSessions: IdentityCache
|
|
@@ -280,6 +285,7 @@ export interface MCPAnalyticsData {
|
|
|
280
285
|
sessionInfo: SessionInfo
|
|
281
286
|
/** `token` = recovered from a self-encoded `Mcp-Session-Id` token (see session-token.ts). */
|
|
282
287
|
sessionSource: 'generated' | 'mcp' | 'token'
|
|
288
|
+
toolAnalyticsParameterOwnership: Map<string, AnalyticsParameterOwnership>
|
|
283
289
|
toolCategories: Map<string, string>
|
|
284
290
|
toolDescriptions: Map<string, string>
|
|
285
291
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '0.10.
|
|
1
|
+
export const version = '0.10.4'
|