@posthog/mcp 0.13.0 → 0.14.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/README.md +25 -10
- package/dist/extensions/constants.d.ts +1 -1
- package/dist/extensions/constants.d.ts.map +1 -1
- package/dist/extensions/constants.js +1 -1
- package/dist/extensions/constants.mjs +1 -1
- package/dist/extensions/instrumentation.d.ts.map +1 -1
- package/dist/extensions/instrumentation.js +4 -1
- package/dist/extensions/instrumentation.mjs +5 -2
- package/dist/extensions/mcp-payloads.d.ts +10 -0
- package/dist/extensions/mcp-payloads.d.ts.map +1 -1
- package/dist/extensions/mcp-payloads.js +64 -0
- package/dist/extensions/mcp-payloads.mjs +62 -1
- package/dist/extensions/model-parameters.d.ts +20 -13
- package/dist/extensions/model-parameters.d.ts.map +1 -1
- package/dist/extensions/model-parameters.js +26 -2
- package/dist/extensions/model-parameters.mjs +24 -3
- package/dist/extensions/posthog-mcp.d.ts +3 -3
- package/dist/extensions/posthog-mcp.d.ts.map +1 -1
- package/dist/extensions/posthog-mcp.js +8 -9
- package/dist/extensions/posthog-mcp.mjs +9 -10
- package/dist/extensions/sanitization.d.ts.map +1 -1
- package/dist/extensions/sanitization.js +1 -1
- package/dist/extensions/sanitization.mjs +2 -2
- package/dist/types.d.ts +20 -20
- 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/capture.ts +2 -2
- package/src/extensions/constants.ts +1 -1
- package/src/extensions/instrumentation.ts +6 -7
- package/src/extensions/mcp-payloads.ts +129 -0
- package/src/extensions/model-parameters.ts +50 -14
- package/src/extensions/posthog-events.ts +2 -2
- package/src/extensions/posthog-mcp.ts +11 -15
- package/src/extensions/sanitization.ts +8 -5
- package/src/types.ts +20 -20
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -150,19 +150,29 @@ instrument(server, posthog, {
|
|
|
150
150
|
|
|
151
151
|
`intentFallback` is the third option: supply the intent yourself when the agent did not send one.
|
|
152
152
|
|
|
153
|
+
Whatever the agent narrates, the SDK redacts structured personal identifiers — email addresses, phone
|
|
154
|
+
numbers, IPv4/IPv6 addresses, Luhn-valid card numbers, and US SSNs — from `$mcp_intent` before it is
|
|
155
|
+
sent. This is always on and needs no configuration. It is best-effort for those well-defined shapes,
|
|
156
|
+
not for free-form personal data such as names or postal addresses, which a regex cannot catch without
|
|
157
|
+
over-redacting ordinary prose. It also applies only to `$mcp_intent`: structured tool `arguments` and
|
|
158
|
+
results are left as-is, because the same shapes are often legitimate data there. If you need a stronger
|
|
159
|
+
guarantee, `context: false` and the `beforeSend` hook above remain the ways to drop the field entirely.
|
|
160
|
+
|
|
153
161
|
### What `$mcp_llm_model` records, and when it stays empty
|
|
154
162
|
|
|
155
|
-
`captureModel` is **off** by default. Turn it on and the SDK
|
|
156
|
-
|
|
157
|
-
|
|
163
|
+
`captureModel` is **off** by default. Turn it on and the SDK records the best model id visible to the
|
|
164
|
+
server as `$mcp_llm_model`. Recognized client metadata wins with source `client_metadata`. Otherwise,
|
|
165
|
+
the SDK injects a required `llm_model` parameter and records the answer with source `self_reported`.
|
|
166
|
+
|
|
167
|
+
MCP does not standardize or attest model identity. Client metadata and self-report are both
|
|
168
|
+
unverified. Use the value to spot degradation across models, never for billing or access control.
|
|
169
|
+
Missing, blank, and `unknown` values are recorded as nothing.
|
|
158
170
|
|
|
159
|
-
The
|
|
160
|
-
|
|
161
|
-
control. An agent that answers `unknown` is recorded as nothing rather than as a model called
|
|
162
|
-
"unknown".
|
|
171
|
+
The recognized metadata path is Codex's `x-codex-turn-metadata.model` field inside request `_meta`.
|
|
172
|
+
Other clients keep using self-report until they expose a stable model field.
|
|
163
173
|
|
|
164
|
-
Unlike `context`,
|
|
165
|
-
and
|
|
174
|
+
Unlike `context`, the self-report fallback degrades to **silence** rather than to a kept argument.
|
|
175
|
+
Its capture and stripping require the SDK to have confirmed the parameter is its own:
|
|
166
176
|
|
|
167
177
|
- `instrument(server)` on a high-level `McpServer` resolves ownership for your registered tools per
|
|
168
178
|
request from the live tool registry, so those work even on a fresh instance.
|
|
@@ -190,13 +200,18 @@ const posthog = new PostHogMCP(process.env.POSTHOG_PROJECT_TOKEN, { captureModel
|
|
|
190
200
|
|
|
191
201
|
const tools = posthog.prepareToolList(serverTools)
|
|
192
202
|
const originalTool = serverTools.find((tool) => tool.name === toolName)
|
|
193
|
-
const { args, llmModel, llmModelSource } = posthog.prepareToolCall(toolName, rawArgs, {
|
|
203
|
+
const { args, llmModel, llmModelSource } = posthog.prepareToolCall(toolName, rawArgs, {
|
|
204
|
+
originalTool,
|
|
205
|
+
requestMeta: request.params?._meta,
|
|
206
|
+
})
|
|
194
207
|
const result = await dispatch(toolName, args)
|
|
195
208
|
|
|
196
209
|
posthog.captureToolCall({ toolName, llmModel, llmModelSource, isError: false })
|
|
197
210
|
```
|
|
198
211
|
|
|
199
212
|
A persistent single-process dispatcher can omit `originalTool` after it has prepared its tool list.
|
|
213
|
+
Pass `requestMeta` whenever the request supplies `_meta`; this enables recognized client metadata
|
|
214
|
+
without changing the arguments sent to the tool.
|
|
200
215
|
|
|
201
216
|
### If you switched to `instrument(server.server)`
|
|
202
217
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const INACTIVITY_TIMEOUT_IN_MINUTES = 30;
|
|
2
|
-
export declare const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION = "Explain
|
|
2
|
+
export declare const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION = "Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\"";
|
|
3
3
|
export declare const DEFAULT_MODEL_PARAMETER_DESCRIPTION = "The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. \"claude-opus-4-8\", \"gpt-5.2\"). Used for analytics only. If you do not know your model identifier with certainty, pass \"unknown\" \u2014 never guess.";
|
|
4
4
|
export declare const DEFAULT_CONVERSATION_ID_DESCRIPTION = "Echo the conversation_id from the server's previous response. The server provides it on the first call \u2014 never invent one, and do not issue parallel tool calls until you have it.";
|
|
5
5
|
export declare const POSTHOG_MCP_ANALYTICS_SOURCE = "posthog_mcp_analytics";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/extensions/constants.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C,eAAO,MAAM,qCAAqC,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/extensions/constants.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C,eAAO,MAAM,qCAAqC,onBAA4mB,CAAA;AAE9pB,eAAO,MAAM,mCAAmC,gRAAqQ,CAAA;AAErT,eAAO,MAAM,mCAAmC,4LACsI,CAAA;AAEtL,eAAO,MAAM,4BAA4B,0BAA0B,CAAA;AAMnE,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AAItD,eAAO,MAAM,wBAAwB;;;;;;;;;;;;CAY3B,CAAA;AAEV,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAA;AAE/G,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;CA0B9B,CAAA;AAEV,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,OAAO,2BAA2B,CAAC,CAAA"}
|
|
@@ -28,7 +28,7 @@ var __webpack_require__ = {};
|
|
|
28
28
|
var __webpack_exports__ = {};
|
|
29
29
|
__webpack_require__.r(__webpack_exports__);
|
|
30
30
|
const INACTIVITY_TIMEOUT_IN_MINUTES = 30;
|
|
31
|
-
const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION =
|
|
31
|
+
const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION = 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."';
|
|
32
32
|
const DEFAULT_MODEL_PARAMETER_DESCRIPTION = 'The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess.';
|
|
33
33
|
const DEFAULT_CONVERSATION_ID_DESCRIPTION = "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.";
|
|
34
34
|
const POSTHOG_MCP_ANALYTICS_SOURCE = 'posthog_mcp_analytics';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const INACTIVITY_TIMEOUT_IN_MINUTES = 30;
|
|
2
|
-
const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION =
|
|
2
|
+
const DEFAULT_CONTEXT_PARAMETER_DESCRIPTION = 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."';
|
|
3
3
|
const DEFAULT_MODEL_PARAMETER_DESCRIPTION = 'The exact model identifier you (the assistant) are running as, taken from your system prompt or environment (e.g. "claude-opus-4-8", "gpt-5.2"). Used for analytics only. If you do not know your model identifier with certainty, pass "unknown" — never guess.';
|
|
4
4
|
const DEFAULT_CONVERSATION_ID_DESCRIPTION = "Echo the conversation_id from the server's previous response. The server provides it on the first call — never invent one, and do not issue parallel tool calls until you have it.";
|
|
5
5
|
const POSTHOG_MCP_ANALYTICS_SOURCE = 'posthog_mcp_analytics';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC7B,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,aAAa,EAId,MAAM,UAAU,CAAA;AAqBjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAIrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AASxC;;;;;;GAMG;AAEH,KAAK,iBAAiB,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,6BAA6B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE7G,2EAA2E;AAC3E,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,2FAA2F;IAC3F,kBAAkB,CAAC,EAAE,2BAA2B,CAAA;IAChD;;;;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,CA8DnF;
|
|
1
|
+
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -123,7 +123,10 @@ async function prepareToolCallEvent(server, data, request, downstreamRequest, ex
|
|
|
123
123
|
const requestAttribution = (0, external_internal_js_namespaceObject.withIdentity)(sessionInfo, identity);
|
|
124
124
|
await (0, external_tracing_helpers_js_namespaceObject.applyResolvedMetadata)(event, data, request, extra);
|
|
125
125
|
(0, external_intent_js_namespaceObject.setEventIntent)(event, await (0, external_intent_js_namespaceObject.resolveToolCallIntent)(data, request, canCaptureContextIntent, extra));
|
|
126
|
-
if (
|
|
126
|
+
if ((0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(data.options.captureModel)) {
|
|
127
|
+
const resolvedModel = (0, external_model_parameters_js_namespaceObject.resolveModel)(request, ownership.llmModel);
|
|
128
|
+
(0, external_model_parameters_js_namespaceObject.setEventModel)(event, resolvedModel?.model, resolvedModel?.source);
|
|
129
|
+
}
|
|
127
130
|
return {
|
|
128
131
|
event,
|
|
129
132
|
requestAttribution
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAnalyticsParameterOwnership, stripOwnedAnalyticsArguments } from "./analytics-parameters.mjs";
|
|
2
2
|
import { addContextParameterToTools, getContextDescription, isContextEnabled } from "./context-parameters.mjs";
|
|
3
|
-
import { addModelParameterToTools,
|
|
3
|
+
import { addModelParameterToTools, getModelDescription, isCaptureModelEnabled, resolveModel, setEventModel } from "./model-parameters.mjs";
|
|
4
4
|
import { addConversationIdToTools, canInjectConversationIdPromptBack, injectConversationIdPromptBack, resolveConversationId } from "./conversation-id.mjs";
|
|
5
5
|
import { stampClientIdentity } from "./client-identity.mjs";
|
|
6
6
|
import { stampTransportIdentity } from "./transport-identity.mjs";
|
|
@@ -82,7 +82,10 @@ async function prepareToolCallEvent(server, data, request, downstreamRequest, ex
|
|
|
82
82
|
const requestAttribution = withIdentity(sessionInfo, identity);
|
|
83
83
|
await applyResolvedMetadata(event, data, request, extra);
|
|
84
84
|
setEventIntent(event, await resolveToolCallIntent(data, request, canCaptureContextIntent, extra));
|
|
85
|
-
if (
|
|
85
|
+
if (isCaptureModelEnabled(data.options.captureModel)) {
|
|
86
|
+
const resolvedModel = resolveModel(request, ownership.llmModel);
|
|
87
|
+
setEventModel(event, resolvedModel?.model, resolvedModel?.source);
|
|
88
|
+
}
|
|
86
89
|
return {
|
|
87
90
|
event,
|
|
88
91
|
requestAttribution
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
type JsonRecord = Record<string, unknown>;
|
|
2
|
+
/**
|
|
3
|
+
* Redacts structured personal identifiers (emails, IP addresses, credit-card
|
|
4
|
+
* numbers, US SSNs, and phone numbers) from a free-text string. Intended for the
|
|
5
|
+
* agent-narrated `$mcp_intent` value only — not for structured tool parameters or
|
|
6
|
+
* responses, where the same shapes are often legitimate data. Horizontal Unicode
|
|
7
|
+
* spaces are first normalized to an ASCII space so copy-pasted identifiers still
|
|
8
|
+
* match. Returns a new string; leaves the input's identifiers untouched when
|
|
9
|
+
* nothing matches.
|
|
10
|
+
*/
|
|
11
|
+
export declare function redactPii(value: string): string;
|
|
2
12
|
export declare function sanitizeCapturedValue(value: unknown): unknown;
|
|
3
13
|
export declare function buildCapturedMcpParameters(request: unknown): JsonRecord;
|
|
4
14
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-payloads.d.ts","sourceRoot":"","sources":["../../src/extensions/mcp-payloads.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp-payloads.d.ts","sourceRoot":"","sources":["../../src/extensions/mcp-payloads.ts"],"names":[],"mappings":"AAmEA,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAiGzC;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU/C;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0B7D;AA6BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBvE"}
|
|
@@ -38,6 +38,15 @@ const BASE64_DATA_URL_PAYLOAD_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/;
|
|
|
38
38
|
const SIZE_GATE = 10240;
|
|
39
39
|
const POSTHOG_TOKEN_PATTERN = /\bph[a-z]_[A-Za-z0-9_-]{20,}\b/g;
|
|
40
40
|
const SENSITIVE_KEY_PATTERN = /^(authorization|cookie|set-cookie|x-api-key|api[-_]?key|api[-_]?token|access[-_]?token|refresh[-_]?token|token|password|secret|client[-_]?secret|private[-_]?key)$/i;
|
|
41
|
+
const UNICODE_SPACE_PATTERN = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
42
|
+
const EMAIL_PATTERN = /[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,255}\.[A-Za-z]{2,24}/g;
|
|
43
|
+
const IPV4_PATTERN = /\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b/g;
|
|
44
|
+
const IPV6_PATTERN = /\b(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}\b|(?<![\w:])(?:[0-9A-Fa-f]{1,4}:){1,7}:(?![\w:])|(?<![\w:])(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,5}(?![\w])|(?<![\w:])::(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,6})(?![\w])/g;
|
|
45
|
+
const US_SSN_PATTERN = /\b\d{3}[ .-]\d{2}[ .-]\d{4}\b/g;
|
|
46
|
+
const CREDIT_CARD_CANDIDATE_PATTERN = /\b\d(?:[ ./-]?\d){12,}\b/g;
|
|
47
|
+
const DIGIT_GROUP_PATTERN = /\d+/g;
|
|
48
|
+
const PHONE_NANP_PATTERN = /(?<![\w+])(?:\+?1[ ./-]?)?(?:\(\d{3}\)[ ./-]?|\d{3}[ ./-])\d{3}[ ./-]\d{4}(?![\w])/g;
|
|
49
|
+
const PHONE_INTL_PATTERN = /(?<!\w)\+\d{1,3}(?:[ ./()-]{0,2}\d){7,13}(?![\w])/g;
|
|
41
50
|
function isRecord(value) {
|
|
42
51
|
return !!value && 'object' == typeof value && !Array.isArray(value);
|
|
43
52
|
}
|
|
@@ -59,6 +68,58 @@ function sanitizeString(value) {
|
|
|
59
68
|
if (value.length >= SIZE_GATE && (BASE64_PATTERN.test(value) || isBase64DataUrl(value) || BASE64URL_SPECIFIC_CHAR_PATTERN.test(value) && BASE64URL_PATTERN.test(value))) return BINARY_REDACTED_VALUE;
|
|
60
69
|
return value.replace(POSTHOG_TOKEN_PATTERN, REDACTED_VALUE);
|
|
61
70
|
}
|
|
71
|
+
function passesLuhn(digits) {
|
|
72
|
+
let sum = 0;
|
|
73
|
+
let double = false;
|
|
74
|
+
for(let index = digits.length - 1; index >= 0; index--){
|
|
75
|
+
let digit = digits.charCodeAt(index) - 48;
|
|
76
|
+
if (digit < 0 || digit > 9) return false;
|
|
77
|
+
if (double) {
|
|
78
|
+
digit *= 2;
|
|
79
|
+
if (digit > 9) digit -= 9;
|
|
80
|
+
}
|
|
81
|
+
sum += digit;
|
|
82
|
+
double = !double;
|
|
83
|
+
}
|
|
84
|
+
return sum % 10 === 0;
|
|
85
|
+
}
|
|
86
|
+
function redactCardInMatch(match) {
|
|
87
|
+
const groups = [];
|
|
88
|
+
for(let m = DIGIT_GROUP_PATTERN.exec(match); null !== m; m = DIGIT_GROUP_PATTERN.exec(match))groups.push({
|
|
89
|
+
digits: m[0],
|
|
90
|
+
start: m.index,
|
|
91
|
+
end: m.index + m[0].length
|
|
92
|
+
});
|
|
93
|
+
let output = '';
|
|
94
|
+
let cursor = 0;
|
|
95
|
+
let first = 0;
|
|
96
|
+
while(first < groups.length){
|
|
97
|
+
let digits = '';
|
|
98
|
+
let matchedLast = -1;
|
|
99
|
+
for(let last = first; last < groups.length; last++){
|
|
100
|
+
digits += groups[last].digits;
|
|
101
|
+
if (digits.length > 19) break;
|
|
102
|
+
if (digits.length >= 13 && passesLuhn(digits)) matchedLast = last;
|
|
103
|
+
}
|
|
104
|
+
if (matchedLast >= 0) {
|
|
105
|
+
output += match.slice(cursor, groups[first].start) + REDACTED_VALUE;
|
|
106
|
+
cursor = groups[matchedLast].end;
|
|
107
|
+
first = matchedLast + 1;
|
|
108
|
+
} else first++;
|
|
109
|
+
}
|
|
110
|
+
return output + match.slice(cursor);
|
|
111
|
+
}
|
|
112
|
+
function redactPii(value) {
|
|
113
|
+
let result = value.replace(UNICODE_SPACE_PATTERN, ' ');
|
|
114
|
+
result = result.replace(EMAIL_PATTERN, REDACTED_VALUE);
|
|
115
|
+
result = result.replace(IPV4_PATTERN, REDACTED_VALUE);
|
|
116
|
+
result = result.replace(IPV6_PATTERN, REDACTED_VALUE);
|
|
117
|
+
result = result.replace(CREDIT_CARD_CANDIDATE_PATTERN, redactCardInMatch);
|
|
118
|
+
result = result.replace(US_SSN_PATTERN, REDACTED_VALUE);
|
|
119
|
+
result = result.replace(PHONE_NANP_PATTERN, REDACTED_VALUE);
|
|
120
|
+
result = result.replace(PHONE_INTL_PATTERN, REDACTED_VALUE);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
62
123
|
function sanitizeCapturedValue(value) {
|
|
63
124
|
if (null == value) return value;
|
|
64
125
|
if ('string' == typeof value) return sanitizeString(value);
|
|
@@ -98,12 +159,15 @@ function buildCapturedMcpParameters(request) {
|
|
|
98
159
|
}
|
|
99
160
|
__webpack_require__.d(__webpack_exports__, {
|
|
100
161
|
buildCapturedMcpParameters: ()=>buildCapturedMcpParameters,
|
|
162
|
+
redactPii: ()=>redactPii,
|
|
101
163
|
sanitizeCapturedValue: ()=>sanitizeCapturedValue
|
|
102
164
|
});
|
|
103
165
|
exports.buildCapturedMcpParameters = __webpack_exports__.buildCapturedMcpParameters;
|
|
166
|
+
exports.redactPii = __webpack_exports__.redactPii;
|
|
104
167
|
exports.sanitizeCapturedValue = __webpack_exports__.sanitizeCapturedValue;
|
|
105
168
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
106
169
|
"buildCapturedMcpParameters",
|
|
170
|
+
"redactPii",
|
|
107
171
|
"sanitizeCapturedValue"
|
|
108
172
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
109
173
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -9,6 +9,15 @@ const BASE64_DATA_URL_PAYLOAD_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/;
|
|
|
9
9
|
const SIZE_GATE = 10240;
|
|
10
10
|
const POSTHOG_TOKEN_PATTERN = /\bph[a-z]_[A-Za-z0-9_-]{20,}\b/g;
|
|
11
11
|
const SENSITIVE_KEY_PATTERN = /^(authorization|cookie|set-cookie|x-api-key|api[-_]?key|api[-_]?token|access[-_]?token|refresh[-_]?token|token|password|secret|client[-_]?secret|private[-_]?key)$/i;
|
|
12
|
+
const UNICODE_SPACE_PATTERN = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
13
|
+
const EMAIL_PATTERN = /[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,255}\.[A-Za-z]{2,24}/g;
|
|
14
|
+
const IPV4_PATTERN = /\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b/g;
|
|
15
|
+
const IPV6_PATTERN = /\b(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}\b|(?<![\w:])(?:[0-9A-Fa-f]{1,4}:){1,7}:(?![\w:])|(?<![\w:])(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,5}(?![\w])|(?<![\w:])::(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,6})(?![\w])/g;
|
|
16
|
+
const US_SSN_PATTERN = /\b\d{3}[ .-]\d{2}[ .-]\d{4}\b/g;
|
|
17
|
+
const CREDIT_CARD_CANDIDATE_PATTERN = /\b\d(?:[ ./-]?\d){12,}\b/g;
|
|
18
|
+
const DIGIT_GROUP_PATTERN = /\d+/g;
|
|
19
|
+
const PHONE_NANP_PATTERN = /(?<![\w+])(?:\+?1[ ./-]?)?(?:\(\d{3}\)[ ./-]?|\d{3}[ ./-])\d{3}[ ./-]\d{4}(?![\w])/g;
|
|
20
|
+
const PHONE_INTL_PATTERN = /(?<!\w)\+\d{1,3}(?:[ ./()-]{0,2}\d){7,13}(?![\w])/g;
|
|
12
21
|
function isRecord(value) {
|
|
13
22
|
return !!value && 'object' == typeof value && !Array.isArray(value);
|
|
14
23
|
}
|
|
@@ -30,6 +39,58 @@ function sanitizeString(value) {
|
|
|
30
39
|
if (value.length >= SIZE_GATE && (BASE64_PATTERN.test(value) || isBase64DataUrl(value) || BASE64URL_SPECIFIC_CHAR_PATTERN.test(value) && BASE64URL_PATTERN.test(value))) return BINARY_REDACTED_VALUE;
|
|
31
40
|
return value.replace(POSTHOG_TOKEN_PATTERN, REDACTED_VALUE);
|
|
32
41
|
}
|
|
42
|
+
function passesLuhn(digits) {
|
|
43
|
+
let sum = 0;
|
|
44
|
+
let double = false;
|
|
45
|
+
for(let index = digits.length - 1; index >= 0; index--){
|
|
46
|
+
let digit = digits.charCodeAt(index) - 48;
|
|
47
|
+
if (digit < 0 || digit > 9) return false;
|
|
48
|
+
if (double) {
|
|
49
|
+
digit *= 2;
|
|
50
|
+
if (digit > 9) digit -= 9;
|
|
51
|
+
}
|
|
52
|
+
sum += digit;
|
|
53
|
+
double = !double;
|
|
54
|
+
}
|
|
55
|
+
return sum % 10 === 0;
|
|
56
|
+
}
|
|
57
|
+
function redactCardInMatch(match) {
|
|
58
|
+
const groups = [];
|
|
59
|
+
for(let m = DIGIT_GROUP_PATTERN.exec(match); null !== m; m = DIGIT_GROUP_PATTERN.exec(match))groups.push({
|
|
60
|
+
digits: m[0],
|
|
61
|
+
start: m.index,
|
|
62
|
+
end: m.index + m[0].length
|
|
63
|
+
});
|
|
64
|
+
let output = '';
|
|
65
|
+
let cursor = 0;
|
|
66
|
+
let first = 0;
|
|
67
|
+
while(first < groups.length){
|
|
68
|
+
let digits = '';
|
|
69
|
+
let matchedLast = -1;
|
|
70
|
+
for(let last = first; last < groups.length; last++){
|
|
71
|
+
digits += groups[last].digits;
|
|
72
|
+
if (digits.length > 19) break;
|
|
73
|
+
if (digits.length >= 13 && passesLuhn(digits)) matchedLast = last;
|
|
74
|
+
}
|
|
75
|
+
if (matchedLast >= 0) {
|
|
76
|
+
output += match.slice(cursor, groups[first].start) + REDACTED_VALUE;
|
|
77
|
+
cursor = groups[matchedLast].end;
|
|
78
|
+
first = matchedLast + 1;
|
|
79
|
+
} else first++;
|
|
80
|
+
}
|
|
81
|
+
return output + match.slice(cursor);
|
|
82
|
+
}
|
|
83
|
+
function redactPii(value) {
|
|
84
|
+
let result = value.replace(UNICODE_SPACE_PATTERN, ' ');
|
|
85
|
+
result = result.replace(EMAIL_PATTERN, REDACTED_VALUE);
|
|
86
|
+
result = result.replace(IPV4_PATTERN, REDACTED_VALUE);
|
|
87
|
+
result = result.replace(IPV6_PATTERN, REDACTED_VALUE);
|
|
88
|
+
result = result.replace(CREDIT_CARD_CANDIDATE_PATTERN, redactCardInMatch);
|
|
89
|
+
result = result.replace(US_SSN_PATTERN, REDACTED_VALUE);
|
|
90
|
+
result = result.replace(PHONE_NANP_PATTERN, REDACTED_VALUE);
|
|
91
|
+
result = result.replace(PHONE_INTL_PATTERN, REDACTED_VALUE);
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
33
94
|
function sanitizeCapturedValue(value) {
|
|
34
95
|
if (null == value) return value;
|
|
35
96
|
if ('string' == typeof value) return sanitizeString(value);
|
|
@@ -67,4 +128,4 @@ function buildCapturedMcpParameters(request) {
|
|
|
67
128
|
request: capturedRequest
|
|
68
129
|
};
|
|
69
130
|
}
|
|
70
|
-
export { buildCapturedMcpParameters, sanitizeCapturedValue };
|
|
131
|
+
export { buildCapturedMcpParameters, redactPii, sanitizeCapturedValue };
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import type { MCPAnalyticsOptions, MCPRequestLike, McpEvent } from '../types';
|
|
1
|
+
import type { MCPAnalyticsModelSource, MCPAnalyticsOptions, MCPRequestLike, McpEvent } from '../types';
|
|
2
2
|
import { type AnalyticsInjectableJsonSchema } from './analytics-parameters';
|
|
3
3
|
import { type LoggerFn } from './logger';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Model capture (`captureModel`).
|
|
6
6
|
*
|
|
7
|
-
* MCP
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* server side of the connection is the agent itself — harnesses inject the
|
|
11
|
-
* model id into the system prompt, so the agent can state it the same way it
|
|
12
|
-
* states its intent through the `context` parameter.
|
|
7
|
+
* MCP does not standardize model identity. Some clients expose it through
|
|
8
|
+
* vendor metadata, while other harnesses inject the model id into the system
|
|
9
|
+
* prompt so the agent can state it like intent through the `context` parameter.
|
|
13
10
|
*
|
|
14
11
|
* This module injects a required `llm_model` string parameter into every tool
|
|
15
12
|
* (mirroring `context-parameters.ts`), strips it before the tool runs, and
|
|
16
|
-
* captures
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
13
|
+
* captures the best available value as `$mcp_llm_model`. Client metadata wins
|
|
14
|
+
* over self-report, and `$mcp_llm_model_source` preserves that provenance.
|
|
15
|
+
* Both sources are unverified — right for degradation analytics ("does our MCP
|
|
16
|
+
* get worse on model X?"), never for billing or security.
|
|
20
17
|
*
|
|
21
18
|
* Reasoning effort is deliberately NOT captured: it never crosses the wire,
|
|
22
19
|
* and models cannot reliably self-report it (harnesses apply it as a sampling
|
|
@@ -44,5 +41,15 @@ export declare function addModelParameterToTools<TTool extends ModelInjectableTo
|
|
|
44
41
|
* not become a property value queries would group by.
|
|
45
42
|
*/
|
|
46
43
|
export declare function getModelArgument(request: MCPRequestLike): string | undefined;
|
|
47
|
-
export
|
|
44
|
+
export interface ResolvedModel {
|
|
45
|
+
model: string;
|
|
46
|
+
source: MCPAnalyticsModelSource;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolves model identity from sources visible to an MCP server. The Codex
|
|
50
|
+
* request metadata is host-generated and therefore more reliable than a model
|
|
51
|
+
* filling an injected argument, but remains unverified client input.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveModel(request: MCPRequestLike, allowSelfReported: boolean): ResolvedModel | undefined;
|
|
54
|
+
export declare function setEventModel(event: McpEvent, model: string | undefined, source?: MCPAnalyticsModelSource): void;
|
|
48
55
|
//# sourceMappingURL=model-parameters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/model-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"model-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/model-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACtG,OAAO,EAA+B,KAAK,6BAA6B,EAAE,MAAM,wBAAwB,CAAA;AAExG,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAE7C;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,6BAA6B,CAAA;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,mBAAmB,CAAC,cAAc,CAAC,GAAG,OAAO,CAEhG;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,mBAAmB,CAAC,cAAc,CAAC,GAAG,MAAM,GAAG,SAAS,CAEzG;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,mBAAmB,EACvE,IAAI,EAAE,KAAK,EACX,wBAAwB,CAAC,EAAE,MAAM,EACjC,MAAM,GAAE,QAAc,GACrB,KAAK,CAQP;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,mBAAmB,EACxE,KAAK,EAAE,KAAK,EAAE,EACd,wBAAwB,CAAC,EAAE,MAAM,EACjC,MAAM,GAAE,QAAc,GACrB,KAAK,EAAE,CAET;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAE5E;AAID,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,uBAAuB,CAAA;CAChC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAiB3G;AAiBD,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,GAAE,uBAAyC,GAChD,IAAI,CAON"}
|
|
@@ -33,6 +33,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
33
33
|
getModelArgument: ()=>getModelArgument,
|
|
34
34
|
getModelDescription: ()=>getModelDescription,
|
|
35
35
|
isCaptureModelEnabled: ()=>isCaptureModelEnabled,
|
|
36
|
+
resolveModel: ()=>resolveModel,
|
|
36
37
|
setEventModel: ()=>setEventModel
|
|
37
38
|
});
|
|
38
39
|
const external_analytics_parameters_js_namespaceObject = require("./analytics-parameters.js");
|
|
@@ -53,23 +54,45 @@ function addModelParameterToTools(tools, modelDescriptionOverride, logger = exte
|
|
|
53
54
|
function getModelArgument(request) {
|
|
54
55
|
return normalizeModel(request.params?.arguments?.llm_model);
|
|
55
56
|
}
|
|
57
|
+
const CODEX_TURN_METADATA_KEY = 'x-codex-turn-metadata';
|
|
58
|
+
function resolveModel(request, allowSelfReported) {
|
|
59
|
+
const codexMetadata = request.params?._meta?.[CODEX_TURN_METADATA_KEY];
|
|
60
|
+
if (isRecord(codexMetadata) && Object.prototype.hasOwnProperty.call(codexMetadata, 'model')) {
|
|
61
|
+
const model = normalizeModel(codexMetadata.model);
|
|
62
|
+
if (model) return {
|
|
63
|
+
model,
|
|
64
|
+
source: 'client_metadata'
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (allowSelfReported) {
|
|
68
|
+
const model = getModelArgument(request);
|
|
69
|
+
if (model) return {
|
|
70
|
+
model,
|
|
71
|
+
source: 'self_reported'
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isRecord(value) {
|
|
76
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
77
|
+
}
|
|
56
78
|
function normalizeModel(model) {
|
|
57
79
|
if ('string' != typeof model) return;
|
|
58
80
|
const trimmed = model.trim();
|
|
59
81
|
if (!trimmed || 'unknown' === trimmed.toLowerCase()) return;
|
|
60
82
|
return trimmed;
|
|
61
83
|
}
|
|
62
|
-
function setEventModel(event, model) {
|
|
84
|
+
function setEventModel(event, model, source = 'self_reported') {
|
|
63
85
|
const normalizedModel = normalizeModel(model);
|
|
64
86
|
if (!normalizedModel) return;
|
|
65
87
|
event.llmModel = normalizedModel;
|
|
66
|
-
event.llmModelSource =
|
|
88
|
+
event.llmModelSource = source;
|
|
67
89
|
}
|
|
68
90
|
exports.addModelParameterToTool = __webpack_exports__.addModelParameterToTool;
|
|
69
91
|
exports.addModelParameterToTools = __webpack_exports__.addModelParameterToTools;
|
|
70
92
|
exports.getModelArgument = __webpack_exports__.getModelArgument;
|
|
71
93
|
exports.getModelDescription = __webpack_exports__.getModelDescription;
|
|
72
94
|
exports.isCaptureModelEnabled = __webpack_exports__.isCaptureModelEnabled;
|
|
95
|
+
exports.resolveModel = __webpack_exports__.resolveModel;
|
|
73
96
|
exports.setEventModel = __webpack_exports__.setEventModel;
|
|
74
97
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
75
98
|
"addModelParameterToTool",
|
|
@@ -77,6 +100,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
|
77
100
|
"getModelArgument",
|
|
78
101
|
"getModelDescription",
|
|
79
102
|
"isCaptureModelEnabled",
|
|
103
|
+
"resolveModel",
|
|
80
104
|
"setEventModel"
|
|
81
105
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
82
106
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -16,16 +16,37 @@ function addModelParameterToTools(tools, modelDescriptionOverride, logger = log)
|
|
|
16
16
|
function getModelArgument(request) {
|
|
17
17
|
return normalizeModel(request.params?.arguments?.llm_model);
|
|
18
18
|
}
|
|
19
|
+
const CODEX_TURN_METADATA_KEY = 'x-codex-turn-metadata';
|
|
20
|
+
function resolveModel(request, allowSelfReported) {
|
|
21
|
+
const codexMetadata = request.params?._meta?.[CODEX_TURN_METADATA_KEY];
|
|
22
|
+
if (isRecord(codexMetadata) && Object.prototype.hasOwnProperty.call(codexMetadata, 'model')) {
|
|
23
|
+
const model = normalizeModel(codexMetadata.model);
|
|
24
|
+
if (model) return {
|
|
25
|
+
model,
|
|
26
|
+
source: 'client_metadata'
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (allowSelfReported) {
|
|
30
|
+
const model = getModelArgument(request);
|
|
31
|
+
if (model) return {
|
|
32
|
+
model,
|
|
33
|
+
source: 'self_reported'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function isRecord(value) {
|
|
38
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
39
|
+
}
|
|
19
40
|
function normalizeModel(model) {
|
|
20
41
|
if ('string' != typeof model) return;
|
|
21
42
|
const trimmed = model.trim();
|
|
22
43
|
if (!trimmed || 'unknown' === trimmed.toLowerCase()) return;
|
|
23
44
|
return trimmed;
|
|
24
45
|
}
|
|
25
|
-
function setEventModel(event, model) {
|
|
46
|
+
function setEventModel(event, model, source = 'self_reported') {
|
|
26
47
|
const normalizedModel = normalizeModel(model);
|
|
27
48
|
if (!normalizedModel) return;
|
|
28
49
|
event.llmModel = normalizedModel;
|
|
29
|
-
event.llmModelSource =
|
|
50
|
+
event.llmModelSource = source;
|
|
30
51
|
}
|
|
31
|
-
export { addModelParameterToTool, addModelParameterToTools, getModelArgument, getModelDescription, isCaptureModelEnabled, setEventModel };
|
|
52
|
+
export { addModelParameterToTool, addModelParameterToTools, getModelArgument, getModelDescription, isCaptureModelEnabled, resolveModel, setEventModel };
|
|
@@ -14,8 +14,8 @@ export interface PostHogMCPOptions extends PostHogOptions {
|
|
|
14
14
|
*/
|
|
15
15
|
missingCapabilityToolName?: string;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Capture the calling model from recognized client metadata, with an injected
|
|
18
|
+
* `llm_model` argument as fallback. Off by default.
|
|
19
19
|
*/
|
|
20
20
|
captureModel?: MCPAnalyticsOptions['captureModel'];
|
|
21
21
|
}
|
|
@@ -112,7 +112,7 @@ export declare class PostHogMCP extends PostHog {
|
|
|
112
112
|
* @example
|
|
113
113
|
* ```ts
|
|
114
114
|
* const { intent, intentSource, llmModel, llmModelSource, args, isMissingCapability } =
|
|
115
|
-
* posthog.prepareToolCall(name, rawArgs)
|
|
115
|
+
* posthog.prepareToolCall(name, rawArgs, { requestMeta: request.params?._meta })
|
|
116
116
|
* if (isMissingCapability) {
|
|
117
117
|
* posthog.captureMissingCapability({ context: intent, llmModel, llmModelSource, ...identity })
|
|
118
118
|
* return getMoreToolsResult()
|
|
@@ -1 +1 @@
|
|
|
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,EAErB,mBAAmB,EAGnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAEjB,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAA;AAgB7B;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;CACnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,UAAW,SAAQ,OAAO;;gBASzB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAO3D,8FAA8F;IAC9F,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI;
|
|
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,EAErB,mBAAmB,EAGnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAEjB,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAA;AAgB7B;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;CACnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,UAAW,SAAQ,OAAO;;gBASzB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAO3D,8FAA8F;IAC9F,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI;IAkBhD,iEAAiE;IACjE,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAUpD;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAclD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,eAAe,CAAC,KAAK,SAAS,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,GAAE,sBAA2B,GAAG,KAAK,EAAE;IAiCnH;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,GAAE,sBAA2B,GACnC,gBAAgB;IA4BnB;;;;OAIG;IACH,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,IAAI;CAmBnE"}
|
|
@@ -63,8 +63,7 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
|
|
|
63
63
|
event.isError = data.isError;
|
|
64
64
|
event.errorType = data.errorType;
|
|
65
65
|
applyIntent(event, data.intent, data.intentSource);
|
|
66
|
-
(0, external_model_parameters_js_namespaceObject.setEventModel)(event, data.llmModel);
|
|
67
|
-
if (event.llmModel && data.llmModelSource) event.llmModelSource = data.llmModelSource;
|
|
66
|
+
(0, external_model_parameters_js_namespaceObject.setEventModel)(event, data.llmModel, data.llmModelSource);
|
|
68
67
|
if (data.isError) event.error = (0, external_exceptions_js_namespaceObject.captureException)(data.error ?? `Tool ${data.toolName} returned an error`);
|
|
69
68
|
this.#emit(event);
|
|
70
69
|
}
|
|
@@ -115,17 +114,18 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
|
|
|
115
114
|
const rawContext = args?.context;
|
|
116
115
|
const intent = 'string' == typeof rawContext && rawContext.trim() ? rawContext.trim() : void 0;
|
|
117
116
|
const ownsModel = (0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(this.#captureModel) && (options.originalTool ? (0, external_analytics_parameters_js_namespaceObject.analyticsOwnsParameter)(options.originalTool.inputSchema, 'llm_model') : true === this.#modelParameterOwnership.get(name));
|
|
118
|
-
const
|
|
117
|
+
const resolvedModel = (0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(this.#captureModel) ? (0, external_model_parameters_js_namespaceObject.resolveModel)({
|
|
119
118
|
params: {
|
|
120
|
-
arguments: args
|
|
119
|
+
arguments: args,
|
|
120
|
+
_meta: options.requestMeta
|
|
121
121
|
}
|
|
122
|
-
}) : void 0;
|
|
122
|
+
}, ownsModel) : void 0;
|
|
123
123
|
const strippedArgs = stripContext(args);
|
|
124
124
|
return {
|
|
125
125
|
intent,
|
|
126
126
|
intentSource: intent ? 'context_parameter' : void 0,
|
|
127
|
-
llmModel,
|
|
128
|
-
llmModelSource:
|
|
127
|
+
llmModel: resolvedModel?.model,
|
|
128
|
+
llmModelSource: resolvedModel?.source,
|
|
129
129
|
args: ownsModel ? (0, external_analytics_parameters_js_namespaceObject.stripOwnedAnalyticsArguments)(strippedArgs, {
|
|
130
130
|
context: false,
|
|
131
131
|
conversationId: false,
|
|
@@ -139,8 +139,7 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
|
|
|
139
139
|
event.resourceName = this.#missingCapabilityToolName;
|
|
140
140
|
event.parameters = data.parameters;
|
|
141
141
|
applyIntent(event, data.context, 'context_parameter');
|
|
142
|
-
(0, external_model_parameters_js_namespaceObject.setEventModel)(event, data.llmModel);
|
|
143
|
-
if (event.llmModel && data.llmModelSource) event.llmModelSource = data.llmModelSource;
|
|
142
|
+
(0, external_model_parameters_js_namespaceObject.setEventModel)(event, data.llmModel, data.llmModelSource);
|
|
144
143
|
this.#emit(event);
|
|
145
144
|
}
|
|
146
145
|
#emit(event) {
|