@posthog/mcp 0.0.8 → 0.1.16
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 +307 -2
- package/README.md +186 -93
- package/dist/extensions/capture.d.ts +13 -0
- package/dist/extensions/capture.d.ts.map +1 -0
- package/dist/extensions/capture.js +80 -0
- package/dist/extensions/capture.mjs +46 -0
- package/dist/extensions/compatibility.d.ts +23 -0
- package/dist/extensions/compatibility.d.ts.map +1 -0
- package/dist/extensions/compatibility.js +113 -0
- package/dist/extensions/compatibility.mjs +67 -0
- package/dist/extensions/constants.d.ts +39 -0
- package/dist/extensions/constants.d.ts.map +1 -0
- package/dist/extensions/constants.js +86 -0
- package/dist/extensions/constants.mjs +37 -0
- package/dist/extensions/context-parameters.d.ts +31 -0
- package/dist/extensions/context-parameters.d.ts.map +1 -0
- package/dist/extensions/context-parameters.js +93 -0
- package/dist/extensions/context-parameters.mjs +50 -0
- package/dist/extensions/conversation-id.d.ts +52 -0
- package/dist/extensions/conversation-id.d.ts.map +1 -0
- package/dist/extensions/conversation-id.js +164 -0
- package/dist/extensions/conversation-id.mjs +103 -0
- package/dist/extensions/event-types.d.ts +21 -0
- package/dist/extensions/event-types.d.ts.map +1 -0
- package/dist/extensions/event-types.js +47 -0
- package/dist/extensions/event-types.mjs +13 -0
- package/dist/extensions/exceptions.d.ts +13 -0
- package/dist/extensions/exceptions.d.ts.map +1 -0
- package/dist/extensions/exceptions.js +58 -0
- package/dist/extensions/exceptions.mjs +24 -0
- package/dist/extensions/ids.d.ts +13 -0
- package/dist/extensions/ids.d.ts.map +1 -0
- package/dist/extensions/ids.js +55 -0
- package/dist/extensions/ids.mjs +18 -0
- package/dist/extensions/instrument-highlevel.d.ts +3 -0
- package/dist/extensions/instrument-highlevel.d.ts.map +1 -0
- package/dist/extensions/instrument-highlevel.js +229 -0
- package/dist/extensions/instrument-highlevel.mjs +195 -0
- package/dist/extensions/instrument-lowlevel.d.ts +8 -0
- package/dist/extensions/instrument-lowlevel.d.ts.map +1 -0
- package/dist/extensions/instrument-lowlevel.js +85 -0
- package/dist/extensions/instrument-lowlevel.mjs +51 -0
- package/dist/extensions/instrumentation.d.ts +59 -0
- package/dist/extensions/instrumentation.d.ts.map +1 -0
- package/dist/extensions/instrumentation.js +237 -0
- package/dist/extensions/instrumentation.mjs +194 -0
- package/dist/extensions/intent.d.ts +10 -0
- package/dist/extensions/intent.d.ts.map +1 -0
- package/dist/extensions/intent.js +84 -0
- package/dist/extensions/intent.mjs +44 -0
- package/dist/extensions/internal.d.ts +32 -0
- package/dist/extensions/internal.d.ts.map +1 -0
- package/dist/extensions/internal.js +158 -0
- package/dist/extensions/internal.mjs +106 -0
- package/dist/extensions/logger.d.ts +14 -0
- package/dist/extensions/logger.d.ts.map +1 -0
- package/dist/extensions/logger.js +47 -0
- package/dist/extensions/logger.mjs +10 -0
- package/dist/extensions/mcp-payloads.d.ts +5 -0
- package/dist/extensions/mcp-payloads.d.ts.map +1 -0
- package/dist/extensions/mcp-payloads.js +91 -0
- package/dist/extensions/mcp-payloads.mjs +54 -0
- package/dist/extensions/mcp-sdk-compat.d.ts +33 -0
- package/dist/extensions/mcp-sdk-compat.d.ts.map +1 -0
- package/dist/extensions/mcp-sdk-compat.js +112 -0
- package/dist/extensions/mcp-sdk-compat.mjs +60 -0
- package/dist/extensions/posthog-events.d.ts +14 -0
- package/dist/extensions/posthog-events.d.ts.map +1 -0
- package/dist/extensions/posthog-events.js +143 -0
- package/dist/extensions/posthog-events.mjs +109 -0
- package/dist/extensions/sanitization.d.ts +10 -0
- package/dist/extensions/sanitization.d.ts.map +1 -0
- package/dist/extensions/sanitization.js +96 -0
- package/dist/extensions/sanitization.mjs +62 -0
- package/dist/extensions/session.d.ts +20 -0
- package/dist/extensions/session.d.ts.map +1 -0
- package/dist/extensions/session.js +113 -0
- package/dist/extensions/session.mjs +67 -0
- package/dist/extensions/sink.d.ts +44 -0
- package/dist/extensions/sink.d.ts.map +1 -0
- package/dist/extensions/sink.js +102 -0
- package/dist/extensions/sink.mjs +65 -0
- package/dist/extensions/tools.d.ts +9 -0
- package/dist/extensions/tools.d.ts.map +1 -0
- package/dist/extensions/tools.js +79 -0
- package/dist/extensions/tools.mjs +39 -0
- package/dist/extensions/tracing-helpers.d.ts +29 -0
- package/dist/extensions/tracing-helpers.d.ts.map +1 -0
- package/dist/extensions/tracing-helpers.js +59 -0
- package/dist/extensions/tracing-helpers.mjs +16 -0
- package/dist/extensions/truncation.d.ts +25 -0
- package/dist/extensions/truncation.d.ts.map +1 -0
- package/dist/extensions/truncation.js +277 -0
- package/dist/extensions/truncation.mjs +228 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +132 -0
- package/dist/index.mjs +83 -2928
- package/dist/types.d.ts +220 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.mjs +0 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +36 -0
- package/dist/version.mjs +2 -0
- package/package.json +55 -87
- package/src/extensions/capture.ts +68 -0
- package/src/extensions/compatibility.ts +138 -0
- package/src/extensions/constants.ts +48 -0
- package/src/extensions/context-parameters.ts +119 -0
- package/src/extensions/conversation-id.ts +177 -0
- package/src/extensions/event-types.ts +21 -0
- package/src/extensions/exceptions.ts +83 -0
- package/src/extensions/ids.ts +32 -0
- package/src/extensions/instrument-highlevel.ts +297 -0
- package/src/extensions/instrument-lowlevel.ts +83 -0
- package/src/extensions/instrumentation.ts +415 -0
- package/src/extensions/intent.ts +78 -0
- package/src/extensions/internal.ts +193 -0
- package/src/extensions/logger.ts +27 -0
- package/src/extensions/mcp-payloads.ts +98 -0
- package/src/extensions/mcp-sdk-compat.ts +160 -0
- package/src/extensions/posthog-events.ts +212 -0
- package/src/extensions/sanitization.ts +121 -0
- package/src/extensions/session.ts +117 -0
- package/src/extensions/sink.ts +130 -0
- package/src/extensions/tools.ts +50 -0
- package/src/extensions/tracing-helpers.ts +51 -0
- package/src/extensions/truncation.ts +453 -0
- package/src/index.ts +174 -0
- package/src/types.ts +244 -0
- package/src/version.ts +1 -0
- package/dist/index.cjs +0 -2936
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -264
- package/dist/index.d.mts +0 -263
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { version } from "../version.mjs";
|
|
2
|
+
import { INACTIVITY_TIMEOUT_IN_MINUTES } from "./constants.mjs";
|
|
3
|
+
import { deterministicPrefixedId, newPrefixedId } from "./ids.mjs";
|
|
4
|
+
import { getServerTrackingData, setServerTrackingData } from "./internal.mjs";
|
|
5
|
+
function newSessionId() {
|
|
6
|
+
return newPrefixedId('ses');
|
|
7
|
+
}
|
|
8
|
+
function deriveSessionIdFromMCPSession(mcpSessionId) {
|
|
9
|
+
return deterministicPrefixedId('ses', mcpSessionId);
|
|
10
|
+
}
|
|
11
|
+
function getServerSessionId(server, extra) {
|
|
12
|
+
const data = getServerTrackingData(server);
|
|
13
|
+
if (!data) throw new Error('Server tracking data not found');
|
|
14
|
+
const mcpSessionId = extra?.sessionId;
|
|
15
|
+
if (mcpSessionId) {
|
|
16
|
+
data.sessionId = deriveSessionIdFromMCPSession(mcpSessionId);
|
|
17
|
+
data.lastMcpSessionId = mcpSessionId;
|
|
18
|
+
data.sessionSource = 'mcp';
|
|
19
|
+
setServerTrackingData(server, data);
|
|
20
|
+
setLastActivity(server);
|
|
21
|
+
return data.sessionId;
|
|
22
|
+
}
|
|
23
|
+
if ('mcp' === data.sessionSource && data.lastMcpSessionId) {
|
|
24
|
+
setLastActivity(server);
|
|
25
|
+
return data.sessionId;
|
|
26
|
+
}
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
const timeoutMs = 60 * INACTIVITY_TIMEOUT_IN_MINUTES * 1000;
|
|
29
|
+
if (now - data.lastActivity.getTime() > timeoutMs) {
|
|
30
|
+
data.sessionId = newSessionId();
|
|
31
|
+
data.sessionSource = 'generated';
|
|
32
|
+
setServerTrackingData(server, data);
|
|
33
|
+
}
|
|
34
|
+
setLastActivity(server);
|
|
35
|
+
return data.sessionId;
|
|
36
|
+
}
|
|
37
|
+
function setLastActivity(server) {
|
|
38
|
+
const data = getServerTrackingData(server);
|
|
39
|
+
if (!data) throw new Error('Server tracking data not found');
|
|
40
|
+
data.lastActivity = new Date();
|
|
41
|
+
setServerTrackingData(server, data);
|
|
42
|
+
}
|
|
43
|
+
function getSessionInfo(server, data, sessionId) {
|
|
44
|
+
let clientInfo = {
|
|
45
|
+
name: void 0,
|
|
46
|
+
version: void 0
|
|
47
|
+
};
|
|
48
|
+
if (!data?.sessionInfo.clientName) clientInfo = server.getClientVersion();
|
|
49
|
+
const actorInfo = data?.identifiedSessions.get(sessionId ?? data.sessionId);
|
|
50
|
+
const sessionInfo = {
|
|
51
|
+
ipAddress: void 0,
|
|
52
|
+
sdkLanguage: 'TypeScript',
|
|
53
|
+
sdkVersion: version,
|
|
54
|
+
serverName: server._serverInfo?.name,
|
|
55
|
+
serverVersion: server._serverInfo?.version,
|
|
56
|
+
clientName: clientInfo?.name,
|
|
57
|
+
clientVersion: clientInfo?.version,
|
|
58
|
+
identifyActorGivenId: actorInfo?.distinctId,
|
|
59
|
+
identifyActorData: actorInfo?.properties || {},
|
|
60
|
+
identifyActorGroups: actorInfo?.groups
|
|
61
|
+
};
|
|
62
|
+
if (!data) return sessionInfo;
|
|
63
|
+
data.sessionInfo = sessionInfo;
|
|
64
|
+
setServerTrackingData(server, data);
|
|
65
|
+
return data.sessionInfo;
|
|
66
|
+
}
|
|
67
|
+
export { deriveSessionIdFromMCPSession, getServerSessionId, getSessionInfo, newSessionId, setLastActivity };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PostHog } from 'posthog-node';
|
|
2
|
+
import type { BeforeSendFn, Event, McpEvent } from '../types';
|
|
3
|
+
import { type PostHogCaptureEvent } from './posthog-events';
|
|
4
|
+
/** Per-event toggles consulted by the sink when fanning out an event. */
|
|
5
|
+
export interface McpCaptureOptions {
|
|
6
|
+
enableExceptionAutocapture: boolean;
|
|
7
|
+
/** Inspect/modify/drop hook applied to each fanned-out payload before capture. */
|
|
8
|
+
beforeSend?: BeforeSendFn;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Runs an MCP event through the full transform: sanitize → truncate → fan out
|
|
12
|
+
* into the `$mcp_*` / `$exception` capture payloads → `beforeSend`. Returns
|
|
13
|
+
* `null` (and logs) if a transform stage throws, so the event is dropped rather
|
|
14
|
+
* than partially sent. Individual payloads dropped by `beforeSend` are filtered
|
|
15
|
+
* out of the returned `captures`.
|
|
16
|
+
*
|
|
17
|
+
* This is the single source of truth for the pipeline — both {@link McpEventSink}
|
|
18
|
+
* and the test harness call it, so tests assert on exactly the payloads that
|
|
19
|
+
* reach `posthog.capture()`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function processMcpEvent(event: McpEvent, options: McpCaptureOptions): Promise<{
|
|
22
|
+
event: Event;
|
|
23
|
+
captures: PostHogCaptureEvent[];
|
|
24
|
+
} | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Wraps a user-supplied `posthog-node` client. Runs every MCP event through the
|
|
27
|
+
* sanitize → truncate pipeline, fans it out into the `$mcp_*` / `$exception`
|
|
28
|
+
* events, applies `beforeSend`, and hands each to `posthog.capture()`.
|
|
29
|
+
*
|
|
30
|
+
* The SDK does not own the client lifecycle — the host application constructs
|
|
31
|
+
* the `PostHog` instance and is responsible for `shutdown()` (matching
|
|
32
|
+
* `@posthog/ai`).
|
|
33
|
+
*/
|
|
34
|
+
export declare class McpEventSink {
|
|
35
|
+
private readonly posthog;
|
|
36
|
+
constructor(posthog: PostHog);
|
|
37
|
+
/**
|
|
38
|
+
* Push an MCP event through the pipeline (sanitize → truncate → fan out →
|
|
39
|
+
* beforeSend → capture). Errors at any stage are logged and the event is
|
|
40
|
+
* dropped, never re-thrown into tool code.
|
|
41
|
+
*/
|
|
42
|
+
capture(event: McpEvent, options: McpCaptureOptions): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/extensions/sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAE7D,OAAO,EAAE,KAAK,mBAAmB,EAA6B,MAAM,kBAAkB,CAAA;AAKtF,yEAAyE;AACzE,MAAM,WAAW,iBAAiB;IAChC,0BAA0B,EAAE,OAAO,CAAA;IACnC,kFAAkF;IAClF,UAAU,CAAC,EAAE,YAAY,CAAA;CAC1B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BnE;AA4BD;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAE7C;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CA0B1E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
processMcpEvent: ()=>processMcpEvent,
|
|
28
|
+
McpEventSink: ()=>McpEventSink
|
|
29
|
+
});
|
|
30
|
+
const core_namespaceObject = require("@posthog/core");
|
|
31
|
+
const external_logger_js_namespaceObject = require("./logger.js");
|
|
32
|
+
const external_posthog_events_js_namespaceObject = require("./posthog-events.js");
|
|
33
|
+
const external_ids_js_namespaceObject = require("./ids.js");
|
|
34
|
+
const external_sanitization_js_namespaceObject = require("./sanitization.js");
|
|
35
|
+
const external_truncation_js_namespaceObject = require("./truncation.js");
|
|
36
|
+
async function processMcpEvent(event, options) {
|
|
37
|
+
let processed = event;
|
|
38
|
+
try {
|
|
39
|
+
processed = (0, external_sanitization_js_namespaceObject.sanitizeEvent)(processed);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
(0, external_logger_js_namespaceObject.log)(`Failed to sanitize event: ${err}`);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
processed = (0, external_truncation_js_namespaceObject.truncateEvent)(processed);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
(0, external_logger_js_namespaceObject.log)(`Failed to truncate event: ${err}`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
processed.id = processed.id || (0, external_ids_js_namespaceObject.newPrefixedId)('evt');
|
|
51
|
+
const fullEvent = processed;
|
|
52
|
+
const built = (0, external_posthog_events_js_namespaceObject.buildPostHogCaptureEvents)(fullEvent, {
|
|
53
|
+
enableExceptionAutocapture: options.enableExceptionAutocapture
|
|
54
|
+
});
|
|
55
|
+
const captures = await applyBeforeSend(built, options.beforeSend);
|
|
56
|
+
return {
|
|
57
|
+
event: fullEvent,
|
|
58
|
+
captures
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function applyBeforeSend(captures, beforeSend) {
|
|
62
|
+
if (!beforeSend) return captures;
|
|
63
|
+
const kept = [];
|
|
64
|
+
for (const capture of captures)try {
|
|
65
|
+
const result = await beforeSend(capture);
|
|
66
|
+
if (result) kept.push(result);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
(0, external_logger_js_namespaceObject.log)(`beforeSend threw for event ${capture.event}; dropping it: ${err}`);
|
|
69
|
+
}
|
|
70
|
+
return kept;
|
|
71
|
+
}
|
|
72
|
+
class McpEventSink {
|
|
73
|
+
constructor(posthog){
|
|
74
|
+
this.posthog = posthog;
|
|
75
|
+
}
|
|
76
|
+
async capture(event, options) {
|
|
77
|
+
const result = await processMcpEvent(event, options);
|
|
78
|
+
if (!result) return;
|
|
79
|
+
const { event: fullEvent, captures } = result;
|
|
80
|
+
try {
|
|
81
|
+
for (const captureEvent of captures)this.posthog.capture({
|
|
82
|
+
distinctId: captureEvent.distinct_id,
|
|
83
|
+
event: captureEvent.event,
|
|
84
|
+
properties: captureEvent.properties,
|
|
85
|
+
timestamp: new Date(captureEvent.timestamp),
|
|
86
|
+
uuid: (0, core_namespaceObject.uuidv7)()
|
|
87
|
+
});
|
|
88
|
+
(0, external_logger_js_namespaceObject.log)(`Captured PostHog event ${fullEvent.id} | ${fullEvent.eventType} | ${fullEvent.duration} ms | ${fullEvent.identifyActorGivenId || 'anonymous'}`);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
(0, external_logger_js_namespaceObject.log)(`Failed to capture PostHog event ${fullEvent.id}: ${err}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.McpEventSink = __webpack_exports__.McpEventSink;
|
|
95
|
+
exports.processMcpEvent = __webpack_exports__.processMcpEvent;
|
|
96
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
97
|
+
"McpEventSink",
|
|
98
|
+
"processMcpEvent"
|
|
99
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
100
|
+
Object.defineProperty(exports, '__esModule', {
|
|
101
|
+
value: true
|
|
102
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { uuidv7 } from "@posthog/core";
|
|
2
|
+
import { log } from "./logger.mjs";
|
|
3
|
+
import { buildPostHogCaptureEvents } from "./posthog-events.mjs";
|
|
4
|
+
import { newPrefixedId } from "./ids.mjs";
|
|
5
|
+
import { sanitizeEvent } from "./sanitization.mjs";
|
|
6
|
+
import { truncateEvent } from "./truncation.mjs";
|
|
7
|
+
async function processMcpEvent(event, options) {
|
|
8
|
+
let processed = event;
|
|
9
|
+
try {
|
|
10
|
+
processed = sanitizeEvent(processed);
|
|
11
|
+
} catch (err) {
|
|
12
|
+
log(`Failed to sanitize event: ${err}`);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
processed = truncateEvent(processed);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
log(`Failed to truncate event: ${err}`);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
processed.id = processed.id || newPrefixedId('evt');
|
|
22
|
+
const fullEvent = processed;
|
|
23
|
+
const built = buildPostHogCaptureEvents(fullEvent, {
|
|
24
|
+
enableExceptionAutocapture: options.enableExceptionAutocapture
|
|
25
|
+
});
|
|
26
|
+
const captures = await applyBeforeSend(built, options.beforeSend);
|
|
27
|
+
return {
|
|
28
|
+
event: fullEvent,
|
|
29
|
+
captures
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async function applyBeforeSend(captures, beforeSend) {
|
|
33
|
+
if (!beforeSend) return captures;
|
|
34
|
+
const kept = [];
|
|
35
|
+
for (const capture of captures)try {
|
|
36
|
+
const result = await beforeSend(capture);
|
|
37
|
+
if (result) kept.push(result);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
log(`beforeSend threw for event ${capture.event}; dropping it: ${err}`);
|
|
40
|
+
}
|
|
41
|
+
return kept;
|
|
42
|
+
}
|
|
43
|
+
class McpEventSink {
|
|
44
|
+
constructor(posthog){
|
|
45
|
+
this.posthog = posthog;
|
|
46
|
+
}
|
|
47
|
+
async capture(event, options) {
|
|
48
|
+
const result = await processMcpEvent(event, options);
|
|
49
|
+
if (!result) return;
|
|
50
|
+
const { event: fullEvent, captures } = result;
|
|
51
|
+
try {
|
|
52
|
+
for (const captureEvent of captures)this.posthog.capture({
|
|
53
|
+
distinctId: captureEvent.distinct_id,
|
|
54
|
+
event: captureEvent.event,
|
|
55
|
+
properties: captureEvent.properties,
|
|
56
|
+
timestamp: new Date(captureEvent.timestamp),
|
|
57
|
+
uuid: uuidv7()
|
|
58
|
+
});
|
|
59
|
+
log(`Captured PostHog event ${fullEvent.id} | ${fullEvent.eventType} | ${fullEvent.duration} ms | ${fullEvent.identifyActorGivenId || 'anonymous'}`);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
log(`Failed to capture PostHog event ${fullEvent.id}: ${err}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export { McpEventSink, processMcpEvent };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CallToolResult, type ListToolsResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
export declare const GET_MORE_TOOLS_NAME: "get_more_tools";
|
|
3
|
+
type ReportMissingToolDescriptor = ListToolsResult['tools'][number];
|
|
4
|
+
export declare function getReportMissingToolDescriptor(): ReportMissingToolDescriptor;
|
|
5
|
+
export declare function handleReportMissing(args: {
|
|
6
|
+
context: string;
|
|
7
|
+
}): CallToolResult;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/extensions/tools.ts"],"names":[],"mappings":"AAAA,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,CA6B5E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAW7E"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
getReportMissingToolDescriptor: ()=>getReportMissingToolDescriptor,
|
|
28
|
+
GET_MORE_TOOLS_NAME: ()=>GET_MORE_TOOLS_NAME,
|
|
29
|
+
handleReportMissing: ()=>handleReportMissing
|
|
30
|
+
});
|
|
31
|
+
const external_logger_js_namespaceObject = require("./logger.js");
|
|
32
|
+
const GET_MORE_TOOLS_NAME = 'get_more_tools';
|
|
33
|
+
function getReportMissingToolDescriptor() {
|
|
34
|
+
return {
|
|
35
|
+
name: GET_MORE_TOOLS_NAME,
|
|
36
|
+
description: 'Check for additional tools whenever your task might benefit from specialized capabilities - even if existing tools could work as a fallback.',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {
|
|
40
|
+
context: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: "A description of your goal and what kind of tool would help accomplish it."
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
required: [
|
|
46
|
+
'context'
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
annotations: {
|
|
50
|
+
title: 'Get More Tools',
|
|
51
|
+
readOnlyHint: true,
|
|
52
|
+
openWorldHint: true,
|
|
53
|
+
idempotentHint: true,
|
|
54
|
+
destructiveHint: false
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function handleReportMissing(args) {
|
|
59
|
+
(0, external_logger_js_namespaceObject.log)(`Missing tool reported: ${JSON.stringify(args)}`);
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: 'text',
|
|
64
|
+
text: 'Unfortunately, we have shown you the full tool list. We have noted your feedback and will work to improve the tool list in the future.'
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
exports.GET_MORE_TOOLS_NAME = __webpack_exports__.GET_MORE_TOOLS_NAME;
|
|
70
|
+
exports.getReportMissingToolDescriptor = __webpack_exports__.getReportMissingToolDescriptor;
|
|
71
|
+
exports.handleReportMissing = __webpack_exports__.handleReportMissing;
|
|
72
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
73
|
+
"GET_MORE_TOOLS_NAME",
|
|
74
|
+
"getReportMissingToolDescriptor",
|
|
75
|
+
"handleReportMissing"
|
|
76
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
77
|
+
Object.defineProperty(exports, '__esModule', {
|
|
78
|
+
value: true
|
|
79
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { log } from "./logger.mjs";
|
|
2
|
+
const GET_MORE_TOOLS_NAME = 'get_more_tools';
|
|
3
|
+
function getReportMissingToolDescriptor() {
|
|
4
|
+
return {
|
|
5
|
+
name: GET_MORE_TOOLS_NAME,
|
|
6
|
+
description: 'Check for additional tools whenever your task might benefit from specialized capabilities - even if existing tools could work as a fallback.',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
context: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
description: "A description of your goal and what kind of tool would help accomplish it."
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
required: [
|
|
16
|
+
'context'
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
annotations: {
|
|
20
|
+
title: 'Get More Tools',
|
|
21
|
+
readOnlyHint: true,
|
|
22
|
+
openWorldHint: true,
|
|
23
|
+
idempotentHint: true,
|
|
24
|
+
destructiveHint: false
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function handleReportMissing(args) {
|
|
29
|
+
log(`Missing tool reported: ${JSON.stringify(args)}`);
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: 'text',
|
|
34
|
+
text: 'Unfortunately, we have shown you the full tool list. We have noted your feedback and will work to improve the tool list in the future.'
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export { GET_MORE_TOOLS_NAME, getReportMissingToolDescriptor, handleReportMissing };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CompatibleRequestHandlerExtra, MCPAnalyticsData, MCPRequestLike, McpEvent } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Helpers shared by the low-level (`instrument-lowlevel.ts`) and high-level
|
|
4
|
+
* (`instrument-highlevel.ts`) MCP server wrappers. Extracted so both paths stay in sync — any change to
|
|
5
|
+
* "what counts as an error result", "how do we resolve customer event
|
|
6
|
+
* properties", "where do we find the context argument", or "how do we measure
|
|
7
|
+
* duration" needs to land in one place.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* MCP tool results signal errors by setting `isError: true` on the result
|
|
11
|
+
* object rather than throwing. Detect that consistently.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isToolResultError(result: unknown): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the `eventProperties` callback (if configured) and stamps the
|
|
16
|
+
* result onto the event. No-op when the callback is absent or returns nullish.
|
|
17
|
+
*/
|
|
18
|
+
export declare function applyResolvedMetadata(event: McpEvent, data: MCPAnalyticsData, request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Reads the SDK-injected `context` argument off a tool-call request. Returns
|
|
21
|
+
* the trimmed string when present, otherwise `undefined`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getContextArgument(request: MCPRequestLike): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Wall-clock duration of a tracked operation in milliseconds, from `event.timestamp`
|
|
26
|
+
* to now. Returns `0` when timestamp is missing so callers don't have to null-check.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getEventDuration(event: McpEvent): number;
|
|
29
|
+
//# sourceMappingURL=tracing-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing-helpers.d.ts","sourceRoot":"","sources":["../../src/extensions/tracing-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGzG;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAG9E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAExD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
getEventDuration: ()=>getEventDuration,
|
|
28
|
+
isToolResultError: ()=>isToolResultError,
|
|
29
|
+
applyResolvedMetadata: ()=>applyResolvedMetadata,
|
|
30
|
+
getContextArgument: ()=>getContextArgument
|
|
31
|
+
});
|
|
32
|
+
const external_internal_js_namespaceObject = require("./internal.js");
|
|
33
|
+
function isToolResultError(result) {
|
|
34
|
+
return !!result && 'object' == typeof result && 'isError' in result && true === result.isError;
|
|
35
|
+
}
|
|
36
|
+
async function applyResolvedMetadata(event, data, request, extra) {
|
|
37
|
+
const resolvedProperties = await (0, external_internal_js_namespaceObject.resolveEventProperties)(data, request, extra);
|
|
38
|
+
if (resolvedProperties) event.properties = resolvedProperties;
|
|
39
|
+
}
|
|
40
|
+
function getContextArgument(request) {
|
|
41
|
+
const context = request.params?.arguments?.context;
|
|
42
|
+
return 'string' == typeof context ? context : void 0;
|
|
43
|
+
}
|
|
44
|
+
function getEventDuration(event) {
|
|
45
|
+
return event.timestamp ? Date.now() - event.timestamp.getTime() : 0;
|
|
46
|
+
}
|
|
47
|
+
exports.applyResolvedMetadata = __webpack_exports__.applyResolvedMetadata;
|
|
48
|
+
exports.getContextArgument = __webpack_exports__.getContextArgument;
|
|
49
|
+
exports.getEventDuration = __webpack_exports__.getEventDuration;
|
|
50
|
+
exports.isToolResultError = __webpack_exports__.isToolResultError;
|
|
51
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
52
|
+
"applyResolvedMetadata",
|
|
53
|
+
"getContextArgument",
|
|
54
|
+
"getEventDuration",
|
|
55
|
+
"isToolResultError"
|
|
56
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
57
|
+
Object.defineProperty(exports, '__esModule', {
|
|
58
|
+
value: true
|
|
59
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { resolveEventProperties } from "./internal.mjs";
|
|
2
|
+
function isToolResultError(result) {
|
|
3
|
+
return !!result && 'object' == typeof result && 'isError' in result && true === result.isError;
|
|
4
|
+
}
|
|
5
|
+
async function applyResolvedMetadata(event, data, request, extra) {
|
|
6
|
+
const resolvedProperties = await resolveEventProperties(data, request, extra);
|
|
7
|
+
if (resolvedProperties) event.properties = resolvedProperties;
|
|
8
|
+
}
|
|
9
|
+
function getContextArgument(request) {
|
|
10
|
+
const context = request.params?.arguments?.context;
|
|
11
|
+
return 'string' == typeof context ? context : void 0;
|
|
12
|
+
}
|
|
13
|
+
function getEventDuration(event) {
|
|
14
|
+
return event.timestamp ? Date.now() - event.timestamp.getTime() : 0;
|
|
15
|
+
}
|
|
16
|
+
export { applyResolvedMetadata, getContextArgument, getEventDuration, isToolResultError };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Event, McpEvent } from '../types';
|
|
2
|
+
export declare const MAX_DEPTH = 10;
|
|
3
|
+
export declare const MAX_BREADTH = 100;
|
|
4
|
+
export declare const MAX_STRING_LENGTH = 32768;
|
|
5
|
+
export declare const MAX_EVENT_BYTES = 102400;
|
|
6
|
+
/**
|
|
7
|
+
* Recursively normalizes a value, handling:
|
|
8
|
+
* - String truncation (> MAX_STRING_LENGTH)
|
|
9
|
+
* - Non-serializable values (functions, symbols, undefined, BigInt, NaN, Infinity)
|
|
10
|
+
* - Date objects -> ISO string
|
|
11
|
+
* - Circular reference detection
|
|
12
|
+
* - Depth limiting
|
|
13
|
+
* - Breadth limiting
|
|
14
|
+
*/
|
|
15
|
+
export declare function normalize(input: unknown, depth?: number, maxBreadth?: number, maxStringLength?: number): unknown;
|
|
16
|
+
/**
|
|
17
|
+
* Applies layered truncation to an event:
|
|
18
|
+
* 1. Field-level string limits (userIntent, resourceName, metadata fields, error.message)
|
|
19
|
+
* 2. Error frame limiting (first 25 + last 25 if > 50)
|
|
20
|
+
* 3. Response content text limits (32KB per text block)
|
|
21
|
+
* 4. Recursive normalization on user-controlled fields
|
|
22
|
+
* 5. Size-targeted truncation (progressive depth reduction + last-resort string truncation)
|
|
23
|
+
*/
|
|
24
|
+
export declare function truncateEvent<T extends Event | McpEvent>(event: T): T;
|
|
25
|
+
//# sourceMappingURL=truncation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truncation.d.ts","sourceRoot":"","sources":["../../src/extensions/truncation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,KAAK,EAAc,QAAQ,EAAE,MAAM,UAAU,CAAA;AAG5E,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B,eAAO,MAAM,WAAW,MAAM,CAAA;AAC9B,eAAO,MAAM,iBAAiB,QAAS,CAAA;AACvC,eAAO,MAAM,eAAe,SAAU,CAAA;AAgBtC;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,KAAK,GAAE,MAAkB,EACzB,UAAU,GAAE,MAAoB,EAChC,eAAe,GAAE,MAA0B,GAC1C,OAAO,CAGT;AAkXD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAmCrE"}
|