@posthog/mcp 0.10.9 → 0.11.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/dist/extensions/capture.d.ts.map +1 -1
- package/dist/extensions/capture.js +2 -0
- package/dist/extensions/capture.mjs +2 -0
- package/dist/extensions/compatibility.d.ts.map +1 -1
- package/dist/extensions/constants.d.ts +2 -0
- package/dist/extensions/constants.d.ts.map +1 -1
- package/dist/extensions/constants.js +3 -1
- package/dist/extensions/constants.mjs +3 -1
- package/dist/extensions/context-parameters.d.ts.map +1 -1
- package/dist/extensions/conversation-id.d.ts +2 -13
- package/dist/extensions/conversation-id.d.ts.map +1 -1
- package/dist/extensions/headers.d.ts +33 -0
- package/dist/extensions/headers.d.ts.map +1 -0
- package/dist/extensions/headers.js +54 -0
- package/dist/extensions/headers.mjs +17 -0
- package/dist/extensions/instrument-highlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-lowlevel.d.ts.map +1 -1
- package/dist/extensions/instrumentation.d.ts +7 -0
- package/dist/extensions/instrumentation.d.ts.map +1 -1
- package/dist/extensions/instrumentation.js +4 -0
- package/dist/extensions/instrumentation.mjs +4 -0
- package/dist/extensions/internal.d.ts.map +1 -1
- package/dist/extensions/internal.js +2 -0
- package/dist/extensions/internal.mjs +2 -0
- package/dist/extensions/output-instructions.d.ts +6 -8
- package/dist/extensions/output-instructions.d.ts.map +1 -1
- package/dist/extensions/posthog-events.js +4 -0
- package/dist/extensions/posthog-events.mjs +4 -0
- package/dist/extensions/posthog-mcp.d.ts.map +1 -1
- package/dist/extensions/posthog-mcp.js +3 -0
- package/dist/extensions/posthog-mcp.mjs +3 -0
- package/dist/extensions/session-token.d.ts.map +1 -1
- package/dist/extensions/session-token.js +5 -14
- package/dist/extensions/session-token.mjs +2 -11
- package/dist/extensions/session.d.ts +4 -3
- package/dist/extensions/session.d.ts.map +1 -1
- package/dist/extensions/sink.d.ts +4 -6
- package/dist/extensions/sink.d.ts.map +1 -1
- package/dist/extensions/tools.d.ts.map +1 -1
- package/dist/extensions/transport-identity.d.ts +59 -0
- package/dist/extensions/transport-identity.d.ts.map +1 -0
- package/dist/extensions/transport-identity.js +63 -0
- package/dist/extensions/transport-identity.mjs +20 -0
- package/dist/extensions/truncation.d.ts.map +1 -1
- package/dist/extensions/truncation.js +2 -0
- package/dist/extensions/truncation.mjs +2 -0
- package/dist/types.d.ts +33 -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 +1 -1
- package/src/extensions/capture.ts +6 -0
- package/src/extensions/compatibility.ts +0 -9
- package/src/extensions/constants.ts +2 -0
- package/src/extensions/context-parameters.ts +3 -11
- package/src/extensions/conversation-id.ts +5 -17
- package/src/extensions/headers.ts +52 -0
- package/src/extensions/instrument-highlevel.ts +0 -1
- package/src/extensions/instrument-lowlevel.ts +0 -1
- package/src/extensions/instrumentation.ts +29 -37
- package/src/extensions/internal.ts +6 -5
- package/src/extensions/output-instructions.ts +6 -8
- package/src/extensions/posthog-events.ts +14 -0
- package/src/extensions/posthog-mcp.ts +7 -5
- package/src/extensions/session-token.ts +3 -15
- package/src/extensions/session.ts +21 -35
- package/src/extensions/sink.ts +4 -6
- package/src/extensions/tools.ts +3 -6
- package/src/extensions/transport-identity.ts +94 -0
- package/src/extensions/truncation.ts +4 -0
- package/src/types.ts +33 -0
- package/src/version.ts +1 -1
|
@@ -24,9 +24,8 @@ export declare function processMcpEvent(event: McpEvent, options: McpCaptureOpti
|
|
|
24
24
|
captures: PostHogCaptureEvent[];
|
|
25
25
|
} | null>;
|
|
26
26
|
/**
|
|
27
|
-
* Wraps a user-supplied `posthog-node` client
|
|
28
|
-
*
|
|
29
|
-
* events, applies `beforeSend`, and hands each to `posthog.capture()`.
|
|
27
|
+
* Wraps a user-supplied `posthog-node` client: runs every MCP event through
|
|
28
|
+
* {@link processMcpEvent} and hands each surviving payload to `posthog.capture()`.
|
|
30
29
|
*
|
|
31
30
|
* The SDK does not own the client lifecycle — the host application constructs
|
|
32
31
|
* the `PostHog` instance and is responsible for `shutdown()` (matching
|
|
@@ -37,9 +36,8 @@ export declare class McpEventSink {
|
|
|
37
36
|
private readonly logger;
|
|
38
37
|
constructor(posthog: PostHog, logger?: LoggerFn);
|
|
39
38
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* dropped, never re-thrown into tool code.
|
|
39
|
+
* Errors at any stage are logged and the event is dropped, never re-thrown
|
|
40
|
+
* into tool code.
|
|
43
41
|
*/
|
|
44
42
|
capture(event: McpEvent, options: McpCaptureOptions): Promise<void>;
|
|
45
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/extensions/sink.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC7C,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,EAC1B,MAAM,GAAE,QAAc,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BnE;AA6BD
|
|
1
|
+
{"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/extensions/sink.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAC7C,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,EAC1B,MAAM,GAAE,QAAc,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BnE;AA6BD;;;;;;;GAOG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,OAAO,EAChB,MAAM,GAAE,QAAc;IAGzC;;;OAGG;IACG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAmC1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/extensions/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAC9F,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAE7C,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,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/extensions/tools.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAC9F,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAE7C,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,CA0B9G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CASnD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,MAAM,GAAE,QAAc,GAAG,cAAc,CAGrG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { CompatibleRequestHandlerExtra, McpEvent } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Transport-level client identity: the two request headers that say *which
|
|
4
|
+
* product* is calling, where `clientInfo` only says which client library is.
|
|
5
|
+
*
|
|
6
|
+
* MCP's own identity fields are too coarse to attribute usage to a surface. A
|
|
7
|
+
* vendor ships many products on one client: Anthropic reports
|
|
8
|
+
* `clientInfo.name = "claude-code"` from the CLI, the Agent SDK, the VS Code
|
|
9
|
+
* extension, the desktop app and more, so `$mcp_client_name` collapses all of
|
|
10
|
+
* them into one bucket. The distinguishing detail exists only in the User-Agent
|
|
11
|
+
* parenthetical — `claude-code/2.1.0 (cli)` vs `claude-code/2.1.0 (sdk-ts)` vs
|
|
12
|
+
* `claude-code/2.1.0 (claude-vscode)` — alongside vendor-specific headers like
|
|
13
|
+
* `x-anthropic-client`. Capturing them is the only way a server owner can tell
|
|
14
|
+
* their surfaces apart.
|
|
15
|
+
*
|
|
16
|
+
* We capture the raw strings and classify nothing. No vendor table, no product
|
|
17
|
+
* labels: friendly names are resolved at query time server-side, so labels can
|
|
18
|
+
* improve (and new surfaces can appear) without waiting on an SDK release, and
|
|
19
|
+
* there is exactly one resolver rather than one per installed SDK version.
|
|
20
|
+
*
|
|
21
|
+
* This is deliberately separate from `client-identity.ts`. That module reads the
|
|
22
|
+
* request body's `_meta` and therefore works on every transport, including stdio
|
|
23
|
+
* and in-memory. Headers exist only on HTTP transports, so everything here is a
|
|
24
|
+
* silent no-op elsewhere and those events stay byte-identical to before.
|
|
25
|
+
*/
|
|
26
|
+
/** Header carrying the client's product/surface, e.g. `claude-code/2.1.0 (cli)`. */
|
|
27
|
+
export declare const CLIENT_USER_AGENT_HEADER = "user-agent";
|
|
28
|
+
/**
|
|
29
|
+
* Vendor-specific client header. Anthropic's clients send it alongside the
|
|
30
|
+
* User-Agent; it is captured verbatim as a second, independent signal rather
|
|
31
|
+
* than merged into one, so a query-time resolver can prefer whichever the
|
|
32
|
+
* vendor keeps stable.
|
|
33
|
+
*/
|
|
34
|
+
export declare const VENDOR_CLIENT_HEADER = "x-anthropic-client";
|
|
35
|
+
export interface TransportIdentity {
|
|
36
|
+
clientUserAgent?: string;
|
|
37
|
+
vendorClient?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reads the transport identity headers off `extra.requestInfo.headers`. Returns
|
|
41
|
+
* `undefined` when the request carries neither — including every stdio and
|
|
42
|
+
* in-memory request, which has no `requestInfo` at all. Never throws.
|
|
43
|
+
*/
|
|
44
|
+
export declare function readTransportIdentity(extra: CompatibleRequestHandlerExtra | undefined): TransportIdentity | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Stamps the transport identity onto the event being built for *this* request,
|
|
47
|
+
* so it carries `$mcp_client_user_agent` and `$mcp_vendor_client`.
|
|
48
|
+
*
|
|
49
|
+
* Headers are per-request, so this writes to the event — a per-request object —
|
|
50
|
+
* and never to the server-wide `sessionInfo`. One instrumented server can
|
|
51
|
+
* multiplex concurrent requests from different clients, and caching a header
|
|
52
|
+
* into shared state would attribute one client's surface to another's event.
|
|
53
|
+
* `client-identity.ts` and `capture.ts` guard the same hazard.
|
|
54
|
+
*
|
|
55
|
+
* Values are capped downstream by `truncateEvent`, which runs on every capture
|
|
56
|
+
* path, so a hostile 1MB header cannot inflate an event.
|
|
57
|
+
*/
|
|
58
|
+
export declare function stampTransportIdentity(event: McpEvent, extra: CompatibleRequestHandlerExtra | undefined): void;
|
|
59
|
+
//# sourceMappingURL=transport-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport-identity.d.ts","sourceRoot":"","sources":["../../src/extensions/transport-identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGvE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,eAAe,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAA;AAExD,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,6BAA6B,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAkBrH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,6BAA6B,GAAG,SAAS,GAAG,IAAI,CAW9G"}
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
VENDOR_CLIENT_HEADER: ()=>VENDOR_CLIENT_HEADER,
|
|
28
|
+
stampTransportIdentity: ()=>stampTransportIdentity,
|
|
29
|
+
CLIENT_USER_AGENT_HEADER: ()=>CLIENT_USER_AGENT_HEADER,
|
|
30
|
+
readTransportIdentity: ()=>readTransportIdentity
|
|
31
|
+
});
|
|
32
|
+
const external_headers_js_namespaceObject = require("./headers.js");
|
|
33
|
+
const CLIENT_USER_AGENT_HEADER = 'user-agent';
|
|
34
|
+
const VENDOR_CLIENT_HEADER = 'x-anthropic-client';
|
|
35
|
+
function readTransportIdentity(extra) {
|
|
36
|
+
const headers = extra?.requestInfo?.headers;
|
|
37
|
+
if (!headers) return;
|
|
38
|
+
const result = {};
|
|
39
|
+
const clientUserAgent = (0, external_headers_js_namespaceObject.readHeaderValue)(headers, CLIENT_USER_AGENT_HEADER);
|
|
40
|
+
if (clientUserAgent) result.clientUserAgent = clientUserAgent;
|
|
41
|
+
const vendorClient = (0, external_headers_js_namespaceObject.readHeaderValue)(headers, VENDOR_CLIENT_HEADER);
|
|
42
|
+
if (vendorClient) result.vendorClient = vendorClient;
|
|
43
|
+
return result.clientUserAgent || result.vendorClient ? result : void 0;
|
|
44
|
+
}
|
|
45
|
+
function stampTransportIdentity(event, extra) {
|
|
46
|
+
const identity = readTransportIdentity(extra);
|
|
47
|
+
if (!identity) return;
|
|
48
|
+
if (identity.clientUserAgent) event.clientUserAgent = identity.clientUserAgent;
|
|
49
|
+
if (identity.vendorClient) event.vendorClient = identity.vendorClient;
|
|
50
|
+
}
|
|
51
|
+
exports.CLIENT_USER_AGENT_HEADER = __webpack_exports__.CLIENT_USER_AGENT_HEADER;
|
|
52
|
+
exports.VENDOR_CLIENT_HEADER = __webpack_exports__.VENDOR_CLIENT_HEADER;
|
|
53
|
+
exports.readTransportIdentity = __webpack_exports__.readTransportIdentity;
|
|
54
|
+
exports.stampTransportIdentity = __webpack_exports__.stampTransportIdentity;
|
|
55
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
56
|
+
"CLIENT_USER_AGENT_HEADER",
|
|
57
|
+
"VENDOR_CLIENT_HEADER",
|
|
58
|
+
"readTransportIdentity",
|
|
59
|
+
"stampTransportIdentity"
|
|
60
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
61
|
+
Object.defineProperty(exports, '__esModule', {
|
|
62
|
+
value: true
|
|
63
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readHeaderValue } from "./headers.mjs";
|
|
2
|
+
const CLIENT_USER_AGENT_HEADER = 'user-agent';
|
|
3
|
+
const VENDOR_CLIENT_HEADER = 'x-anthropic-client';
|
|
4
|
+
function readTransportIdentity(extra) {
|
|
5
|
+
const headers = extra?.requestInfo?.headers;
|
|
6
|
+
if (!headers) return;
|
|
7
|
+
const result = {};
|
|
8
|
+
const clientUserAgent = readHeaderValue(headers, CLIENT_USER_AGENT_HEADER);
|
|
9
|
+
if (clientUserAgent) result.clientUserAgent = clientUserAgent;
|
|
10
|
+
const vendorClient = readHeaderValue(headers, VENDOR_CLIENT_HEADER);
|
|
11
|
+
if (vendorClient) result.vendorClient = vendorClient;
|
|
12
|
+
return result.clientUserAgent || result.vendorClient ? result : void 0;
|
|
13
|
+
}
|
|
14
|
+
function stampTransportIdentity(event, extra) {
|
|
15
|
+
const identity = readTransportIdentity(extra);
|
|
16
|
+
if (!identity) return;
|
|
17
|
+
if (identity.clientUserAgent) event.clientUserAgent = identity.clientUserAgent;
|
|
18
|
+
if (identity.vendorClient) event.vendorClient = identity.vendorClient;
|
|
19
|
+
}
|
|
20
|
+
export { CLIENT_USER_AGENT_HEADER, VENDOR_CLIENT_HEADER, readTransportIdentity, stampTransportIdentity };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"truncation.d.ts","sourceRoot":"","sources":["../../src/extensions/truncation.ts"],"names":[],"mappings":"AAKA,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,
|
|
1
|
+
{"version":3,"file":"truncation.d.ts","sourceRoot":"","sources":["../../src/extensions/truncation.ts"],"names":[],"mappings":"AAKA,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,CAwCrE"}
|
|
@@ -250,6 +250,8 @@ function truncateEvent(event) {
|
|
|
250
250
|
result.serverVersion = truncateString(result.serverVersion, MAX_METADATA_LENGTH);
|
|
251
251
|
result.clientName = truncateString(result.clientName, MAX_METADATA_LENGTH);
|
|
252
252
|
result.clientVersion = truncateString(result.clientVersion, MAX_METADATA_LENGTH);
|
|
253
|
+
result.clientUserAgent = truncateString(result.clientUserAgent, MAX_METADATA_LENGTH);
|
|
254
|
+
result.vendorClient = truncateString(result.vendorClient, MAX_METADATA_LENGTH);
|
|
253
255
|
result.errorType = truncateString(result.errorType, MAX_METADATA_LENGTH);
|
|
254
256
|
if (null != result.error && 'object' == typeof result.error) result.error = truncateExceptionList(result.error);
|
|
255
257
|
result.response = truncateResponseContent(result.response);
|
|
@@ -217,6 +217,8 @@ function truncateEvent(event) {
|
|
|
217
217
|
result.serverVersion = truncateString(result.serverVersion, MAX_METADATA_LENGTH);
|
|
218
218
|
result.clientName = truncateString(result.clientName, MAX_METADATA_LENGTH);
|
|
219
219
|
result.clientVersion = truncateString(result.clientVersion, MAX_METADATA_LENGTH);
|
|
220
|
+
result.clientUserAgent = truncateString(result.clientUserAgent, MAX_METADATA_LENGTH);
|
|
221
|
+
result.vendorClient = truncateString(result.vendorClient, MAX_METADATA_LENGTH);
|
|
220
222
|
result.errorType = truncateString(result.errorType, MAX_METADATA_LENGTH);
|
|
221
223
|
if (null != result.error && 'object' == typeof result.error) result.error = truncateExceptionList(result.error);
|
|
222
224
|
result.response = truncateResponseContent(result.response);
|
package/dist/types.d.ts
CHANGED
|
@@ -128,6 +128,15 @@ export type BeforeSendFn = (event: PostHogCaptureEvent) => MaybePromise<PostHogC
|
|
|
128
128
|
export interface Event {
|
|
129
129
|
actorId?: string;
|
|
130
130
|
clientName?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Raw `user-agent` request header → `$mcp_client_user_agent`. HTTP transports
|
|
133
|
+
* only. The only place a client's *surface* is distinguishable: one vendor
|
|
134
|
+
* ships many products under a single `clientName` (Anthropic's CLI, Agent SDK
|
|
135
|
+
* and VS Code extension all report `claude-code`), and only the User-Agent
|
|
136
|
+
* parenthetical tells them apart. Captured verbatim — surfaces are resolved to
|
|
137
|
+
* friendly labels at query time, never in this SDK.
|
|
138
|
+
*/
|
|
139
|
+
clientUserAgent?: string;
|
|
131
140
|
clientVersion?: string;
|
|
132
141
|
conversationId?: string;
|
|
133
142
|
duration?: number;
|
|
@@ -176,6 +185,12 @@ export interface Event {
|
|
|
176
185
|
toolDescription?: string;
|
|
177
186
|
userIntent?: string;
|
|
178
187
|
userIntentSource?: MCPAnalyticsIntentSource;
|
|
188
|
+
/**
|
|
189
|
+
* Raw vendor client header (`x-anthropic-client`) → `$mcp_vendor_client`. HTTP
|
|
190
|
+
* transports only. A second, independent surface signal alongside
|
|
191
|
+
* {@link Event.clientUserAgent}; captured verbatim, never classified.
|
|
192
|
+
*/
|
|
193
|
+
vendorClient?: string;
|
|
179
194
|
}
|
|
180
195
|
/** A partially-built MCP event as it flows through the SDK before capture. */
|
|
181
196
|
export type McpEvent = Partial<Event>;
|
|
@@ -310,6 +325,24 @@ export interface McpCaptureCommon {
|
|
|
310
325
|
* not just the initialize event — the `PostHogMCP` client holds no per-session state.
|
|
311
326
|
*/
|
|
312
327
|
protocolVersion?: string;
|
|
328
|
+
/**
|
|
329
|
+
* Raw `user-agent` request header → `$mcp_client_user_agent`. The
|
|
330
|
+
* `instrument()` path reads this off the transport automatically; a custom
|
|
331
|
+
* dispatcher has no `extra`, so pass `req.headers['user-agent']` yourself.
|
|
332
|
+
*
|
|
333
|
+
* Worth wiring up: it is the only signal that separates a vendor's surfaces
|
|
334
|
+
* (Anthropic's CLI, Agent SDK and VS Code extension all report
|
|
335
|
+
* `clientName: "claude-code"`, and only the User-Agent parenthetical —
|
|
336
|
+
* `(cli)` / `(sdk-ts)` / `(claude-vscode)` — tells them apart). Send it raw;
|
|
337
|
+
* PostHog resolves friendly product labels at query time.
|
|
338
|
+
*/
|
|
339
|
+
clientUserAgent?: string;
|
|
340
|
+
/**
|
|
341
|
+
* Raw vendor client header → `$mcp_vendor_client`. Anthropic's clients send
|
|
342
|
+
* `x-anthropic-client`; pass it as a second, independent surface signal
|
|
343
|
+
* alongside {@link McpCaptureCommon.clientUserAgent}. Sent verbatim.
|
|
344
|
+
*/
|
|
345
|
+
vendorClient?: string;
|
|
313
346
|
/** Person properties → `$set` (e.g. `{ name, email, plan }`). */
|
|
314
347
|
setProperties?: JsonRecord;
|
|
315
348
|
/** Group memberships → `$groups`. */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEhD,+FAA+F;AAC/F,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,eAAe,CAAA;AAC3D,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,CAAA;AAEjD,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,oBAAoB,CAAA;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAA;IACjB,2FAA2F;IAC3F,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;;;;;;;;;;;;;OAcG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,GAAG,0BAA0B,CAAA;IAC9C;;;;;OAKG;IACH,QAAQ,CAAC,EACL,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,6BAA6B,KAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,GAClG,YAAY,GACZ,IAAI,CAAA;IACR;;;OAGG;IACH,cAAc,CAAC,EAAE,CACf,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,KAClC,YAAY,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;IAC5C;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,CAChB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,KAClC,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;CACpD;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAC5C,MAAM,MAAM,wBAAwB,GAAG,mBAAmB,GAAG,UAAU,CAAA;AAEvE,MAAM,MAAM,YAAY,GACpB,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,6BAA6B,KAAK,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,GACnG,CAAC,CAAC,KAAK,EAAE,6BAA6B,KAAK,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAA;AAGxF,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;CACzC,GAAG,CAAC;IAAE,QAAQ,EAAE,YAAY,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAAA;AAE/F;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,YAAY,CAAC,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAE/G,MAAM,WAAW,KAAK;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,qBAAqB,CAAA;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,UAAU,CAAA;IAC9B,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,IAAI,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "0.
|
|
1
|
+
export declare const version = "0.11.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -26,7 +26,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
27
|
version: ()=>version
|
|
28
28
|
});
|
|
29
|
-
const version = '0.
|
|
29
|
+
const version = '0.11.0';
|
|
30
30
|
exports.version = __webpack_exports__.version;
|
|
31
31
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
32
32
|
"version"
|
package/dist/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = '0.
|
|
1
|
+
const version = '0.11.0';
|
|
2
2
|
export { version };
|
package/package.json
CHANGED
|
@@ -60,6 +60,12 @@ export function captureEvent(
|
|
|
60
60
|
// over sessionInfo, so concurrent stateless requests stay isolated.
|
|
61
61
|
clientName: eventInput.clientName ?? sessionInfo.clientName,
|
|
62
62
|
clientVersion: eventInput.clientVersion ?? sessionInfo.clientVersion,
|
|
63
|
+
// Read from this request's headers only — there is deliberately no
|
|
64
|
+
// sessionInfo fallback to coalesce with. Headers ride every HTTP request, so
|
|
65
|
+
// a remembered value would just be a chance to attribute a sibling request's
|
|
66
|
+
// client surface to this event.
|
|
67
|
+
clientUserAgent: eventInput.clientUserAgent,
|
|
68
|
+
vendorClient: eventInput.vendorClient,
|
|
63
69
|
identifyActorGivenId: sessionInfo.identifyActorGivenId,
|
|
64
70
|
identifyActorData: sessionInfo.identifyActorData,
|
|
65
71
|
groups: sessionInfo.identifyActorGroups,
|
|
@@ -21,26 +21,22 @@ type ServerRecord = Record<string, unknown>
|
|
|
21
21
|
* - Server info structure
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
// Function to log compatibility information
|
|
25
24
|
export function logCompatibilityWarning(logger: LoggerFn): void {
|
|
26
25
|
logger(
|
|
27
26
|
'PostHog MCP analytics SDK Compatibility: This version only supports Model Context Protocol TypeScript SDK v1.11 and above. Please upgrade if using an older version.'
|
|
28
27
|
)
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
// Check if server has high-level structure (wrapper with .server property)
|
|
32
30
|
export function isHighLevelServer(server: unknown): server is ServerRecord & { server: ServerRecord } {
|
|
33
31
|
return (
|
|
34
32
|
!!server && typeof server === 'object' && 'server' in server && !!server.server && typeof server.server === 'object'
|
|
35
33
|
)
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
// Check if server has low-level structure (no .server property)
|
|
39
36
|
export function isLowLevelServer(server: unknown): server is ServerRecord {
|
|
40
37
|
return !!server && typeof server === 'object' && !('server' in server)
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
// Type guard function that validates server compatibility and returns typed server
|
|
44
40
|
export function isCompatibleServerType(server: unknown, logger: LoggerFn): MCPServerLike | HighLevelMCPServerLike {
|
|
45
41
|
if (!server || typeof server !== 'object') {
|
|
46
42
|
logCompatibilityWarning(logger)
|
|
@@ -50,7 +46,6 @@ export function isCompatibleServerType(server: unknown, logger: LoggerFn): MCPSe
|
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
if (isHighLevelServer(server)) {
|
|
53
|
-
// Validate high-level server requirements
|
|
54
49
|
if (!server._registeredTools || typeof server._registeredTools !== 'object') {
|
|
55
50
|
logCompatibilityWarning(logger)
|
|
56
51
|
throw new Error(
|
|
@@ -64,18 +59,15 @@ export function isCompatibleServerType(server: unknown, logger: LoggerFn): MCPSe
|
|
|
64
59
|
)
|
|
65
60
|
}
|
|
66
61
|
|
|
67
|
-
// Validate the underlying low-level server
|
|
68
62
|
const targetServer = server.server
|
|
69
63
|
validateLowLevelServer(targetServer, logger)
|
|
70
64
|
|
|
71
65
|
return server as unknown as HighLevelMCPServerLike
|
|
72
66
|
}
|
|
73
|
-
// Direct low-level server validation
|
|
74
67
|
validateLowLevelServer(server, logger)
|
|
75
68
|
return server as MCPServerLike
|
|
76
69
|
}
|
|
77
70
|
|
|
78
|
-
// Helper function to validate low-level server requirements
|
|
79
71
|
function validateLowLevelServer(server: unknown, logger: LoggerFn): void {
|
|
80
72
|
if (!server || typeof server !== 'object') {
|
|
81
73
|
logCompatibilityWarning(logger)
|
|
@@ -100,7 +92,6 @@ function validateLowLevelServer(server: unknown, logger: LoggerFn): void {
|
|
|
100
92
|
)
|
|
101
93
|
}
|
|
102
94
|
|
|
103
|
-
// Validate that _requestHandlers contains functions with compatible signatures
|
|
104
95
|
if (typeof serverRecord._requestHandlers.get !== 'function') {
|
|
105
96
|
logCompatibilityWarning(logger)
|
|
106
97
|
throw new Error(
|
|
@@ -38,6 +38,7 @@ export type PostHogMCPAnalyticsEvent = (typeof PostHogMCPAnalyticsEvent)[keyof t
|
|
|
38
38
|
|
|
39
39
|
export const PostHogMCPAnalyticsProperty = {
|
|
40
40
|
ClientName: '$mcp_client_name',
|
|
41
|
+
ClientUserAgent: '$mcp_client_user_agent',
|
|
41
42
|
ClientVersion: '$mcp_client_version',
|
|
42
43
|
ConversationId: '$mcp_conversation_id',
|
|
43
44
|
DurationMs: '$mcp_duration_ms',
|
|
@@ -58,6 +59,7 @@ export const PostHogMCPAnalyticsProperty = {
|
|
|
58
59
|
ToolCategory: '$mcp_tool_category',
|
|
59
60
|
ToolDescription: '$mcp_tool_description',
|
|
60
61
|
ToolName: '$mcp_tool_name',
|
|
62
|
+
VendorClient: '$mcp_vendor_client',
|
|
61
63
|
} as const
|
|
62
64
|
|
|
63
65
|
export type PostHogMCPAnalyticsProperty = (typeof PostHogMCPAnalyticsProperty)[keyof typeof PostHogMCPAnalyticsProperty]
|
|
@@ -41,7 +41,6 @@ export function addContextParameterToTool<TTool extends ContextInjectableTool>(
|
|
|
41
41
|
contextDescriptionOverride?: string,
|
|
42
42
|
logger: LoggerFn = log
|
|
43
43
|
): TTool {
|
|
44
|
-
// Create a shallow copy of the tool to avoid modifying the original
|
|
45
44
|
const modifiedTool = { ...tool }
|
|
46
45
|
const toolName = tool.name || 'unknown'
|
|
47
46
|
const schema = modifiedTool.inputSchema as AnalyticsInjectableJsonSchema | undefined
|
|
@@ -55,10 +54,6 @@ export function addContextParameterToTool<TTool extends ContextInjectableTool>(
|
|
|
55
54
|
return modifiedTool
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
// Note: If additionalProperties is false, we'll need to remove that constraint
|
|
59
|
-
// when adding context, otherwise the schema would be invalid. We handle this
|
|
60
|
-
// after the deep copy below.
|
|
61
|
-
|
|
62
57
|
if (!modifiedTool.inputSchema) {
|
|
63
58
|
modifiedTool.inputSchema = {
|
|
64
59
|
type: 'object',
|
|
@@ -69,29 +64,26 @@ export function addContextParameterToTool<TTool extends ContextInjectableTool>(
|
|
|
69
64
|
|
|
70
65
|
const contextDescription = contextDescriptionOverride || DEFAULT_CONTEXT_PARAMETER_DESCRIPTION
|
|
71
66
|
|
|
72
|
-
// Deep copy the
|
|
67
|
+
// Deep copy: the server may reuse or freeze the schema object it handed us.
|
|
73
68
|
modifiedTool.inputSchema = JSON.parse(JSON.stringify(modifiedTool.inputSchema)) as AnalyticsInjectableJsonSchema
|
|
74
69
|
|
|
75
70
|
const inputSchema = modifiedTool.inputSchema as AnalyticsInjectableJsonSchema
|
|
76
71
|
|
|
77
|
-
// Ensure properties object exists
|
|
78
72
|
if (!inputSchema.properties) {
|
|
79
73
|
inputSchema.properties = {}
|
|
80
74
|
}
|
|
81
75
|
|
|
82
|
-
//
|
|
83
|
-
//
|
|
76
|
+
// The MCP SDK emits `additionalProperties: false` when converting Zod schemas;
|
|
77
|
+
// left in place it would make the injected `context` key invalid.
|
|
84
78
|
if (inputSchema.additionalProperties === false) {
|
|
85
79
|
inputSchema.additionalProperties = undefined
|
|
86
80
|
}
|
|
87
81
|
|
|
88
|
-
// Add context property
|
|
89
82
|
inputSchema.properties.context = {
|
|
90
83
|
type: 'string',
|
|
91
84
|
description: contextDescription,
|
|
92
85
|
}
|
|
93
86
|
|
|
94
|
-
// Add context to required array
|
|
95
87
|
if (Array.isArray(inputSchema.required)) {
|
|
96
88
|
if (!inputSchema.required.includes('context')) {
|
|
97
89
|
inputSchema.required.push('context')
|
|
@@ -102,20 +102,9 @@ export type ConversationIdResolution =
|
|
|
102
102
|
* derivation is deterministic so that two pods agree — which also means two
|
|
103
103
|
* *callers* sending the same string land in the same session. The strings agents
|
|
104
104
|
* invent are not random (`conv-1`, `1`, `session`), so trusting them verbatim
|
|
105
|
-
* would silently merge unrelated conversations, potentially across users.
|
|
106
|
-
*
|
|
107
|
-
* A compliant agent echoes the uuidv7 we minted and is unaffected. Anything else
|
|
108
|
-
* is treated exactly as if the handle were absent: mint, and prompt back. Shape
|
|
105
|
+
* would silently merge unrelated conversations, potentially across users. Shape
|
|
109
106
|
* rather than a registry of issued ids, because a per-request server has no
|
|
110
|
-
* memory of what it minted.
|
|
111
|
-
*
|
|
112
|
-
* This narrows the problem, it does not prove provenance: a caller supplying a
|
|
113
|
-
* well-formed uuidv7 is trusted, so two that pick the *same* one still merge. That
|
|
114
|
-
* residue is far smaller than the case it replaces — an agent ignoring the
|
|
115
|
-
* parameter description reaches for `conv-1` or `1`, not a conforming uuidv7 — and
|
|
116
|
-
* closing it needs a signed handle, i.e. a secret shared by every pod. Worth doing
|
|
117
|
-
* if this ever anchors something security-bearing; `$session_id` is an analytics
|
|
118
|
-
* grouping key, so it does not today.
|
|
107
|
+
* memory of what it minted. Residual risk and why it's accepted: ADR-0004.
|
|
119
108
|
*/
|
|
120
109
|
export function resolveConversationId(enabled: boolean, args: unknown): ConversationIdResolution {
|
|
121
110
|
if (!enabled) {
|
|
@@ -123,10 +112,9 @@ export function resolveConversationId(enabled: boolean, args: unknown): Conversa
|
|
|
123
112
|
}
|
|
124
113
|
const supplied = extractConversationId(args)
|
|
125
114
|
if (supplied && MINTED_CONVERSATION_ID.test(supplied)) {
|
|
126
|
-
// Lowercased
|
|
127
|
-
// `$session_id` is not
|
|
128
|
-
//
|
|
129
|
-
// land in a different session than the call that minted it.
|
|
115
|
+
// Lowercased: the shape test is case-insensitive but the hash behind
|
|
116
|
+
// `$session_id` is not, so an uppercased echo (some hosts normalise uuids)
|
|
117
|
+
// would land in a different session than the call that minted it.
|
|
130
118
|
return { minted: false, conversationId: supplied.toLowerCase() }
|
|
131
119
|
}
|
|
132
120
|
return { minted: true, conversationId: uuidv7() }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single place this package reads an HTTP request header.
|
|
3
|
+
*
|
|
4
|
+
* The MCP SDK hands us `IsomorphicHeaders` — a plain
|
|
5
|
+
* `Record<string, string | string[] | undefined>`, not a `Headers` instance — so
|
|
6
|
+
* values come out by bracket access rather than `.get()`. MCP SDK v2 plans to
|
|
7
|
+
* pass a real `Headers` object instead; funnelling every read through here keeps
|
|
8
|
+
* that migration a one-function change instead of a hunt for bracket lookups.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reads one header value out of an `IsomorphicHeaders` bag. `name` must be
|
|
13
|
+
* lower-cased: the HTTP transports build the bag with
|
|
14
|
+
* `Object.fromEntries(req.headers.entries())` and the Fetch spec lower-cases
|
|
15
|
+
* header names. A hand-rolled transport can still hand us mixed-case keys, so a
|
|
16
|
+
* case-insensitive scan backs up the direct lookup.
|
|
17
|
+
*
|
|
18
|
+
* Repeated headers arrive as an array — we take the first entry, since every
|
|
19
|
+
* header we read is single-valued by definition. Returns `undefined` for a
|
|
20
|
+
* missing, non-string, or blank value, and never throws: a malformed header from
|
|
21
|
+
* an untrusted client must not break the request it rode in on.
|
|
22
|
+
*/
|
|
23
|
+
export function readHeaderValue(headers: unknown, name: string): string | undefined {
|
|
24
|
+
if (!headers || typeof headers !== 'object') {
|
|
25
|
+
return undefined
|
|
26
|
+
}
|
|
27
|
+
const record = headers as Record<string, unknown>
|
|
28
|
+
let value = record[name]
|
|
29
|
+
if (value === undefined) {
|
|
30
|
+
const key = Object.keys(record).find((k) => k.toLowerCase() === name)
|
|
31
|
+
value = key === undefined ? undefined : record[key]
|
|
32
|
+
}
|
|
33
|
+
return normalizeHeaderString(value)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Coerces one raw header value into a clean string, or `undefined`.
|
|
38
|
+
*
|
|
39
|
+
* Exported so the custom-dispatcher path can apply the same rules to values a host
|
|
40
|
+
* read off the request itself. Without it the two integration paths emit different
|
|
41
|
+
* properties for the *same* request: a whitespace-only header would survive as a junk
|
|
42
|
+
* value, and a repeated header would reach the wire as an array, because the
|
|
43
|
+
* downstream length cap passes non-strings through untouched.
|
|
44
|
+
*/
|
|
45
|
+
export function normalizeHeaderString(value: unknown): string | undefined {
|
|
46
|
+
const first = Array.isArray(value) ? value[0] : value
|
|
47
|
+
if (typeof first !== 'string') {
|
|
48
|
+
return undefined
|
|
49
|
+
}
|
|
50
|
+
const trimmed = first.trim()
|
|
51
|
+
return trimmed.length > 0 ? trimmed : undefined
|
|
52
|
+
}
|
|
@@ -280,7 +280,6 @@ export function instrumentHighLevelServer(server: HighLevelMCPServerLike, logger
|
|
|
280
280
|
const lowLevelServer = server.server
|
|
281
281
|
const mcpAnalyticsData = getServerTrackingData(lowLevelServer)
|
|
282
282
|
|
|
283
|
-
// Patch already existing handlers, and patch setRequestHandler to capture dynamically created handlers.
|
|
284
283
|
const handlers: Record<string, HandlerPatch> = {
|
|
285
284
|
initialize: (trackedServer, originalHandler, request, extra) =>
|
|
286
285
|
handleInitializeRequest(trackedServer, originalHandler, request, extra, logger),
|
|
@@ -32,7 +32,6 @@ type MCPRequestExtra = Parameters<MCPRequestHandler>[1]
|
|
|
32
32
|
*/
|
|
33
33
|
export function instrumentLowLevelServer(server: MCPServerLike, logger: LoggerFn): void {
|
|
34
34
|
try {
|
|
35
|
-
// Patch already existing handlers, and patch setRequestHandler to capture dynamically created handlers.
|
|
36
35
|
const hadCallToolHandler = server._requestHandlers.has('tools/call')
|
|
37
36
|
const traceToolCall: HandlerPatch = (server, originalHandler, request, extra) =>
|
|
38
37
|
handleToolCallRequest(server, originalHandler, request, extra, logger)
|