@posthog/mcp 0.3.0 → 0.4.1
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/conversation-id.d.ts +2 -2
- package/dist/extensions/conversation-id.d.ts.map +1 -1
- package/dist/extensions/conversation-id.js +4 -4
- package/dist/extensions/conversation-id.mjs +4 -4
- package/dist/extensions/instrument-highlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-highlevel.js +4 -3
- package/dist/extensions/instrument-highlevel.mjs +5 -4
- package/dist/extensions/instrument-lowlevel.js +1 -1
- package/dist/extensions/instrument-lowlevel.mjs +2 -2
- package/dist/extensions/instrumentation.d.ts.map +1 -1
- package/dist/extensions/instrumentation.js +5 -4
- package/dist/extensions/instrumentation.mjs +6 -5
- package/dist/extensions/posthog-mcp.d.ts +80 -2
- package/dist/extensions/posthog-mcp.d.ts.map +1 -1
- package/dist/extensions/posthog-mcp.js +57 -3
- package/dist/extensions/posthog-mcp.mjs +57 -3
- package/dist/extensions/sanitization.d.ts +3 -1
- package/dist/extensions/sanitization.d.ts.map +1 -1
- package/dist/extensions/sanitization.js +1 -0
- package/dist/extensions/sanitization.mjs +1 -0
- package/dist/extensions/tools.d.ts +16 -1
- package/dist/extensions/tools.d.ts.map +1 -1
- package/dist/extensions/tools.js +18 -6
- package/dist/extensions/tools.mjs +11 -5
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.mjs +3 -1
- package/dist/types.d.ts +78 -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 +3 -3
- package/src/extensions/conversation-id.ts +8 -4
- package/src/extensions/instrument-highlevel.ts +7 -4
- package/src/extensions/instrument-lowlevel.ts +2 -2
- package/src/extensions/instrumentation.ts +7 -5
- package/src/extensions/posthog-mcp.ts +168 -2
- package/src/extensions/sanitization.ts +10 -1
- package/src/extensions/tools.ts +23 -5
- package/src/index.ts +11 -1
- package/src/types.ts +82 -0
- package/src/version.ts +1 -1
|
@@ -14,7 +14,7 @@ export interface ConversationIdInjectableTool {
|
|
|
14
14
|
[key: string]: unknown;
|
|
15
15
|
}
|
|
16
16
|
export declare function addConversationIdToTool<TTool extends ConversationIdInjectableTool>(tool: TTool): TTool;
|
|
17
|
-
export declare function addConversationIdToTools<TTool extends ConversationIdInjectableTool>(tools: TTool[]): TTool[];
|
|
17
|
+
export declare function addConversationIdToTools<TTool extends ConversationIdInjectableTool>(tools: TTool[], missingCapabilityToolName?: string): TTool[];
|
|
18
18
|
export type ConversationIdResolution = {
|
|
19
19
|
minted: false;
|
|
20
20
|
conversationId: string | undefined;
|
|
@@ -28,7 +28,7 @@ export type ConversationIdResolution = {
|
|
|
28
28
|
* - agent supplied a value → use it
|
|
29
29
|
* - agent omitted → mint a UUID
|
|
30
30
|
*/
|
|
31
|
-
export declare function resolveConversationId(enabled: boolean, args: unknown, toolName: string | undefined): ConversationIdResolution;
|
|
31
|
+
export declare function resolveConversationId(enabled: boolean, args: unknown, toolName: string | undefined, missingCapabilityToolName?: string): ConversationIdResolution;
|
|
32
32
|
/**
|
|
33
33
|
* Predicate matching the same eligibility checks injectConversationIdPromptBack uses,
|
|
34
34
|
* exposed so callers can pre-decide whether the prompt-back will actually land
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-id.d.ts","sourceRoot":"","sources":["../../src/extensions/conversation-id.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D,UAAU,UAAU;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,4BAA4B,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CA2CtG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,4BAA4B,
|
|
1
|
+
{"version":3,"file":"conversation-id.d.ts","sourceRoot":"","sources":["../../src/extensions/conversation-id.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D,UAAU,UAAU;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,UAAU,CAAA;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,4BAA4B,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CA2CtG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,4BAA4B,EACjF,KAAK,EAAE,KAAK,EAAE,EACd,yBAAyB,GAAE,MAA4B,GACtD,KAAK,EAAE,CAOT;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,yBAAyB,GAAE,MAA4B,GACtD,wBAAwB,CAS1B;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAS1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,iCAAiC,CAC/C,QAAQ,SAAS;IAAE,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAAE,EAC3E,OAAO,EAAE,QAAQ,GAAG,QAAQ,CAe7B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAM1D;AAED,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAKA;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAS/F"}
|
|
@@ -69,14 +69,14 @@ function addConversationIdToTool(tool) {
|
|
|
69
69
|
};
|
|
70
70
|
return modifiedTool;
|
|
71
71
|
}
|
|
72
|
-
function addConversationIdToTools(tools) {
|
|
72
|
+
function addConversationIdToTools(tools, missingCapabilityToolName = external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME) {
|
|
73
73
|
return tools.map((tool)=>{
|
|
74
|
-
if (tool.name ===
|
|
74
|
+
if (tool.name === missingCapabilityToolName) return tool;
|
|
75
75
|
return addConversationIdToTool(tool);
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
|
-
function resolveConversationId(enabled, args, toolName) {
|
|
79
|
-
if (!enabled || toolName ===
|
|
78
|
+
function resolveConversationId(enabled, args, toolName, missingCapabilityToolName = external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME) {
|
|
79
|
+
if (!enabled || toolName === missingCapabilityToolName) return {
|
|
80
80
|
minted: false,
|
|
81
81
|
conversationId: void 0
|
|
82
82
|
};
|
|
@@ -32,14 +32,14 @@ function addConversationIdToTool(tool) {
|
|
|
32
32
|
};
|
|
33
33
|
return modifiedTool;
|
|
34
34
|
}
|
|
35
|
-
function addConversationIdToTools(tools) {
|
|
35
|
+
function addConversationIdToTools(tools, missingCapabilityToolName = GET_MORE_TOOLS_NAME) {
|
|
36
36
|
return tools.map((tool)=>{
|
|
37
|
-
if (tool.name ===
|
|
37
|
+
if (tool.name === missingCapabilityToolName) return tool;
|
|
38
38
|
return addConversationIdToTool(tool);
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
function resolveConversationId(enabled, args, toolName) {
|
|
42
|
-
if (!enabled || toolName ===
|
|
41
|
+
function resolveConversationId(enabled, args, toolName, missingCapabilityToolName = GET_MORE_TOOLS_NAME) {
|
|
42
|
+
if (!enabled || toolName === missingCapabilityToolName) return {
|
|
43
43
|
minted: false,
|
|
44
44
|
conversationId: void 0
|
|
45
45
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiC,sBAAsB,EAAiC,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAiC,sBAAsB,EAAiC,MAAM,UAAU,CAAA;AAmRpH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAqB9E"}
|
|
@@ -104,8 +104,9 @@ function setupListenerToRegisteredTools(server) {
|
|
|
104
104
|
(0, external_logger_js_namespaceObject.log)(`Warning: Failed to setup listener for registered tools - ${error}`);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
function addTracingToToolCallbackInternal(tool, toolName,
|
|
107
|
+
function addTracingToToolCallbackInternal(tool, toolName, server) {
|
|
108
108
|
const originalCallback = (0, external_mcp_sdk_compat_js_namespaceObject.getToolFunction)(tool);
|
|
109
|
+
const missingToolName = (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)((0, external_internal_js_namespaceObject.getServerTrackingData)(server.server)?.options);
|
|
109
110
|
if (wrappedCallbacks.has(originalCallback)) {
|
|
110
111
|
(0, external_logger_js_namespaceObject.log)(`Tool ${toolName} callback already wrapped, skipping re-wrap`);
|
|
111
112
|
return tool;
|
|
@@ -131,7 +132,7 @@ function addTracingToToolCallbackInternal(tool, toolName, _server) {
|
|
|
131
132
|
}
|
|
132
133
|
return input;
|
|
133
134
|
};
|
|
134
|
-
const cleanedArgs = toolName ===
|
|
135
|
+
const cleanedArgs = toolName === missingToolName ? args : (0, external_conversation_id_js_namespaceObject.stripConversationId)(removeContextFromArgs(args));
|
|
135
136
|
try {
|
|
136
137
|
if (void 0 === cleanedArgs) {
|
|
137
138
|
const handler = originalCallback;
|
|
@@ -177,7 +178,7 @@ async function handleWrappedToolsCall(originalHandler, server, request, extra) {
|
|
|
177
178
|
(0, external_logger_js_namespaceObject.log)('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
|
|
178
179
|
return await originalHandler(request, extra);
|
|
179
180
|
}
|
|
180
|
-
if (request.params?.name === external_tools_js_namespaceObject.
|
|
181
|
+
if (request.params?.name === (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options)) {
|
|
181
182
|
const context = (0, external_tracing_helpers_js_namespaceObject.getContextArgument)(request) || '';
|
|
182
183
|
return await (0, external_instrumentation_js_namespaceObject.captureToolCall)({
|
|
183
184
|
server,
|
|
@@ -3,7 +3,7 @@ import { MCPAnalyticsEventType } from "./event-types.mjs";
|
|
|
3
3
|
import { getServerTrackingData } from "./internal.mjs";
|
|
4
4
|
import { log } from "./logger.mjs";
|
|
5
5
|
import { createWrappedTool, getLiteralValue, getObjectShape, getToolFunction, hasToolFunction } from "./mcp-sdk-compat.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
7
7
|
import { captureToolCall, instrumentInitializeHandler, instrumentToolsListHandler, readToolMetaCategory } from "./instrumentation.mjs";
|
|
8
8
|
import { getContextArgument } from "./tracing-helpers.mjs";
|
|
9
9
|
const wrappedCallbacks = new WeakMap();
|
|
@@ -76,8 +76,9 @@ function setupListenerToRegisteredTools(server) {
|
|
|
76
76
|
log(`Warning: Failed to setup listener for registered tools - ${error}`);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
function addTracingToToolCallbackInternal(tool, toolName,
|
|
79
|
+
function addTracingToToolCallbackInternal(tool, toolName, server) {
|
|
80
80
|
const originalCallback = getToolFunction(tool);
|
|
81
|
+
const missingToolName = resolveMissingCapabilityToolName(getServerTrackingData(server.server)?.options);
|
|
81
82
|
if (wrappedCallbacks.has(originalCallback)) {
|
|
82
83
|
log(`Tool ${toolName} callback already wrapped, skipping re-wrap`);
|
|
83
84
|
return tool;
|
|
@@ -103,7 +104,7 @@ function addTracingToToolCallbackInternal(tool, toolName, _server) {
|
|
|
103
104
|
}
|
|
104
105
|
return input;
|
|
105
106
|
};
|
|
106
|
-
const cleanedArgs = toolName ===
|
|
107
|
+
const cleanedArgs = toolName === missingToolName ? args : stripConversationId(removeContextFromArgs(args));
|
|
107
108
|
try {
|
|
108
109
|
if (void 0 === cleanedArgs) {
|
|
109
110
|
const handler = originalCallback;
|
|
@@ -149,7 +150,7 @@ async function handleWrappedToolsCall(originalHandler, server, request, extra) {
|
|
|
149
150
|
log('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
|
|
150
151
|
return await originalHandler(request, extra);
|
|
151
152
|
}
|
|
152
|
-
if (request.params?.name ===
|
|
153
|
+
if (request.params?.name === resolveMissingCapabilityToolName(data.options)) {
|
|
153
154
|
const context = getContextArgument(request) || '';
|
|
154
155
|
return await captureToolCall({
|
|
155
156
|
server,
|
|
@@ -50,7 +50,7 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
50
50
|
(0, external_logger_js_namespaceObject.log)('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
|
|
51
51
|
return await originalCallToolHandler?.(request, extra);
|
|
52
52
|
}
|
|
53
|
-
if (request.params?.name === external_tools_js_namespaceObject.
|
|
53
|
+
if (request.params?.name === (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options)) {
|
|
54
54
|
const context = (0, external_tracing_helpers_js_namespaceObject.getContextArgument)(request) || '';
|
|
55
55
|
return await (0, external_instrumentation_js_namespaceObject.captureToolCall)({
|
|
56
56
|
server,
|
|
@@ -2,7 +2,7 @@ import { CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
|
2
2
|
import { MCPAnalyticsEventType } from "./event-types.mjs";
|
|
3
3
|
import { getServerTrackingData } from "./internal.mjs";
|
|
4
4
|
import { log } from "./logger.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { handleReportMissing, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
6
6
|
import { captureToolCall, instrumentInitializeHandler, instrumentToolsListHandler } from "./instrumentation.mjs";
|
|
7
7
|
import { getContextArgument } from "./tracing-helpers.mjs";
|
|
8
8
|
function instrumentLowLevelServer(server) {
|
|
@@ -22,7 +22,7 @@ async function handleToolCallRequest(server, originalCallToolHandler, request, e
|
|
|
22
22
|
log('Warning: PostHog MCP analytics is unable to find server tracking data. Please ensure you have called instrument(server, options) before using tool calls.');
|
|
23
23
|
return await originalCallToolHandler?.(request, extra);
|
|
24
24
|
}
|
|
25
|
-
if (request.params?.name ===
|
|
25
|
+
if (request.params?.name === resolveMissingCapabilityToolName(data.options)) {
|
|
26
26
|
const context = getContextArgument(request) || '';
|
|
27
27
|
return await captureToolCall({
|
|
28
28
|
server,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAY,MAAM,UAAU,CAAA;AAWxH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAoBrD;;;;GAIG;AACH,KAAK,YAAY,GAAG,CAAC,iBAAiB,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE3E,UAAU,mBAAmB;IAC3B,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,gBAAgB,CAAA;IACtB,OAAO,EAAE,cAAc,CAAA;IACvB,KAAK,CAAC,EAAE,6BAA6B,CAAA;IACrC,OAAO,EAAE,YAAY,CAAA;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,CAAA;IACjC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAA;CAClC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAY,MAAM,UAAU,CAAA;AAWxH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAoBrD;;;;GAIG;AACH,KAAK,YAAY,GAAG,CAAC,iBAAiB,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE3E,UAAU,mBAAmB;IAC3B,MAAM,EAAE,aAAa,CAAA;IACrB,IAAI,EAAE,gBAAgB,CAAA;IACtB,OAAO,EAAE,cAAc,CAAA;IACvB,KAAK,CAAC,EAAE,6BAA6B,CAAA;IACrC,OAAO,EAAE,YAAY,CAAA;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,qBAAqB,CAAA;IACjC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAA;CAClC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCnF;AAwHD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAsBtE;AAuGD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CASnH;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CAUjH;AAID;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAiCvE"}
|
|
@@ -46,7 +46,7 @@ const external_tools_js_namespaceObject = require("./tools.js");
|
|
|
46
46
|
const external_tracing_helpers_js_namespaceObject = require("./tracing-helpers.js");
|
|
47
47
|
async function captureToolCall(params) {
|
|
48
48
|
const { server, data, request, extra, execute, eventType, explicitContextIntent, takeCapturedError } = params;
|
|
49
|
-
const conversation = (0, external_conversation_id_js_namespaceObject.resolveConversationId)(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
|
|
49
|
+
const conversation = (0, external_conversation_id_js_namespaceObject.resolveConversationId)(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name, (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options));
|
|
50
50
|
const downstreamRequest = conversation.conversationId ? (0, external_conversation_id_js_namespaceObject.cloneRequestWithoutConversationId)(request) : request;
|
|
51
51
|
const startTime = new Date();
|
|
52
52
|
const event = await prepareToolCallEvent(server, data, request, downstreamRequest, extra, startTime, conversation, eventType ?? external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpToolsCall);
|
|
@@ -180,10 +180,11 @@ async function getTracedToolsList(server, originalListToolsHandler, request, ext
|
|
|
180
180
|
const originalResponse = await originalListToolsHandler(request, extra);
|
|
181
181
|
let tools = originalResponse.tools || [];
|
|
182
182
|
if (data && (0, external_context_parameters_js_namespaceObject.isContextEnabled)(data.options.context)) tools = (0, external_context_parameters_js_namespaceObject.addContextParameterToTools)(tools, (0, external_context_parameters_js_namespaceObject.getContextDescription)(data.options.context));
|
|
183
|
-
if (data?.options.enableConversationId) tools = (0, external_conversation_id_js_namespaceObject.addConversationIdToTools)(tools);
|
|
183
|
+
if (data?.options.enableConversationId) tools = (0, external_conversation_id_js_namespaceObject.addConversationIdToTools)(tools, (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options));
|
|
184
184
|
if (data?.options.reportMissing) {
|
|
185
|
-
const
|
|
186
|
-
|
|
185
|
+
const missingToolName = (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options);
|
|
186
|
+
const alreadyPresent = tools.some((tool)=>tool?.name === missingToolName);
|
|
187
|
+
if (!alreadyPresent) tools.push((0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(missingToolName));
|
|
187
188
|
}
|
|
188
189
|
if (data) {
|
|
189
190
|
cacheToolDescriptions(data.toolDescriptions, tools);
|
|
@@ -9,11 +9,11 @@ import { getServerTrackingData, handleIdentify } from "./internal.mjs";
|
|
|
9
9
|
import { log } from "./logger.mjs";
|
|
10
10
|
import { buildCapturedMcpParameters } from "./mcp-payloads.mjs";
|
|
11
11
|
import { getServerSessionId } from "./session.mjs";
|
|
12
|
-
import {
|
|
12
|
+
import { getReportMissingToolDescriptor, resolveMissingCapabilityToolName } from "./tools.mjs";
|
|
13
13
|
import { applyResolvedMetadata, isToolResultError } from "./tracing-helpers.mjs";
|
|
14
14
|
async function captureToolCall(params) {
|
|
15
15
|
const { server, data, request, extra, execute, eventType, explicitContextIntent, takeCapturedError } = params;
|
|
16
|
-
const conversation = resolveConversationId(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name);
|
|
16
|
+
const conversation = resolveConversationId(data.options.enableConversationId ?? false, request.params?.arguments, request.params?.name, resolveMissingCapabilityToolName(data.options));
|
|
17
17
|
const downstreamRequest = conversation.conversationId ? cloneRequestWithoutConversationId(request) : request;
|
|
18
18
|
const startTime = new Date();
|
|
19
19
|
const event = await prepareToolCallEvent(server, data, request, downstreamRequest, extra, startTime, conversation, eventType ?? MCPAnalyticsEventType.mcpToolsCall);
|
|
@@ -147,10 +147,11 @@ async function getTracedToolsList(server, originalListToolsHandler, request, ext
|
|
|
147
147
|
const originalResponse = await originalListToolsHandler(request, extra);
|
|
148
148
|
let tools = originalResponse.tools || [];
|
|
149
149
|
if (data && isContextEnabled(data.options.context)) tools = addContextParameterToTools(tools, getContextDescription(data.options.context));
|
|
150
|
-
if (data?.options.enableConversationId) tools = addConversationIdToTools(tools);
|
|
150
|
+
if (data?.options.enableConversationId) tools = addConversationIdToTools(tools, resolveMissingCapabilityToolName(data.options));
|
|
151
151
|
if (data?.options.reportMissing) {
|
|
152
|
-
const
|
|
153
|
-
|
|
152
|
+
const missingToolName = resolveMissingCapabilityToolName(data.options);
|
|
153
|
+
const alreadyPresent = tools.some((tool)=>tool?.name === missingToolName);
|
|
154
|
+
if (!alreadyPresent) tools.push(getReportMissingToolDescriptor(missingToolName));
|
|
154
155
|
}
|
|
155
156
|
if (data) {
|
|
156
157
|
cacheToolDescriptions(data.toolDescriptions, tools);
|
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import { PostHog } from 'posthog-node';
|
|
2
|
-
import type { InitializeCaptureData, ToolCallCaptureData } from '../types';
|
|
1
|
+
import { PostHog, type PostHogOptions } from 'posthog-node';
|
|
2
|
+
import type { InitializeCaptureData, MissingCapabilityCaptureData, PreparedToolCall, PrepareToolListOptions, ToolCallCaptureData, ToolsListCaptureData } from '../types';
|
|
3
|
+
import { type ContextInjectableTool } from './context-parameters';
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link PostHogMCP}. A superset of `posthog-node`'s options, plus
|
|
6
|
+
* MCP-specific knobs.
|
|
7
|
+
*/
|
|
8
|
+
export interface PostHogMCPOptions extends PostHogOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Name of the virtual "report a missing capability" tool injected by
|
|
11
|
+
* {@link PostHogMCP.prepareToolList} and detected by
|
|
12
|
+
* {@link PostHogMCP.prepareToolCall}. Set once here so injection and detection
|
|
13
|
+
* can't drift. Defaults to `get_more_tools`.
|
|
14
|
+
*/
|
|
15
|
+
missingCapabilityToolName?: string;
|
|
16
|
+
}
|
|
3
17
|
/**
|
|
4
18
|
* A `posthog-node` client with first-class MCP analytics. Use this when there is
|
|
5
19
|
* no `Server`/`McpServer` to wrap (e.g. a custom HTTP or hono dispatcher): the
|
|
@@ -35,9 +49,73 @@ import type { InitializeCaptureData, ToolCallCaptureData } from '../types';
|
|
|
35
49
|
*/
|
|
36
50
|
export declare class PostHogMCP extends PostHog {
|
|
37
51
|
#private;
|
|
52
|
+
constructor(apiKey: string, options?: PostHogMCPOptions);
|
|
38
53
|
/** Capture a tool invocation. Emits `$mcp_tool_call` (+ an `$exception` sibling on error). */
|
|
39
54
|
captureToolCall(data: ToolCallCaptureData): void;
|
|
40
55
|
/** Capture the connection handshake. Emits `$mcp_initialize`. */
|
|
41
56
|
captureInitialize(data: InitializeCaptureData): void;
|
|
57
|
+
/**
|
|
58
|
+
* Capture a `tools/list` response. Emits `$mcp_tools_list` carrying the
|
|
59
|
+
* advertised tool names (`$mcp_listed_tool_names`), which powers
|
|
60
|
+
* "advertised but never called" analysis. Pass the names you're about to
|
|
61
|
+
* return — typically the result of {@link prepareToolList}.
|
|
62
|
+
*/
|
|
63
|
+
captureToolsList(data: ToolsListCaptureData): void;
|
|
64
|
+
/**
|
|
65
|
+
* Decorate your `tools/list` response with PostHog's analytics affordances:
|
|
66
|
+
* injects the `context` argument into every tool (so agents state their intent,
|
|
67
|
+
* captured as `$mcp_intent`) and, when `reportMissing` is on, appends the
|
|
68
|
+
* `get_more_tools` virtual tool (rename it via the `missingCapabilityToolName`
|
|
69
|
+
* constructor option). Returns a new array; your tools are untouched.
|
|
70
|
+
*
|
|
71
|
+
* The appended `get_more_tools` descriptor carries only the base MCP tool fields
|
|
72
|
+
* (name, description, input schema) — not any framework-specific fields your
|
|
73
|
+
* `TTool` may add (e.g. a `handler`). It is meant to be detected via
|
|
74
|
+
* {@link prepareToolCall}'s `isMissingCapability`, not dispatched through a handler.
|
|
75
|
+
*
|
|
76
|
+
* Call this when there is no `Server` to wrap — it does for a custom dispatcher
|
|
77
|
+
* what `instrument()` does for a `Server`. Pair it with {@link prepareToolCall}
|
|
78
|
+
* on the inbound side.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* // building your tools/list response
|
|
83
|
+
* return { tools: posthog.prepareToolList(myTools, { reportMissing: true }) }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
prepareToolList<TTool extends ContextInjectableTool>(tools: TTool[], options?: PrepareToolListOptions): TTool[];
|
|
87
|
+
/**
|
|
88
|
+
* Read an incoming `tools/call` before you dispatch it: pulls the agent's
|
|
89
|
+
* intent off the injected `context` argument, strips `context` from the
|
|
90
|
+
* arguments (so your handler and its schema validation never see it), and flags
|
|
91
|
+
* whether the call targeted the `get_more_tools` virtual tool.
|
|
92
|
+
*
|
|
93
|
+
* Pass the returned `intent` / `intentSource` to {@link captureToolCall}, and
|
|
94
|
+
* dispatch the returned `args` to your tool.
|
|
95
|
+
*
|
|
96
|
+
* This only extracts the explicit `context` argument (`intentSource:
|
|
97
|
+
* 'context_parameter'`); it does not infer intent. If you run your own
|
|
98
|
+
* inference, pass that string with `intentSource: 'inferred'` straight to
|
|
99
|
+
* {@link captureToolCall} (the `instrument()` path's `intentFallback`
|
|
100
|
+
* equivalent).
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const { intent, intentSource, args, isMissingCapability } = posthog.prepareToolCall(name, rawArgs)
|
|
105
|
+
* if (isMissingCapability) {
|
|
106
|
+
* posthog.captureMissingCapability({ context: intent, ...identity })
|
|
107
|
+
* return getMoreToolsResult()
|
|
108
|
+
* }
|
|
109
|
+
* const result = await runTool(name, args)
|
|
110
|
+
* posthog.captureToolCall({ toolName: name, intent, intentSource, ...identity })
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
prepareToolCall(name: string, args?: Record<string, unknown>): PreparedToolCall;
|
|
114
|
+
/**
|
|
115
|
+
* Capture a `get_more_tools` call as a missing-capability report. Emits
|
|
116
|
+
* `$mcp_missing_capability` with the agent's description as `$mcp_intent`. Reply
|
|
117
|
+
* to the agent with `getMoreToolsResult()`.
|
|
118
|
+
*/
|
|
119
|
+
captureMissingCapability(data: MissingCapabilityCaptureData): void;
|
|
42
120
|
}
|
|
43
121
|
//# sourceMappingURL=posthog-mcp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posthog-mcp.d.ts","sourceRoot":"","sources":["../../src/extensions/posthog-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"posthog-mcp.d.ts","sourceRoot":"","sources":["../../src/extensions/posthog-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAE3D,OAAO,KAAK,EACV,qBAAqB,EAIrB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AACjB,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAA;AAO7B;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,UAAW,SAAQ,OAAO;;gBAWzB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAK3D,8FAA8F;IAC9F,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI;IAgBhD,iEAAiE;IACjE,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAUpD;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAalD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,eAAe,CAAC,KAAK,SAAS,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,GAAE,sBAA2B,GAAG,KAAK,EAAE;IAYnH;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB;IAW/E;;;;OAIG;IACH,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,IAAI;CAkBnE"}
|
|
@@ -27,12 +27,19 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
27
27
|
PostHogMCP: ()=>PostHogMCP
|
|
28
28
|
});
|
|
29
29
|
const external_posthog_node_namespaceObject = require("posthog-node");
|
|
30
|
+
const external_context_parameters_js_namespaceObject = require("./context-parameters.js");
|
|
30
31
|
const external_event_types_js_namespaceObject = require("./event-types.js");
|
|
31
32
|
const external_exceptions_js_namespaceObject = require("./exceptions.js");
|
|
32
33
|
const external_logger_js_namespaceObject = require("./logger.js");
|
|
33
34
|
const external_sink_js_namespaceObject = require("./sink.js");
|
|
35
|
+
const external_tools_js_namespaceObject = require("./tools.js");
|
|
34
36
|
class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
|
|
35
37
|
#sink;
|
|
38
|
+
#missingCapabilityToolName;
|
|
39
|
+
constructor(apiKey, options = {}){
|
|
40
|
+
super(apiKey, options), this.#sink = new external_sink_js_namespaceObject.McpEventSink(this);
|
|
41
|
+
this.#missingCapabilityToolName = options.missingCapabilityToolName ?? external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME;
|
|
42
|
+
}
|
|
36
43
|
captureToolCall(data) {
|
|
37
44
|
const event = baseEvent(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpToolsCall, data);
|
|
38
45
|
event.resourceName = data.toolName;
|
|
@@ -42,6 +49,7 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
|
|
|
42
49
|
event.response = data.response;
|
|
43
50
|
event.duration = data.durationMs;
|
|
44
51
|
event.isError = data.isError;
|
|
52
|
+
applyIntent(event, data.intent, data.intentSource);
|
|
45
53
|
if (data.isError) event.error = (0, external_exceptions_js_namespaceObject.captureException)(data.error ?? `Tool ${data.toolName} returned an error`);
|
|
46
54
|
this.#emit(event);
|
|
47
55
|
}
|
|
@@ -54,14 +62,49 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
|
|
|
54
62
|
event.duration = data.durationMs;
|
|
55
63
|
this.#emit(event);
|
|
56
64
|
}
|
|
65
|
+
captureToolsList(data) {
|
|
66
|
+
const event = baseEvent(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpToolsList, data);
|
|
67
|
+
event.listedToolNames = data.toolNames;
|
|
68
|
+
event.parameters = data.parameters;
|
|
69
|
+
event.response = data.response;
|
|
70
|
+
event.duration = data.durationMs;
|
|
71
|
+
event.isError = data.isError;
|
|
72
|
+
if (data.isError) event.error = (0, external_exceptions_js_namespaceObject.captureException)(data.error ?? 'tools/list failed');
|
|
73
|
+
this.#emit(event);
|
|
74
|
+
}
|
|
75
|
+
prepareToolList(tools, options = {}) {
|
|
76
|
+
const contextOption = options.context ?? true;
|
|
77
|
+
let prepared = (0, external_context_parameters_js_namespaceObject.isContextEnabled)(contextOption) ? (0, external_context_parameters_js_namespaceObject.addContextParameterToTools)(tools, (0, external_context_parameters_js_namespaceObject.getContextDescription)(contextOption)) : [
|
|
78
|
+
...tools
|
|
79
|
+
];
|
|
80
|
+
if (options.reportMissing && !prepared.some((tool)=>tool?.name === this.#missingCapabilityToolName)) prepared = [
|
|
81
|
+
...prepared,
|
|
82
|
+
(0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(this.#missingCapabilityToolName)
|
|
83
|
+
];
|
|
84
|
+
return prepared;
|
|
85
|
+
}
|
|
86
|
+
prepareToolCall(name, args) {
|
|
87
|
+
const rawContext = args?.context;
|
|
88
|
+
const intent = 'string' == typeof rawContext && rawContext.trim() ? rawContext.trim() : void 0;
|
|
89
|
+
return {
|
|
90
|
+
intent,
|
|
91
|
+
intentSource: intent ? 'context_parameter' : void 0,
|
|
92
|
+
args: stripContext(args),
|
|
93
|
+
isMissingCapability: name === this.#missingCapabilityToolName
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
captureMissingCapability(data) {
|
|
97
|
+
const event = baseEvent(external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpMissingCapability, data);
|
|
98
|
+
event.resourceName = this.#missingCapabilityToolName;
|
|
99
|
+
event.parameters = data.parameters;
|
|
100
|
+
applyIntent(event, data.context, 'context_parameter');
|
|
101
|
+
this.#emit(event);
|
|
102
|
+
}
|
|
57
103
|
#emit(event) {
|
|
58
104
|
this.#sink.capture(event, {
|
|
59
105
|
enableExceptionAutocapture: this.options.enableExceptionAutocapture ?? true
|
|
60
106
|
}).catch((error)=>(0, external_logger_js_namespaceObject.log)(`Warning: PostHogMCP failed to capture event - ${error}`));
|
|
61
107
|
}
|
|
62
|
-
constructor(...args){
|
|
63
|
-
super(...args), this.#sink = new external_sink_js_namespaceObject.McpEventSink(this);
|
|
64
|
-
}
|
|
65
108
|
}
|
|
66
109
|
function baseEvent(eventType, common) {
|
|
67
110
|
const event = {
|
|
@@ -75,6 +118,17 @@ function baseEvent(eventType, common) {
|
|
|
75
118
|
if (common.setProperties && Object.keys(common.setProperties).length > 0) event.identifyActorData = common.setProperties;
|
|
76
119
|
return event;
|
|
77
120
|
}
|
|
121
|
+
function applyIntent(event, intent, source) {
|
|
122
|
+
const trimmed = 'string' == typeof intent ? intent.trim() : '';
|
|
123
|
+
if (!trimmed) return;
|
|
124
|
+
event.userIntent = trimmed;
|
|
125
|
+
event.userIntentSource = source ?? 'context_parameter';
|
|
126
|
+
}
|
|
127
|
+
function stripContext(args) {
|
|
128
|
+
if (!args || !('context' in args)) return args;
|
|
129
|
+
const { context: _context, ...rest } = args;
|
|
130
|
+
return rest;
|
|
131
|
+
}
|
|
78
132
|
exports.PostHogMCP = __webpack_exports__.PostHogMCP;
|
|
79
133
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
80
134
|
"PostHogMCP"
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { PostHog } from "posthog-node";
|
|
2
|
+
import { addContextParameterToTools, getContextDescription, isContextEnabled } from "./context-parameters.mjs";
|
|
2
3
|
import { MCPAnalyticsEventType } from "./event-types.mjs";
|
|
3
4
|
import { captureException } from "./exceptions.mjs";
|
|
4
5
|
import { log } from "./logger.mjs";
|
|
5
6
|
import { McpEventSink } from "./sink.mjs";
|
|
7
|
+
import { GET_MORE_TOOLS_NAME, getReportMissingToolDescriptor } from "./tools.mjs";
|
|
6
8
|
class PostHogMCP extends PostHog {
|
|
7
9
|
#sink;
|
|
10
|
+
#missingCapabilityToolName;
|
|
11
|
+
constructor(apiKey, options = {}){
|
|
12
|
+
super(apiKey, options), this.#sink = new McpEventSink(this);
|
|
13
|
+
this.#missingCapabilityToolName = options.missingCapabilityToolName ?? GET_MORE_TOOLS_NAME;
|
|
14
|
+
}
|
|
8
15
|
captureToolCall(data) {
|
|
9
16
|
const event = baseEvent(MCPAnalyticsEventType.mcpToolsCall, data);
|
|
10
17
|
event.resourceName = data.toolName;
|
|
@@ -14,6 +21,7 @@ class PostHogMCP extends PostHog {
|
|
|
14
21
|
event.response = data.response;
|
|
15
22
|
event.duration = data.durationMs;
|
|
16
23
|
event.isError = data.isError;
|
|
24
|
+
applyIntent(event, data.intent, data.intentSource);
|
|
17
25
|
if (data.isError) event.error = captureException(data.error ?? `Tool ${data.toolName} returned an error`);
|
|
18
26
|
this.#emit(event);
|
|
19
27
|
}
|
|
@@ -26,14 +34,49 @@ class PostHogMCP extends PostHog {
|
|
|
26
34
|
event.duration = data.durationMs;
|
|
27
35
|
this.#emit(event);
|
|
28
36
|
}
|
|
37
|
+
captureToolsList(data) {
|
|
38
|
+
const event = baseEvent(MCPAnalyticsEventType.mcpToolsList, data);
|
|
39
|
+
event.listedToolNames = data.toolNames;
|
|
40
|
+
event.parameters = data.parameters;
|
|
41
|
+
event.response = data.response;
|
|
42
|
+
event.duration = data.durationMs;
|
|
43
|
+
event.isError = data.isError;
|
|
44
|
+
if (data.isError) event.error = captureException(data.error ?? 'tools/list failed');
|
|
45
|
+
this.#emit(event);
|
|
46
|
+
}
|
|
47
|
+
prepareToolList(tools, options = {}) {
|
|
48
|
+
const contextOption = options.context ?? true;
|
|
49
|
+
let prepared = isContextEnabled(contextOption) ? addContextParameterToTools(tools, getContextDescription(contextOption)) : [
|
|
50
|
+
...tools
|
|
51
|
+
];
|
|
52
|
+
if (options.reportMissing && !prepared.some((tool)=>tool?.name === this.#missingCapabilityToolName)) prepared = [
|
|
53
|
+
...prepared,
|
|
54
|
+
getReportMissingToolDescriptor(this.#missingCapabilityToolName)
|
|
55
|
+
];
|
|
56
|
+
return prepared;
|
|
57
|
+
}
|
|
58
|
+
prepareToolCall(name, args) {
|
|
59
|
+
const rawContext = args?.context;
|
|
60
|
+
const intent = 'string' == typeof rawContext && rawContext.trim() ? rawContext.trim() : void 0;
|
|
61
|
+
return {
|
|
62
|
+
intent,
|
|
63
|
+
intentSource: intent ? 'context_parameter' : void 0,
|
|
64
|
+
args: stripContext(args),
|
|
65
|
+
isMissingCapability: name === this.#missingCapabilityToolName
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
captureMissingCapability(data) {
|
|
69
|
+
const event = baseEvent(MCPAnalyticsEventType.mcpMissingCapability, data);
|
|
70
|
+
event.resourceName = this.#missingCapabilityToolName;
|
|
71
|
+
event.parameters = data.parameters;
|
|
72
|
+
applyIntent(event, data.context, 'context_parameter');
|
|
73
|
+
this.#emit(event);
|
|
74
|
+
}
|
|
29
75
|
#emit(event) {
|
|
30
76
|
this.#sink.capture(event, {
|
|
31
77
|
enableExceptionAutocapture: this.options.enableExceptionAutocapture ?? true
|
|
32
78
|
}).catch((error)=>log(`Warning: PostHogMCP failed to capture event - ${error}`));
|
|
33
79
|
}
|
|
34
|
-
constructor(...args){
|
|
35
|
-
super(...args), this.#sink = new McpEventSink(this);
|
|
36
|
-
}
|
|
37
80
|
}
|
|
38
81
|
function baseEvent(eventType, common) {
|
|
39
82
|
const event = {
|
|
@@ -47,4 +90,15 @@ function baseEvent(eventType, common) {
|
|
|
47
90
|
if (common.setProperties && Object.keys(common.setProperties).length > 0) event.identifyActorData = common.setProperties;
|
|
48
91
|
return event;
|
|
49
92
|
}
|
|
93
|
+
function applyIntent(event, intent, source) {
|
|
94
|
+
const trimmed = 'string' == typeof intent ? intent.trim() : '';
|
|
95
|
+
if (!trimmed) return;
|
|
96
|
+
event.userIntent = trimmed;
|
|
97
|
+
event.userIntentSource = source ?? 'context_parameter';
|
|
98
|
+
}
|
|
99
|
+
function stripContext(args) {
|
|
100
|
+
if (!args || !('context' in args)) return args;
|
|
101
|
+
const { context: _context, ...rest } = args;
|
|
102
|
+
return rest;
|
|
103
|
+
}
|
|
50
104
|
export { PostHogMCP };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { Event, McpEvent } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Sanitizes an event by redacting non-text content blocks from responses
|
|
4
|
-
* and large base64-encoded strings from parameters
|
|
4
|
+
* and large base64-encoded strings from parameters, and applying the same
|
|
5
|
+
* string redaction (PostHog tokens, base64 blobs, sensitive keys) to the
|
|
6
|
+
* agent-supplied intent.
|
|
5
7
|
*
|
|
6
8
|
* This is a synchronous operation that returns a new object without mutating the original.
|
|
7
9
|
* It should run after customer redaction in the event pipeline.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../../src/extensions/sanitization.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAS/C
|
|
1
|
+
{"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../../src/extensions/sanitization.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAS/C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAmBrE"}
|
|
@@ -36,6 +36,7 @@ function sanitizeEvent(event) {
|
|
|
36
36
|
};
|
|
37
37
|
if (null != result.response) result.response = sanitizeResponse(result.response);
|
|
38
38
|
if (null != result.parameters) result.parameters = sanitizeParameters(result.parameters);
|
|
39
|
+
if (null != result.userIntent) result.userIntent = (0, external_mcp_payloads_js_namespaceObject.sanitizeCapturedValue)(result.userIntent);
|
|
39
40
|
return result;
|
|
40
41
|
}
|
|
41
42
|
function sanitizeResponse(response) {
|
|
@@ -8,6 +8,7 @@ function sanitizeEvent(event) {
|
|
|
8
8
|
};
|
|
9
9
|
if (null != result.response) result.response = sanitizeResponse(result.response);
|
|
10
10
|
if (null != result.parameters) result.parameters = sanitizeParameters(result.parameters);
|
|
11
|
+
if (null != result.userIntent) result.userIntent = sanitizeCapturedValue(result.userIntent);
|
|
11
12
|
return result;
|
|
12
13
|
}
|
|
13
14
|
function sanitizeResponse(response) {
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
import { type CallToolResult, type ListToolsResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
export declare const GET_MORE_TOOLS_NAME: "get_more_tools";
|
|
3
|
+
/**
|
|
4
|
+
* The configured name of the `get_more_tools` virtual tool, falling back to the
|
|
5
|
+
* default. Resolve through here everywhere (inject + detect) so a custom name
|
|
6
|
+
* can't drift between call sites.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveMissingCapabilityToolName(options?: {
|
|
9
|
+
missingCapabilityToolName?: string;
|
|
10
|
+
}): string;
|
|
3
11
|
type ReportMissingToolDescriptor = ListToolsResult['tools'][number];
|
|
4
|
-
export declare function getReportMissingToolDescriptor(): ReportMissingToolDescriptor;
|
|
12
|
+
export declare function getReportMissingToolDescriptor(name?: string): ReportMissingToolDescriptor;
|
|
13
|
+
/**
|
|
14
|
+
* The canned acknowledgement returned to the agent after it calls
|
|
15
|
+
* `get_more_tools`. Reply with this from your dispatcher so the agent knows the
|
|
16
|
+
* report was recorded (custom dispatcher path); the `instrument()` path returns
|
|
17
|
+
* it automatically.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getMoreToolsResult(): CallToolResult;
|
|
5
20
|
export declare function handleReportMissing(args: {
|
|
6
21
|
context: string;
|
|
7
22
|
}): CallToolResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/extensions/tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAG9F,eAAO,MAAM,mBAAmB,EAAG,gBAAyB,CAAA;AAE5D,KAAK,2BAA2B,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,wBAAgB,8BAA8B,IAAI,2BAA2B,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/extensions/tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAG9F,eAAO,MAAM,mBAAmB,EAAG,gBAAyB,CAAA;AAE5D;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,CAAC,EAAE;IAAE,yBAAyB,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEzG;AAED,KAAK,2BAA2B,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,wBAAgB,8BAA8B,CAAC,IAAI,GAAE,MAA4B,GAAG,2BAA2B,CA6B9G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CASnD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAG7E"}
|