@posthog/mcp 0.14.1 → 0.16.0
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/LICENSE +64 -0
- package/README.md +64 -0
- package/dist/extensions/constants.d.ts +9 -0
- package/dist/extensions/constants.d.ts.map +1 -1
- package/dist/extensions/constants.js +9 -0
- package/dist/extensions/constants.mjs +9 -0
- package/dist/extensions/event-types.d.ts +1 -0
- package/dist/extensions/event-types.d.ts.map +1 -1
- package/dist/extensions/event-types.js +1 -0
- package/dist/extensions/event-types.mjs +1 -0
- package/dist/extensions/feedback.d.ts +41 -0
- package/dist/extensions/feedback.d.ts.map +1 -0
- package/dist/extensions/feedback.js +259 -0
- package/dist/extensions/feedback.mjs +200 -0
- package/dist/extensions/instrument-highlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-highlevel.js +23 -2
- package/dist/extensions/instrument-highlevel.mjs +25 -4
- package/dist/extensions/instrument-lowlevel.d.ts +4 -3
- package/dist/extensions/instrument-lowlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-lowlevel.js +23 -2
- package/dist/extensions/instrument-lowlevel.mjs +25 -4
- package/dist/extensions/instrumentation.d.ts +33 -13
- package/dist/extensions/instrumentation.d.ts.map +1 -1
- package/dist/extensions/instrumentation.js +103 -9
- package/dist/extensions/instrumentation.mjs +99 -8
- package/dist/extensions/internal.js +9 -2
- package/dist/extensions/internal.mjs +9 -2
- package/dist/extensions/mcp-payloads.d.ts +19 -0
- package/dist/extensions/mcp-payloads.d.ts.map +1 -1
- package/dist/extensions/mcp-payloads.js +217 -7
- package/dist/extensions/mcp-payloads.mjs +210 -6
- package/dist/extensions/posthog-events.d.ts.map +1 -1
- package/dist/extensions/posthog-events.js +1 -0
- package/dist/extensions/posthog-events.mjs +1 -0
- package/dist/extensions/posthog-mcp.d.ts +23 -3
- package/dist/extensions/posthog-mcp.d.ts.map +1 -1
- package/dist/extensions/posthog-mcp.js +27 -1
- package/dist/extensions/posthog-mcp.mjs +27 -1
- package/dist/extensions/sanitization.d.ts.map +1 -1
- package/dist/extensions/sanitization.js +2 -1
- package/dist/extensions/sanitization.mjs +3 -2
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.mjs +5 -1
- package/dist/types.d.ts +114 -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/constants.ts +9 -0
- package/src/extensions/event-types.ts +1 -0
- package/src/extensions/feedback.ts +349 -0
- package/src/extensions/instrument-highlevel.ts +45 -2
- package/src/extensions/instrument-lowlevel.ts +49 -5
- package/src/extensions/instrumentation.ts +170 -17
- package/src/extensions/internal.ts +13 -2
- package/src/extensions/mcp-payloads.ts +443 -7
- package/src/extensions/posthog-events.ts +1 -0
- package/src/extensions/posthog-mcp.ts +74 -3
- package/src/extensions/sanitization.ts +14 -6
- package/src/index.ts +24 -3
- package/src/types.ts +120 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { PostHogMCPAnalyticsProperty } from "./constants.mjs";
|
|
2
|
+
import { log } from "./logger.mjs";
|
|
3
|
+
import { sanitizeFreeText, sanitizeFreeTextValue } from "./mcp-payloads.mjs";
|
|
4
|
+
const SEND_FEEDBACK_TOOL_NAME = 'send_feedback';
|
|
5
|
+
const FEEDBACK_TYPES = [
|
|
6
|
+
'missing_capability',
|
|
7
|
+
'issue',
|
|
8
|
+
'praise',
|
|
9
|
+
'other'
|
|
10
|
+
];
|
|
11
|
+
const SENTIMENTS = [
|
|
12
|
+
'positive',
|
|
13
|
+
'neutral',
|
|
14
|
+
'negative',
|
|
15
|
+
'mixed'
|
|
16
|
+
];
|
|
17
|
+
const MAX_FEEDBACK_TEXT_LENGTH = 2048;
|
|
18
|
+
const MAX_FEEDBACK_TOOL_NAME_LENGTH = 256;
|
|
19
|
+
const TRUNCATION_SUFFIX = '...';
|
|
20
|
+
const DEFAULT_FEEDBACK_DESCRIPTION = 'Send feedback about this server to its developers. Most important: report a missing capability whenever no available tool fits your task, even if you can work around it (feedback_type "missing_capability"). Also welcome: a tool that failed or confused you, an unhelpful error, or something that worked well. This records the feedback; it does not add or change tools. Do not include user PII or sensitive content.';
|
|
21
|
+
const CORE_FEEDBACK_SCHEMA_PROPERTIES = {
|
|
22
|
+
feedback_type: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
enum: [
|
|
25
|
+
...FEEDBACK_TYPES
|
|
26
|
+
],
|
|
27
|
+
description: "What kind of feedback this is. Use 'missing_capability' when the tool you needed does not exist in the tool list - nothing failed, the capability is absent (this is the most valuable report; send it even if you found a workaround). Use 'issue' when an existing tool behaved badly: it failed, returned a confusing error, or its description or schema misled you. Use 'praise' when something worked notably well. Use 'other' for anything else."
|
|
28
|
+
},
|
|
29
|
+
summary: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: "One self-contained sentence. For 'missing_capability': the capability you needed, e.g. 'No tool to delete multiple cohorts in one call.' For 'issue': the tool and the problem, e.g. 'query-trends rejects relative date ranges with an unclear error.'"
|
|
32
|
+
},
|
|
33
|
+
details: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: "Optional longer context: what you tried, exact parameter values, the error text you saw, and any workaround you used. Omit when the summary says it all."
|
|
36
|
+
},
|
|
37
|
+
friction_points: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: "Optional: the specific moments that slowed you down, as short bullet-like sentences, quoting exact tool names, parameters, or error text."
|
|
40
|
+
},
|
|
41
|
+
suggested_improvement: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description: "Optional: the concrete change that would have helped, e.g. the tool to add, the description to reword, or the error message to improve."
|
|
44
|
+
},
|
|
45
|
+
tool_name: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: "Optional: the existing tool this feedback is about (for 'issue' or 'praise'). Leave empty for 'missing_capability' - the point is that no tool fits."
|
|
48
|
+
},
|
|
49
|
+
sentiment: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
enum: [
|
|
52
|
+
...SENTIMENTS
|
|
53
|
+
],
|
|
54
|
+
description: 'Optional: how the experience felt overall.'
|
|
55
|
+
},
|
|
56
|
+
task_completed: {
|
|
57
|
+
type: 'boolean',
|
|
58
|
+
description: "Optional: whether you still completed the user's task despite the problem."
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const RESERVED_EXTRA_PROPERTY_KEYS = new Set([
|
|
62
|
+
...Object.keys(CORE_FEEDBACK_SCHEMA_PROPERTIES),
|
|
63
|
+
'type',
|
|
64
|
+
'tool',
|
|
65
|
+
'context',
|
|
66
|
+
'conversation_id',
|
|
67
|
+
'llm_model'
|
|
68
|
+
]);
|
|
69
|
+
function resolveCollectFeedbackOptions(config) {
|
|
70
|
+
if (!config) return;
|
|
71
|
+
return true === config ? {} : config;
|
|
72
|
+
}
|
|
73
|
+
function getFeedbackToolDescriptor(options = {}) {
|
|
74
|
+
const extraProperties = options.extraProperties ?? {};
|
|
75
|
+
const extraRequired = options.extraRequired ?? [];
|
|
76
|
+
for (const key of Object.keys(extraProperties))if (RESERVED_EXTRA_PROPERTY_KEYS.has(key)) throw new Error(`collectFeedback.extraProperties key "${key}" collides with a core or SDK-reserved send_feedback field. Rename it.`);
|
|
77
|
+
for (const key of extraRequired)if (!Object.prototype.hasOwnProperty.call(extraProperties, key)) throw new Error(`collectFeedback.extraRequired key "${key}" is not declared in extraProperties.`);
|
|
78
|
+
const copiedExtras = Object.keys(extraProperties).length > 0 ? JSON.parse(JSON.stringify(extraProperties)) : void 0;
|
|
79
|
+
return {
|
|
80
|
+
name: options.toolName ?? SEND_FEEDBACK_TOOL_NAME,
|
|
81
|
+
description: options.description ?? DEFAULT_FEEDBACK_DESCRIPTION,
|
|
82
|
+
inputSchema: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
...JSON.parse(JSON.stringify(CORE_FEEDBACK_SCHEMA_PROPERTIES)),
|
|
86
|
+
...copiedExtras
|
|
87
|
+
},
|
|
88
|
+
required: [
|
|
89
|
+
'feedback_type',
|
|
90
|
+
'summary',
|
|
91
|
+
...extraRequired
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
annotations: {
|
|
95
|
+
title: 'Send feedback',
|
|
96
|
+
readOnlyHint: true,
|
|
97
|
+
openWorldHint: true,
|
|
98
|
+
idempotentHint: true,
|
|
99
|
+
destructiveHint: false
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function readString(value) {
|
|
104
|
+
return 'string' == typeof value && value.trim() ? value : void 0;
|
|
105
|
+
}
|
|
106
|
+
function parseFeedbackType(value) {
|
|
107
|
+
return FEEDBACK_TYPES.includes(value) ? value : 'other';
|
|
108
|
+
}
|
|
109
|
+
function parseSentiment(value) {
|
|
110
|
+
return SENTIMENTS.includes(value) ? value : void 0;
|
|
111
|
+
}
|
|
112
|
+
function matchesExtraSchema(value, schema) {
|
|
113
|
+
const type = Array.isArray(value) ? 'array' : null === value ? 'null' : typeof value;
|
|
114
|
+
if (schema.type !== type && !('integer' === schema.type && 'number' == typeof value)) return false;
|
|
115
|
+
return !Array.isArray(schema.enum) || schema.enum.includes(value);
|
|
116
|
+
}
|
|
117
|
+
function parseFeedbackReport(args, options = {}) {
|
|
118
|
+
const raw = args ?? {};
|
|
119
|
+
const extras = {};
|
|
120
|
+
for (const [key, schema] of Object.entries(options.extraProperties ?? {}))if (void 0 !== raw[key] && matchesExtraSchema(raw[key], schema)) extras[key] = raw[key];
|
|
121
|
+
return {
|
|
122
|
+
feedbackType: parseFeedbackType(raw.feedback_type),
|
|
123
|
+
summary: readString(raw.summary) ?? '',
|
|
124
|
+
sentiment: parseSentiment(raw.sentiment),
|
|
125
|
+
frictionPoints: readString(raw.friction_points),
|
|
126
|
+
suggestedImprovement: readString(raw.suggested_improvement),
|
|
127
|
+
details: readString(raw.details),
|
|
128
|
+
toolName: readString(raw.tool_name),
|
|
129
|
+
taskCompleted: 'boolean' == typeof raw.task_completed ? raw.task_completed : void 0,
|
|
130
|
+
extras,
|
|
131
|
+
raw
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function buildFeedbackIntent(report) {
|
|
135
|
+
return [
|
|
136
|
+
report.summary,
|
|
137
|
+
report.details
|
|
138
|
+
].filter(Boolean).join('\n\n');
|
|
139
|
+
}
|
|
140
|
+
function truncateFeedbackText(value, maxLength) {
|
|
141
|
+
return value.length > maxLength ? value.slice(0, maxLength) + TRUNCATION_SUFFIX : value;
|
|
142
|
+
}
|
|
143
|
+
function captureFreeText(value) {
|
|
144
|
+
return truncateFeedbackText(sanitizeFreeText(value), MAX_FEEDBACK_TEXT_LENGTH);
|
|
145
|
+
}
|
|
146
|
+
function captureExtraValue(value) {
|
|
147
|
+
const sanitized = sanitizeFreeTextValue(value);
|
|
148
|
+
if ('string' == typeof sanitized) return truncateFeedbackText(sanitized, MAX_FEEDBACK_TEXT_LENGTH);
|
|
149
|
+
if (null == sanitized || 'number' == typeof sanitized || 'boolean' == typeof sanitized) return sanitized;
|
|
150
|
+
try {
|
|
151
|
+
return truncateFeedbackText(JSON.stringify(sanitized), MAX_FEEDBACK_TEXT_LENGTH);
|
|
152
|
+
} catch {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function buildFeedbackEventProperties(report) {
|
|
157
|
+
const properties = {
|
|
158
|
+
[PostHogMCPAnalyticsProperty.FeedbackType]: report.feedbackType
|
|
159
|
+
};
|
|
160
|
+
if (report.summary) properties[PostHogMCPAnalyticsProperty.FeedbackSummary] = captureFreeText(report.summary);
|
|
161
|
+
if (report.sentiment) properties[PostHogMCPAnalyticsProperty.FeedbackSentiment] = report.sentiment;
|
|
162
|
+
if (report.frictionPoints) properties[PostHogMCPAnalyticsProperty.FeedbackFrictionPoints] = captureFreeText(report.frictionPoints);
|
|
163
|
+
if (report.suggestedImprovement) properties[PostHogMCPAnalyticsProperty.FeedbackSuggestedImprovement] = captureFreeText(report.suggestedImprovement);
|
|
164
|
+
if (report.details) properties[PostHogMCPAnalyticsProperty.FeedbackDetails] = captureFreeText(report.details);
|
|
165
|
+
if (report.toolName) properties[PostHogMCPAnalyticsProperty.FeedbackTool] = truncateFeedbackText(sanitizeFreeText(report.toolName), MAX_FEEDBACK_TOOL_NAME_LENGTH);
|
|
166
|
+
if (void 0 !== report.taskCompleted) properties[PostHogMCPAnalyticsProperty.FeedbackTaskCompleted] = report.taskCompleted;
|
|
167
|
+
for (const [key, value] of Object.entries(report.extras)){
|
|
168
|
+
const captured = captureExtraValue(value);
|
|
169
|
+
if (void 0 !== captured) properties[`$mcp_feedback_${key}`] = captured;
|
|
170
|
+
}
|
|
171
|
+
return properties;
|
|
172
|
+
}
|
|
173
|
+
function sendFeedbackResult() {
|
|
174
|
+
return {
|
|
175
|
+
content: [
|
|
176
|
+
{
|
|
177
|
+
type: 'text',
|
|
178
|
+
text: "Your feedback was recorded for the server's developers. No additional tools are available - continue with the tools already listed."
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
async function handleFeedback(report, options = {}, logger = log) {
|
|
184
|
+
logger(`Agent feedback reported (${report.feedbackType})`);
|
|
185
|
+
if (options.onFeedback) try {
|
|
186
|
+
const reply = await options.onFeedback(report);
|
|
187
|
+
if ('string' == typeof reply && reply.trim()) return {
|
|
188
|
+
content: [
|
|
189
|
+
{
|
|
190
|
+
type: 'text',
|
|
191
|
+
text: reply
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
};
|
|
195
|
+
} catch (error) {
|
|
196
|
+
logger(`Warning: onFeedback handler threw; returning the default acknowledgement - ${error}`);
|
|
197
|
+
}
|
|
198
|
+
return sendFeedbackResult();
|
|
199
|
+
}
|
|
200
|
+
export { SEND_FEEDBACK_TOOL_NAME, buildFeedbackEventProperties, buildFeedbackIntent, getFeedbackToolDescriptor, handleFeedback, parseFeedbackReport, resolveCollectFeedbackOptions, sendFeedbackResult };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,sBAAsB,EAIvB,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,sBAAsB,EAIvB,MAAM,UAAU,CAAA;AAmBjB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAgSxC,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CA+BhG"}
|
|
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
30
30
|
__webpack_require__.d(__webpack_exports__, {
|
|
31
31
|
instrumentHighLevelServer: ()=>instrumentHighLevelServer
|
|
32
32
|
});
|
|
33
|
+
const external_feedback_js_namespaceObject = require("./feedback.js");
|
|
33
34
|
const external_analytics_parameters_js_namespaceObject = require("./analytics-parameters.js");
|
|
34
35
|
const external_context_parameters_js_namespaceObject = require("./context-parameters.js");
|
|
35
36
|
const external_model_parameters_js_namespaceObject = require("./model-parameters.js");
|
|
@@ -171,12 +172,29 @@ async function handleToolCallRequest(highLevelServer, server, originalCallToolHa
|
|
|
171
172
|
extra,
|
|
172
173
|
eventType: external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpMissingCapability,
|
|
173
174
|
explicitContextIntent: context,
|
|
174
|
-
parameterOwnership: (0, external_instrumentation_js_namespaceObject.getVirtualToolParameterOwnership)(data, toolName),
|
|
175
|
+
parameterOwnership: (0, external_instrumentation_js_namespaceObject.getVirtualToolParameterOwnership)(data, toolName, (0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(toolName).inputSchema),
|
|
175
176
|
execute: async ()=>(0, external_tools_js_namespaceObject.handleReportMissing)({
|
|
176
177
|
context
|
|
177
178
|
}, data.logger)
|
|
178
179
|
});
|
|
179
180
|
}
|
|
181
|
+
const feedbackOptions = (0, external_feedback_js_namespaceObject.resolveCollectFeedbackOptions)(data.options.collectFeedback);
|
|
182
|
+
const isFeedbackCandidate = void 0 !== feedbackOptions && toolName === (feedbackOptions.toolName ?? external_feedback_js_namespaceObject.SEND_FEEDBACK_TOOL_NAME);
|
|
183
|
+
if (isFeedbackCandidate && await (0, external_instrumentation_js_namespaceObject.isToolAdvertised)(server, toolName, extra, data.logger) === false) {
|
|
184
|
+
const report = (0, external_feedback_js_namespaceObject.parseFeedbackReport)(request.params?.arguments, feedbackOptions);
|
|
185
|
+
return await (0, external_instrumentation_js_namespaceObject.captureToolCall)({
|
|
186
|
+
server,
|
|
187
|
+
data,
|
|
188
|
+
request,
|
|
189
|
+
extra,
|
|
190
|
+
eventType: external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpFeedback,
|
|
191
|
+
explicitContextIntent: (0, external_feedback_js_namespaceObject.buildFeedbackIntent)(report),
|
|
192
|
+
omitCapturedParameters: true,
|
|
193
|
+
extraEventProperties: (0, external_feedback_js_namespaceObject.buildFeedbackEventProperties)(report),
|
|
194
|
+
parameterOwnership: (0, external_instrumentation_js_namespaceObject.getVirtualToolParameterOwnership)(data, toolName, (0, external_feedback_js_namespaceObject.getFeedbackToolDescriptor)(feedbackOptions).inputSchema),
|
|
195
|
+
execute: async ()=>(0, external_feedback_js_namespaceObject.handleFeedback)(report, feedbackOptions, data.logger)
|
|
196
|
+
});
|
|
197
|
+
}
|
|
180
198
|
const registeredTool = toolName ? highLevelServer._registeredTools[toolName] : void 0;
|
|
181
199
|
return await (0, external_instrumentation_js_namespaceObject.captureToolCall)({
|
|
182
200
|
server,
|
|
@@ -199,7 +217,10 @@ function instrumentHighLevelServer(server, logger) {
|
|
|
199
217
|
const handlers = {
|
|
200
218
|
initialize: (trackedServer, originalHandler, request, extra)=>(0, external_instrumentation_js_namespaceObject.handleInitializeRequest)(trackedServer, originalHandler, request, extra, logger),
|
|
201
219
|
'tools/list': (trackedServer, originalHandler, request, extra)=>(0, external_instrumentation_js_namespaceObject.handleListToolsRequest)(trackedServer, originalHandler, request, extra, logger),
|
|
202
|
-
'tools/call': (trackedServer, originalHandler, request, extra)=>handleToolCallRequest(server, trackedServer, originalHandler, request, extra, logger)
|
|
220
|
+
'tools/call': (trackedServer, originalHandler, request, extra)=>handleToolCallRequest(server, trackedServer, originalHandler, request, extra, logger),
|
|
221
|
+
'resources/list': (0, external_instrumentation_js_namespaceObject.traceResourceRequest)(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
222
|
+
'resources/templates/list': (0, external_instrumentation_js_namespaceObject.traceResourceRequest)(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
223
|
+
'resources/read': (0, external_instrumentation_js_namespaceObject.traceResourceRequest)(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpResourcesRead, logger)
|
|
203
224
|
};
|
|
204
225
|
(0, external_instrumentation_js_namespaceObject.patchRequestHandlers)(lowLevelServer, handlers);
|
|
205
226
|
server._registeredTools = addTracingToToolRegistry(server._registeredTools, server, logger);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { SEND_FEEDBACK_TOOL_NAME, buildFeedbackEventProperties, buildFeedbackIntent, getFeedbackToolDescriptor, handleFeedback, parseFeedbackReport, resolveCollectFeedbackOptions } from "./feedback.mjs";
|
|
1
2
|
import { analyticsOwnsParameter, getAnalyticsParameterOwnership, stripOwnedAnalyticsArguments } from "./analytics-parameters.mjs";
|
|
2
3
|
import { isContextEnabled } from "./context-parameters.mjs";
|
|
3
4
|
import { isCaptureModelEnabled } from "./model-parameters.mjs";
|
|
4
5
|
import { MCPAnalyticsEventType } from "./event-types.mjs";
|
|
5
6
|
import { getServerTrackingData } from "./internal.mjs";
|
|
6
7
|
import { createWrappedTool, getToolFunction, hasToolFunction } from "./mcp-sdk-compat.mjs";
|
|
7
|
-
import { handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
8
|
-
import { captureToolCall, getVirtualToolParameterOwnership, handleInitializeRequest, handleListToolsRequest, isToolAdvertised, patchRequestHandlers, readToolMetaCategory } from "./instrumentation.mjs";
|
|
8
|
+
import { getReportMissingToolDescriptor, handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
9
|
+
import { captureToolCall, getVirtualToolParameterOwnership, handleInitializeRequest, handleListToolsRequest, isToolAdvertised, patchRequestHandlers, readToolMetaCategory, traceResourceRequest } from "./instrumentation.mjs";
|
|
9
10
|
import { getContextArgument } from "./tracing-helpers.mjs";
|
|
10
11
|
const wrappedCallbacks = new WeakMap();
|
|
11
12
|
const MCP_ANALYTICS_PROCESSED = Symbol('__posthog_mcp_analytics_processed__');
|
|
@@ -139,12 +140,29 @@ async function handleToolCallRequest(highLevelServer, server, originalCallToolHa
|
|
|
139
140
|
extra,
|
|
140
141
|
eventType: MCPAnalyticsEventType.mcpMissingCapability,
|
|
141
142
|
explicitContextIntent: context,
|
|
142
|
-
parameterOwnership: getVirtualToolParameterOwnership(data, toolName),
|
|
143
|
+
parameterOwnership: getVirtualToolParameterOwnership(data, toolName, getReportMissingToolDescriptor(toolName).inputSchema),
|
|
143
144
|
execute: async ()=>handleReportMissing({
|
|
144
145
|
context
|
|
145
146
|
}, data.logger)
|
|
146
147
|
});
|
|
147
148
|
}
|
|
149
|
+
const feedbackOptions = resolveCollectFeedbackOptions(data.options.collectFeedback);
|
|
150
|
+
const isFeedbackCandidate = void 0 !== feedbackOptions && toolName === (feedbackOptions.toolName ?? SEND_FEEDBACK_TOOL_NAME);
|
|
151
|
+
if (isFeedbackCandidate && await isToolAdvertised(server, toolName, extra, data.logger) === false) {
|
|
152
|
+
const report = parseFeedbackReport(request.params?.arguments, feedbackOptions);
|
|
153
|
+
return await captureToolCall({
|
|
154
|
+
server,
|
|
155
|
+
data,
|
|
156
|
+
request,
|
|
157
|
+
extra,
|
|
158
|
+
eventType: MCPAnalyticsEventType.mcpFeedback,
|
|
159
|
+
explicitContextIntent: buildFeedbackIntent(report),
|
|
160
|
+
omitCapturedParameters: true,
|
|
161
|
+
extraEventProperties: buildFeedbackEventProperties(report),
|
|
162
|
+
parameterOwnership: getVirtualToolParameterOwnership(data, toolName, getFeedbackToolDescriptor(feedbackOptions).inputSchema),
|
|
163
|
+
execute: async ()=>handleFeedback(report, feedbackOptions, data.logger)
|
|
164
|
+
});
|
|
165
|
+
}
|
|
148
166
|
const registeredTool = toolName ? highLevelServer._registeredTools[toolName] : void 0;
|
|
149
167
|
return await captureToolCall({
|
|
150
168
|
server,
|
|
@@ -167,7 +185,10 @@ function instrumentHighLevelServer(server, logger) {
|
|
|
167
185
|
const handlers = {
|
|
168
186
|
initialize: (trackedServer, originalHandler, request, extra)=>handleInitializeRequest(trackedServer, originalHandler, request, extra, logger),
|
|
169
187
|
'tools/list': (trackedServer, originalHandler, request, extra)=>handleListToolsRequest(trackedServer, originalHandler, request, extra, logger),
|
|
170
|
-
'tools/call': (trackedServer, originalHandler, request, extra)=>handleToolCallRequest(server, trackedServer, originalHandler, request, extra, logger)
|
|
188
|
+
'tools/call': (trackedServer, originalHandler, request, extra)=>handleToolCallRequest(server, trackedServer, originalHandler, request, extra, logger),
|
|
189
|
+
'resources/list': traceResourceRequest(MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
190
|
+
'resources/templates/list': traceResourceRequest(MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
191
|
+
'resources/read': traceResourceRequest(MCPAnalyticsEventType.mcpResourcesRead, logger)
|
|
171
192
|
};
|
|
172
193
|
patchRequestHandlers(lowLevelServer, handlers);
|
|
173
194
|
server._registeredTools = addTracingToToolRegistry(server._registeredTools, server, logger);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { MCPServerLike } from '../types';
|
|
2
2
|
import type { LoggerFn } from './logger';
|
|
3
3
|
/**
|
|
4
|
-
* Instruments a low-level `Server`: wraps `initialize`, `tools/list`,
|
|
5
|
-
* `tools/call
|
|
6
|
-
*
|
|
4
|
+
* Instruments a low-level `Server`: wraps `initialize`, `tools/list`,
|
|
5
|
+
* `tools/call`, `resources/list`, `resources/templates/list`, and
|
|
6
|
+
* `resources/read`. The tool-call lifecycle is delegated to
|
|
7
|
+
* {@link captureToolCall}, shared with the high-level wrapper.
|
|
7
8
|
*/
|
|
8
9
|
export declare function instrumentLowLevelServer(server: MCPServerLike, logger: LoggerFn): void;
|
|
9
10
|
//# sourceMappingURL=instrument-lowlevel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument-lowlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-lowlevel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiD,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"instrument-lowlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-lowlevel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiD,aAAa,EAAE,MAAM,UAAU,CAAA;AAY5F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAqBxC;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CA8BtF"}
|
|
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
30
30
|
__webpack_require__.d(__webpack_exports__, {
|
|
31
31
|
instrumentLowLevelServer: ()=>instrumentLowLevelServer
|
|
32
32
|
});
|
|
33
|
+
const external_feedback_js_namespaceObject = require("./feedback.js");
|
|
33
34
|
const external_event_types_js_namespaceObject = require("./event-types.js");
|
|
34
35
|
const external_internal_js_namespaceObject = require("./internal.js");
|
|
35
36
|
const external_tools_js_namespaceObject = require("./tools.js");
|
|
@@ -42,7 +43,10 @@ function instrumentLowLevelServer(server, logger) {
|
|
|
42
43
|
const handlers = {
|
|
43
44
|
initialize: (server, originalHandler, request, extra)=>(0, external_instrumentation_js_namespaceObject.handleInitializeRequest)(server, originalHandler, request, extra, logger),
|
|
44
45
|
'tools/list': (server, originalHandler, request, extra)=>(0, external_instrumentation_js_namespaceObject.handleListToolsRequest)(server, originalHandler, request, extra, logger),
|
|
45
|
-
'tools/call': traceToolCall
|
|
46
|
+
'tools/call': traceToolCall,
|
|
47
|
+
'resources/list': (0, external_instrumentation_js_namespaceObject.traceResourceRequest)(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
48
|
+
'resources/templates/list': (0, external_instrumentation_js_namespaceObject.traceResourceRequest)(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
49
|
+
'resources/read': (0, external_instrumentation_js_namespaceObject.traceResourceRequest)(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpResourcesRead, logger)
|
|
46
50
|
};
|
|
47
51
|
(0, external_instrumentation_js_namespaceObject.patchRequestHandlers)(server, handlers);
|
|
48
52
|
if (!hadCallToolHandler) (0, external_instrumentation_js_namespaceObject.registerFallbackRequestHandler)(server, 'tools/call', unknownToolHandler, traceToolCall);
|
|
@@ -71,12 +75,29 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
71
75
|
extra,
|
|
72
76
|
eventType: external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpMissingCapability,
|
|
73
77
|
explicitContextIntent: context,
|
|
74
|
-
parameterOwnership: (0, external_instrumentation_js_namespaceObject.getVirtualToolParameterOwnership)(data, toolName),
|
|
78
|
+
parameterOwnership: (0, external_instrumentation_js_namespaceObject.getVirtualToolParameterOwnership)(data, toolName, (0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(toolName).inputSchema),
|
|
75
79
|
execute: async ()=>(0, external_tools_js_namespaceObject.handleReportMissing)({
|
|
76
80
|
context
|
|
77
81
|
}, data.logger)
|
|
78
82
|
});
|
|
79
83
|
}
|
|
84
|
+
const feedbackOptions = (0, external_feedback_js_namespaceObject.resolveCollectFeedbackOptions)(data.options.collectFeedback);
|
|
85
|
+
const isFeedbackCandidate = void 0 !== feedbackOptions && toolName === (feedbackOptions.toolName ?? external_feedback_js_namespaceObject.SEND_FEEDBACK_TOOL_NAME);
|
|
86
|
+
if (isFeedbackCandidate && await (0, external_instrumentation_js_namespaceObject.isToolAdvertised)(server, toolName, extra, data.logger) === false) {
|
|
87
|
+
const report = (0, external_feedback_js_namespaceObject.parseFeedbackReport)(request.params?.arguments, feedbackOptions);
|
|
88
|
+
return await (0, external_instrumentation_js_namespaceObject.captureToolCall)({
|
|
89
|
+
server,
|
|
90
|
+
data,
|
|
91
|
+
request,
|
|
92
|
+
extra,
|
|
93
|
+
eventType: external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpFeedback,
|
|
94
|
+
explicitContextIntent: (0, external_feedback_js_namespaceObject.buildFeedbackIntent)(report),
|
|
95
|
+
omitCapturedParameters: true,
|
|
96
|
+
extraEventProperties: (0, external_feedback_js_namespaceObject.buildFeedbackEventProperties)(report),
|
|
97
|
+
parameterOwnership: (0, external_instrumentation_js_namespaceObject.getVirtualToolParameterOwnership)(data, toolName, (0, external_feedback_js_namespaceObject.getFeedbackToolDescriptor)(feedbackOptions).inputSchema),
|
|
98
|
+
execute: async ()=>(0, external_feedback_js_namespaceObject.handleFeedback)(report, feedbackOptions, data.logger)
|
|
99
|
+
});
|
|
100
|
+
}
|
|
80
101
|
return await (0, external_instrumentation_js_namespaceObject.captureToolCall)({
|
|
81
102
|
server,
|
|
82
103
|
data,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { SEND_FEEDBACK_TOOL_NAME, buildFeedbackEventProperties, buildFeedbackIntent, getFeedbackToolDescriptor, handleFeedback, parseFeedbackReport, resolveCollectFeedbackOptions } from "./feedback.mjs";
|
|
1
2
|
import { MCPAnalyticsEventType } from "./event-types.mjs";
|
|
2
3
|
import { getServerTrackingData } from "./internal.mjs";
|
|
3
|
-
import { handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
4
|
-
import { captureToolCall, getVirtualToolParameterOwnership, handleInitializeRequest, handleListToolsRequest, isToolAdvertised, patchRequestHandlers, registerFallbackRequestHandler } from "./instrumentation.mjs";
|
|
4
|
+
import { getReportMissingToolDescriptor, handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
5
|
+
import { captureToolCall, getVirtualToolParameterOwnership, handleInitializeRequest, handleListToolsRequest, isToolAdvertised, patchRequestHandlers, registerFallbackRequestHandler, traceResourceRequest } from "./instrumentation.mjs";
|
|
5
6
|
import { getContextArgument } from "./tracing-helpers.mjs";
|
|
6
7
|
function instrumentLowLevelServer(server, logger) {
|
|
7
8
|
try {
|
|
@@ -10,7 +11,10 @@ function instrumentLowLevelServer(server, logger) {
|
|
|
10
11
|
const handlers = {
|
|
11
12
|
initialize: (server, originalHandler, request, extra)=>handleInitializeRequest(server, originalHandler, request, extra, logger),
|
|
12
13
|
'tools/list': (server, originalHandler, request, extra)=>handleListToolsRequest(server, originalHandler, request, extra, logger),
|
|
13
|
-
'tools/call': traceToolCall
|
|
14
|
+
'tools/call': traceToolCall,
|
|
15
|
+
'resources/list': traceResourceRequest(MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
16
|
+
'resources/templates/list': traceResourceRequest(MCPAnalyticsEventType.mcpResourcesList, logger),
|
|
17
|
+
'resources/read': traceResourceRequest(MCPAnalyticsEventType.mcpResourcesRead, logger)
|
|
14
18
|
};
|
|
15
19
|
patchRequestHandlers(server, handlers);
|
|
16
20
|
if (!hadCallToolHandler) registerFallbackRequestHandler(server, 'tools/call', unknownToolHandler, traceToolCall);
|
|
@@ -39,12 +43,29 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
39
43
|
extra,
|
|
40
44
|
eventType: MCPAnalyticsEventType.mcpMissingCapability,
|
|
41
45
|
explicitContextIntent: context,
|
|
42
|
-
parameterOwnership: getVirtualToolParameterOwnership(data, toolName),
|
|
46
|
+
parameterOwnership: getVirtualToolParameterOwnership(data, toolName, getReportMissingToolDescriptor(toolName).inputSchema),
|
|
43
47
|
execute: async ()=>handleReportMissing({
|
|
44
48
|
context
|
|
45
49
|
}, data.logger)
|
|
46
50
|
});
|
|
47
51
|
}
|
|
52
|
+
const feedbackOptions = resolveCollectFeedbackOptions(data.options.collectFeedback);
|
|
53
|
+
const isFeedbackCandidate = void 0 !== feedbackOptions && toolName === (feedbackOptions.toolName ?? SEND_FEEDBACK_TOOL_NAME);
|
|
54
|
+
if (isFeedbackCandidate && await isToolAdvertised(server, toolName, extra, data.logger) === false) {
|
|
55
|
+
const report = parseFeedbackReport(request.params?.arguments, feedbackOptions);
|
|
56
|
+
return await captureToolCall({
|
|
57
|
+
server,
|
|
58
|
+
data,
|
|
59
|
+
request,
|
|
60
|
+
extra,
|
|
61
|
+
eventType: MCPAnalyticsEventType.mcpFeedback,
|
|
62
|
+
explicitContextIntent: buildFeedbackIntent(report),
|
|
63
|
+
omitCapturedParameters: true,
|
|
64
|
+
extraEventProperties: buildFeedbackEventProperties(report),
|
|
65
|
+
parameterOwnership: getVirtualToolParameterOwnership(data, toolName, getFeedbackToolDescriptor(feedbackOptions).inputSchema),
|
|
66
|
+
execute: async ()=>handleFeedback(report, feedbackOptions, data.logger)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
48
69
|
return await captureToolCall({
|
|
49
70
|
server,
|
|
50
71
|
data,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnalyticsParameterOwnership, CompatibleRequestHandlerExtra, CompatibleToolsListLike, MCPAnalyticsData, MCPRequestLike, MCPServerLike } from '../types';
|
|
1
|
+
import type { AnalyticsParameterOwnership, CompatibleRequestHandlerExtra, CompatibleToolsListLike, JsonRecord, MCPAnalyticsData, MCPRequestLike, MCPServerLike } from '../types';
|
|
2
2
|
import { MCPAnalyticsEventType } from './event-types';
|
|
3
3
|
import type { LoggerFn } from './logger';
|
|
4
4
|
/**
|
|
@@ -21,16 +21,29 @@ interface TraceToolCallParams {
|
|
|
21
21
|
parameterOwnership?: AnalyticsParameterOwnership;
|
|
22
22
|
/**
|
|
23
23
|
* Event type to capture. Defaults to a tool call; the `get_more_tools` virtual
|
|
24
|
-
* tool passes `mcpMissingCapability`
|
|
25
|
-
* a
|
|
24
|
+
* tool passes `mcpMissingCapability` and `send_feedback` passes
|
|
25
|
+
* `mcpFeedback`, so they record a capability gap / a feedback report
|
|
26
|
+
* rather than a tool invocation.
|
|
26
27
|
*/
|
|
27
28
|
eventType?: MCPAnalyticsEventType;
|
|
28
29
|
/**
|
|
29
30
|
* When set, used verbatim as the captured intent (source `context_parameter`)
|
|
30
|
-
* instead of running `resolveToolCallIntent`. Used by the
|
|
31
|
-
*
|
|
31
|
+
* instead of running `resolveToolCallIntent`. Used by the virtual tools, which
|
|
32
|
+
* carry their intent in their own arguments.
|
|
32
33
|
*/
|
|
33
34
|
explicitContextIntent?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Extra event properties spread onto the captured event, after the host's
|
|
37
|
+
* `eventProperties`. Used by `send_feedback` for its `$mcp_feedback_*` fields.
|
|
38
|
+
*/
|
|
39
|
+
extraEventProperties?: JsonRecord;
|
|
40
|
+
/**
|
|
41
|
+
* Drop the generically captured `$mcp_parameters` from the event. Used by
|
|
42
|
+
* `send_feedback`: its arguments are agent-narrated free text, so the
|
|
43
|
+
* PII-redacted `$mcp_feedback_*` properties are the captured surface — the
|
|
44
|
+
* raw arguments would bypass that redaction and record undeclared fields.
|
|
45
|
+
*/
|
|
46
|
+
omitCapturedParameters?: boolean;
|
|
34
47
|
/**
|
|
35
48
|
* Optional accessor for an error the executor captured out-of-band. The
|
|
36
49
|
* high-level SDK turns thrown tool errors into `isError: true` results before
|
|
@@ -48,6 +61,9 @@ interface TraceToolCallParams {
|
|
|
48
61
|
* throws, and the tool's own errors are always re-thrown to the caller.
|
|
49
62
|
*/
|
|
50
63
|
export declare function captureToolCall(params: TraceToolCallParams): Promise<unknown>;
|
|
64
|
+
type ResourceEventType = typeof MCPAnalyticsEventType.mcpResourcesList | typeof MCPAnalyticsEventType.mcpResourcesRead;
|
|
65
|
+
/** Builds the handler patch that captures one resource method, for either adapter. */
|
|
66
|
+
export declare function traceResourceRequest(eventType: ResourceEventType, logger: LoggerFn): HandlerPatch;
|
|
51
67
|
/**
|
|
52
68
|
* A method's patch: runs the original handler and captures analytics. `server`
|
|
53
69
|
* and `originalHandler` are bound by {@link patchRequestHandlers}; the SDK
|
|
@@ -85,21 +101,25 @@ export declare function registerFallbackRequestHandler(server: MCPServerLike, ha
|
|
|
85
101
|
*/
|
|
86
102
|
export declare function patchRequestHandlers(server: MCPServerLike, patches: Record<string, HandlerPatch>): void;
|
|
87
103
|
/**
|
|
88
|
-
* Ownership for
|
|
89
|
-
* `tools/list` cache.
|
|
104
|
+
* Ownership for an SDK-owned virtual tool (`get_more_tools`, `send_feedback`),
|
|
105
|
+
* resolved from its own descriptor rather than the `tools/list` cache.
|
|
90
106
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
107
|
+
* A virtual-tool branch is only entered when the application does not advertise
|
|
108
|
+
* a tool by this name, so the descriptor is the SDK's own and what it declares
|
|
109
|
+
* is known statically. An instance that never served a listing — a per-request
|
|
110
|
+
* `McpServer`/`Server`, the topology in ADR-0011 — would otherwise read every
|
|
111
|
+
* injected parameter as not-ours and neither capture nor strip it.
|
|
96
112
|
*
|
|
97
113
|
* `conversation_id` still comes from the cache on purpose: resolving it here too
|
|
98
114
|
* would start minting a handle, and appending its prompt-back block, on
|
|
99
115
|
* instances that today mint none. That changes session anchoring (ADR-0004)
|
|
100
116
|
* rather than closing this gap.
|
|
117
|
+
*
|
|
118
|
+
* `virtualToolInputSchema` is required (not defaulted to one specific virtual
|
|
119
|
+
* tool's descriptor) so every call site names the tool it means; each caller
|
|
120
|
+
* passes its own descriptor's `inputSchema`.
|
|
101
121
|
*/
|
|
102
|
-
export declare function getVirtualToolParameterOwnership(data: MCPAnalyticsData, toolName: string): AnalyticsParameterOwnership;
|
|
122
|
+
export declare function getVirtualToolParameterOwnership(data: MCPAnalyticsData, toolName: string, virtualToolInputSchema: unknown): AnalyticsParameterOwnership;
|
|
103
123
|
/**
|
|
104
124
|
* Checks the server's raw listing for a real owner of a candidate virtual tool.
|
|
105
125
|
* This does not depend on a previous client request and does not call the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC7B,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,aAAa,EAId,MAAM,UAAU,CAAA;AAqBjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAIrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"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"}
|