@posthog/mcp 0.22.0 → 0.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/mcp-payloads.d.ts +2 -28
- package/dist/extensions/mcp-payloads.d.ts.map +1 -1
- package/dist/extensions/mcp-payloads.js +9 -314
- package/dist/extensions/mcp-payloads.mjs +18 -323
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +2 -2
- package/src/extensions/mcp-payloads.ts +15 -666
- package/src/version.ts +1 -1
|
@@ -1,352 +1,47 @@
|
|
|
1
|
+
import { redactPii, sanitizeCapturedValue, sanitizeFreeText, sanitizeFreeTextValue } from "@posthog/core";
|
|
1
2
|
import { MAX_STRING_LENGTH, TRUNCATION_SUFFIX } from "./truncation.mjs";
|
|
2
3
|
const CONTEXT_ARGUMENT_NAME = 'context';
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const BASE64URL_SPECIFIC_CHAR_PATTERN = /[-_]/;
|
|
8
|
-
const BASE64_DATA_URL_PREFIX_PATTERN = /^data:[^,\s]*;base64,/i;
|
|
9
|
-
const BASE64_DATA_URL_PAYLOAD_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/;
|
|
10
|
-
const SIZE_GATE = 10240;
|
|
11
|
-
const SCANNED_HEAD_LENGTH = 4 * MAX_STRING_LENGTH;
|
|
12
|
-
const MIN_REDACTED_HEAD_LENGTH = 2 * MAX_STRING_LENGTH;
|
|
13
|
-
const POSTHOG_TOKEN_PATTERN = /\bph[a-z]_[A-Za-z0-9_-]{20,}\b/g;
|
|
14
|
-
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;
|
|
15
|
-
const URL_PATTERN = /[a-z][a-z0-9+.-]{0,63}:[^\s<>"]+/gi;
|
|
16
|
-
const URL_END_PATTERN = /[\s<>"]/;
|
|
17
|
-
const URL_PATTERN_ONCE = new RegExp(URL_PATTERN.source, 'i');
|
|
18
|
-
const URL_AUTHORITY_SEARCH = /[a-z][a-z0-9+.-]{0,63}:\/\//i;
|
|
19
|
-
const URL_AUTHORITY_PATTERN = new RegExp(`^${URL_AUTHORITY_SEARCH.source}`, 'i');
|
|
20
|
-
const URL_AUTHORITY_SEARCH_ALL = new RegExp(URL_AUTHORITY_SEARCH.source, 'gi');
|
|
21
|
-
const URL_FIELD_CHARACTERS = '=&';
|
|
22
|
-
const LEGACY_FIELD_SEPARATOR = ';';
|
|
23
|
-
const URL_TRAILING_PUNCTUATION = ".,;:!?)]}'";
|
|
24
|
-
const MAX_URL_LENGTH = 8192;
|
|
25
|
-
const MAX_URL_QUERY_FIELDS = 128;
|
|
26
|
-
const SENSITIVE_QUERY_KEY_SEGMENT_PATTERN = /(^|[-_./;])(auth|token|secret|password|passwd|pwd|credential|signature|sig|key|hmac|sas|bearer|jwt|session|sessionid)([-_./;]|$)/i;
|
|
27
|
-
const SENSITIVE_QUERY_KEY_EXACT_PATTERN = /^(code|AWSAccessKeyId|GoogleAccessId|Policy)$/i;
|
|
28
|
-
const UNICODE_SPACE_PATTERN = /[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
29
|
-
const EMAIL_PATTERN = /[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,255}\.[A-Za-z]{2,24}/g;
|
|
30
|
-
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;
|
|
31
|
-
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;
|
|
32
|
-
const US_SSN_PATTERN = /\b\d{3}[ .-]\d{2}[ .-]\d{4}\b/g;
|
|
33
|
-
const CREDIT_CARD_CANDIDATE_PATTERN = /\b\d(?:[ ./-]?\d){12,}\b/g;
|
|
34
|
-
const DIGIT_GROUP_PATTERN = /\d+/g;
|
|
35
|
-
const PHONE_NANP_PATTERN = /(?<![\w+])(?:\+?1[ ./-]?)?(?:\(\d{3}\)[ ./-]?|\d{3}[ ./-])\d{3}[ ./-]\d{4}(?![\w])/g;
|
|
36
|
-
const PHONE_INTL_PATTERN = /(?<!\w)\+\d{1,3}(?:[ ./()-]{0,2}\d){7,13}(?![\w])/g;
|
|
4
|
+
const SANITIZATION_OPTIONS = {
|
|
5
|
+
maxStringLength: MAX_STRING_LENGTH,
|
|
6
|
+
truncationSuffix: TRUNCATION_SUFFIX
|
|
7
|
+
};
|
|
37
8
|
function isRecord(value) {
|
|
38
9
|
return !!value && 'object' == typeof value && !Array.isArray(value);
|
|
39
10
|
}
|
|
40
|
-
function
|
|
41
|
-
return
|
|
11
|
+
function mcp_payloads_sanitizeFreeText(value) {
|
|
12
|
+
return sanitizeFreeText(value, SANITIZATION_OPTIONS);
|
|
42
13
|
}
|
|
43
|
-
function
|
|
44
|
-
return
|
|
14
|
+
function mcp_payloads_sanitizeCapturedValue(value) {
|
|
15
|
+
return sanitizeCapturedValue(value, SANITIZATION_OPTIONS);
|
|
45
16
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
if (!prefix) return false;
|
|
49
|
-
let payload;
|
|
50
|
-
try {
|
|
51
|
-
payload = decodeURIComponent(value.slice(prefix[0].length));
|
|
52
|
-
} catch {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
return BASE64_DATA_URL_PAYLOAD_PATTERN.test(payload.replace(/[\r\n]/g, ''));
|
|
56
|
-
}
|
|
57
|
-
function exceedsUrlFieldLimit(fields) {
|
|
58
|
-
return fields.split('&', MAX_URL_QUERY_FIELDS + 1).length > MAX_URL_QUERY_FIELDS;
|
|
59
|
-
}
|
|
60
|
-
function hasLegacySensitiveField(value) {
|
|
61
|
-
return value.split(LEGACY_FIELD_SEPARATOR).some((piece)=>shouldRedactQueryKey(piece.split('=', 1)[0]));
|
|
62
|
-
}
|
|
63
|
-
function sanitizeUrlFieldValue(key, value, allowNestedUrls) {
|
|
64
|
-
if (shouldRedactQueryKey(key)) return REDACTED_VALUE;
|
|
65
|
-
if (value.includes(LEGACY_FIELD_SEPARATOR) && hasLegacySensitiveField(value)) return REDACTED_VALUE;
|
|
66
|
-
if (!URL_PATTERN_ONCE.test(value)) return value;
|
|
67
|
-
return allowNestedUrls ? sanitizeUrlsInString(value, {
|
|
68
|
-
allowNestedUrls: false,
|
|
69
|
-
stripPunctuation: true
|
|
70
|
-
}) : REDACTED_VALUE;
|
|
71
|
-
}
|
|
72
|
-
function sanitizeUrlFields(fields, allowNestedUrls) {
|
|
73
|
-
const sanitized = new URLSearchParams();
|
|
74
|
-
let changed = false;
|
|
75
|
-
let lastFieldSensitive = false;
|
|
76
|
-
for (const [key, value] of new URLSearchParams(fields)){
|
|
77
|
-
const sanitizedValue = sanitizeUrlFieldValue(key, value, allowNestedUrls);
|
|
78
|
-
changed ||= sanitizedValue !== value;
|
|
79
|
-
lastFieldSensitive = shouldRedactQueryKey(key) || sanitizedValue !== value;
|
|
80
|
-
sanitized.append(key, sanitizedValue);
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
changed,
|
|
84
|
-
lastFieldSensitive,
|
|
85
|
-
serialized: sanitized.toString()
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
function splitTrailingPunctuation(value) {
|
|
89
|
-
let end = value.length;
|
|
90
|
-
while(end > 0 && URL_TRAILING_PUNCTUATION.includes(value[end - 1]))end--;
|
|
91
|
-
return {
|
|
92
|
-
address: value.slice(0, end),
|
|
93
|
-
suffix: value.slice(end)
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
function sanitizeFragmentTail(tail, headLastFieldSensitive, allowNestedUrls) {
|
|
97
|
-
if (!headLastFieldSensitive) return sanitizeFragmentPart(tail, allowNestedUrls);
|
|
98
|
-
return {
|
|
99
|
-
value: '' === tail ? '' : REDACTED_VALUE,
|
|
100
|
-
lastFieldSensitive: true
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
function splitFragmentParts(hash) {
|
|
104
|
-
const fragment = hash.slice(1);
|
|
105
|
-
const separator = fragment.indexOf('?');
|
|
106
|
-
if (separator < 0) return {
|
|
107
|
-
head: fragment,
|
|
108
|
-
tail: null
|
|
109
|
-
};
|
|
110
|
-
return {
|
|
111
|
-
head: fragment.slice(0, separator),
|
|
112
|
-
tail: fragment.slice(separator + 1)
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
function sanitizeFragmentPart(part, allowNestedUrls) {
|
|
116
|
-
if (!part.includes('=')) return {
|
|
117
|
-
value: sanitizeFragmentText(part, allowNestedUrls),
|
|
118
|
-
lastFieldSensitive: false
|
|
119
|
-
};
|
|
120
|
-
const fields = sanitizeUrlFields(part, allowNestedUrls);
|
|
121
|
-
return {
|
|
122
|
-
value: fields.changed ? fields.serialized : part,
|
|
123
|
-
lastFieldSensitive: fields.lastFieldSensitive
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
function sanitizeFragmentText(text, allowNestedUrls) {
|
|
127
|
-
if (!allowNestedUrls) return URL_PATTERN_ONCE.test(text) ? REDACTED_VALUE : text;
|
|
128
|
-
return sanitizeUrlsInString(text, {
|
|
129
|
-
allowNestedUrls: false,
|
|
130
|
-
stripPunctuation: true
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
function findEmbeddedAuthorityIndexes(value) {
|
|
134
|
-
if (!value.includes('://')) return [];
|
|
135
|
-
const starts = [
|
|
136
|
-
...value.matchAll(URL_AUTHORITY_SEARCH_ALL)
|
|
137
|
-
].map((match)=>match.index);
|
|
138
|
-
const indexes = [];
|
|
139
|
-
const delimiters = {
|
|
140
|
-
query: false,
|
|
141
|
-
fragment: false,
|
|
142
|
-
fragmentQuery: false
|
|
143
|
-
};
|
|
144
|
-
let pending = 0;
|
|
145
|
-
let inFields = false;
|
|
146
|
-
let lastStructural = '';
|
|
147
|
-
for(let cursor = 0; cursor < value.length && pending < starts.length; cursor++){
|
|
148
|
-
if (starts[pending] === cursor) {
|
|
149
|
-
if (cursor > 0 && '=' !== lastStructural) indexes.push(cursor);
|
|
150
|
-
pending++;
|
|
151
|
-
}
|
|
152
|
-
const character = value[cursor];
|
|
153
|
-
if (isDelimiter(character, delimiters, lastStructural)) {
|
|
154
|
-
lastStructural = character;
|
|
155
|
-
inFields = true;
|
|
156
|
-
} else if (inFields && URL_FIELD_CHARACTERS.includes(character)) lastStructural = character;
|
|
157
|
-
}
|
|
158
|
-
return indexes;
|
|
159
|
-
}
|
|
160
|
-
function isDelimiter(character, seen, lastStructural) {
|
|
161
|
-
if ('#' === character) return seen.fragment ? false : seen.fragment = true;
|
|
162
|
-
if ('?' !== character) return false;
|
|
163
|
-
if (seen.fragment) {
|
|
164
|
-
if ('=' === lastStructural) return false;
|
|
165
|
-
return seen.fragmentQuery ? false : seen.fragmentQuery = true;
|
|
166
|
-
}
|
|
167
|
-
return seen.query ? false : seen.query = true;
|
|
168
|
-
}
|
|
169
|
-
function sanitizeUrl(value, mode) {
|
|
170
|
-
const embedded = findEmbeddedAuthorityIndexes(value);
|
|
171
|
-
if (0 === embedded.length) return sanitizeSingleUrl(value, mode);
|
|
172
|
-
let result = '';
|
|
173
|
-
let start = 0;
|
|
174
|
-
for (const index of embedded){
|
|
175
|
-
result += sanitizeSingleUrl(value.slice(start, index), {
|
|
176
|
-
...mode,
|
|
177
|
-
stripPunctuation: false
|
|
178
|
-
});
|
|
179
|
-
start = index;
|
|
180
|
-
}
|
|
181
|
-
return result + sanitizeSingleUrl(value.slice(start), mode);
|
|
182
|
-
}
|
|
183
|
-
function sanitizeSingleUrl(value, mode) {
|
|
184
|
-
if (value.length > MAX_URL_LENGTH && URL_AUTHORITY_PATTERN.test(value)) return REDACTED_VALUE;
|
|
185
|
-
const { address, suffix } = mode.stripPunctuation ? splitTrailingPunctuation(value) : {
|
|
186
|
-
address: value,
|
|
187
|
-
suffix: ''
|
|
188
|
-
};
|
|
189
|
-
let url;
|
|
190
|
-
try {
|
|
191
|
-
url = new URL(address);
|
|
192
|
-
} catch {
|
|
193
|
-
return REDACTED_VALUE + suffix;
|
|
194
|
-
}
|
|
195
|
-
const query = url.search.slice(1);
|
|
196
|
-
const hasFragment = '' !== url.hash;
|
|
197
|
-
const fragment = splitFragmentParts(url.hash);
|
|
198
|
-
if (exceedsUrlFieldLimit(query) || exceedsUrlFieldLimit(fragment.head) || exceedsUrlFieldLimit(fragment.tail ?? '')) return REDACTED_VALUE + suffix;
|
|
199
|
-
let changed = false;
|
|
200
|
-
if (url.username || url.password) {
|
|
201
|
-
url.username = REDACTED_VALUE;
|
|
202
|
-
url.password = '';
|
|
203
|
-
changed = true;
|
|
204
|
-
}
|
|
205
|
-
const sanitizedQuery = sanitizeUrlFields(query, mode.allowNestedUrls);
|
|
206
|
-
if (sanitizedQuery.changed) {
|
|
207
|
-
url.search = sanitizedQuery.serialized;
|
|
208
|
-
changed = true;
|
|
209
|
-
}
|
|
210
|
-
const sanitizedHead = sanitizeFragmentPart(fragment.head, mode.allowNestedUrls);
|
|
211
|
-
const sanitizedTail = null === fragment.tail ? null : sanitizeFragmentTail(fragment.tail, sanitizedHead.lastFieldSensitive, mode.allowNestedUrls);
|
|
212
|
-
const sanitizedHash = null === sanitizedTail ? sanitizedHead.value : `${sanitizedHead.value}?${sanitizedTail.value}`;
|
|
213
|
-
if (sanitizedHash !== url.hash.slice(1)) {
|
|
214
|
-
url.hash = sanitizedHash;
|
|
215
|
-
changed = true;
|
|
216
|
-
}
|
|
217
|
-
const trailingFields = hasFragment ? sanitizedTail ?? sanitizedHead : sanitizedQuery;
|
|
218
|
-
return (changed ? url.toString() : address) + (trailingFields.lastFieldSensitive ? '' : suffix);
|
|
219
|
-
}
|
|
220
|
-
function sanitizeUrlsInString(text, mode) {
|
|
221
|
-
return text.replace(URL_PATTERN, (match)=>sanitizeUrl(match, {
|
|
222
|
-
...mode,
|
|
223
|
-
stripPunctuation: mode.stripPunctuation && match.length !== text.length
|
|
224
|
-
}));
|
|
225
|
-
}
|
|
226
|
-
function isBinaryBlob(value) {
|
|
227
|
-
return value.length >= SIZE_GATE && (BASE64_PATTERN.test(value) || isBase64DataUrl(value) || BASE64URL_SPECIFIC_CHAR_PATTERN.test(value) && BASE64URL_PATTERN.test(value));
|
|
228
|
-
}
|
|
229
|
-
function redactCredentials(value) {
|
|
230
|
-
return value.replace(POSTHOG_TOKEN_PATTERN, REDACTED_VALUE);
|
|
231
|
-
}
|
|
232
|
-
function redactUrls(value) {
|
|
233
|
-
return sanitizeUrlsInString(value, {
|
|
234
|
-
allowNestedUrls: true,
|
|
235
|
-
stripPunctuation: true
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
function redactCapturedHead(value, redact) {
|
|
239
|
-
if (value.length > SCANNED_HEAD_LENGTH) {
|
|
240
|
-
const head = redact(value.slice(0, headLength(value)));
|
|
241
|
-
if (head.length >= MIN_REDACTED_HEAD_LENGTH) return head + TRUNCATION_SUFFIX;
|
|
242
|
-
}
|
|
243
|
-
return redact(value);
|
|
244
|
-
}
|
|
245
|
-
function headLength(value) {
|
|
246
|
-
let end = SCANNED_HEAD_LENGTH;
|
|
247
|
-
while(end > 0 && !URL_END_PATTERN.test(value[end - 1]))end--;
|
|
248
|
-
return end;
|
|
249
|
-
}
|
|
250
|
-
function sanitizeString(value) {
|
|
251
|
-
return isBinaryBlob(value) ? BINARY_REDACTED_VALUE : redactCapturedHead(value, (head)=>redactUrls(redactCredentials(head)));
|
|
252
|
-
}
|
|
253
|
-
function sanitizeFreeText(value) {
|
|
254
|
-
if (isBinaryBlob(value)) return BINARY_REDACTED_VALUE;
|
|
255
|
-
return redactCapturedHead(value, (head)=>redactUrls(redactPii(redactCredentials(head))));
|
|
256
|
-
}
|
|
257
|
-
function passesLuhn(digits) {
|
|
258
|
-
let sum = 0;
|
|
259
|
-
let double = false;
|
|
260
|
-
for(let index = digits.length - 1; index >= 0; index--){
|
|
261
|
-
let digit = digits.charCodeAt(index) - 48;
|
|
262
|
-
if (digit < 0 || digit > 9) return false;
|
|
263
|
-
if (double) {
|
|
264
|
-
digit *= 2;
|
|
265
|
-
if (digit > 9) digit -= 9;
|
|
266
|
-
}
|
|
267
|
-
sum += digit;
|
|
268
|
-
double = !double;
|
|
269
|
-
}
|
|
270
|
-
return sum % 10 === 0;
|
|
271
|
-
}
|
|
272
|
-
function redactCardInMatch(match) {
|
|
273
|
-
const groups = [];
|
|
274
|
-
for(let m = DIGIT_GROUP_PATTERN.exec(match); null !== m; m = DIGIT_GROUP_PATTERN.exec(match))groups.push({
|
|
275
|
-
digits: m[0],
|
|
276
|
-
start: m.index,
|
|
277
|
-
end: m.index + m[0].length
|
|
278
|
-
});
|
|
279
|
-
let output = '';
|
|
280
|
-
let cursor = 0;
|
|
281
|
-
let first = 0;
|
|
282
|
-
while(first < groups.length){
|
|
283
|
-
let digits = '';
|
|
284
|
-
let matchedLast = -1;
|
|
285
|
-
for(let last = first; last < groups.length; last++){
|
|
286
|
-
digits += groups[last].digits;
|
|
287
|
-
if (digits.length > 19) break;
|
|
288
|
-
if (digits.length >= 13 && passesLuhn(digits)) matchedLast = last;
|
|
289
|
-
}
|
|
290
|
-
if (matchedLast >= 0) {
|
|
291
|
-
output += match.slice(cursor, groups[first].start) + REDACTED_VALUE;
|
|
292
|
-
cursor = groups[matchedLast].end;
|
|
293
|
-
first = matchedLast + 1;
|
|
294
|
-
} else first++;
|
|
295
|
-
}
|
|
296
|
-
return output + match.slice(cursor);
|
|
297
|
-
}
|
|
298
|
-
function redactPii(value) {
|
|
299
|
-
let result = value.replace(UNICODE_SPACE_PATTERN, ' ');
|
|
300
|
-
result = result.replace(EMAIL_PATTERN, REDACTED_VALUE);
|
|
301
|
-
result = result.replace(IPV4_PATTERN, REDACTED_VALUE);
|
|
302
|
-
result = result.replace(IPV6_PATTERN, REDACTED_VALUE);
|
|
303
|
-
result = result.replace(CREDIT_CARD_CANDIDATE_PATTERN, redactCardInMatch);
|
|
304
|
-
result = result.replace(US_SSN_PATTERN, REDACTED_VALUE);
|
|
305
|
-
result = result.replace(PHONE_NANP_PATTERN, REDACTED_VALUE);
|
|
306
|
-
result = result.replace(PHONE_INTL_PATTERN, REDACTED_VALUE);
|
|
307
|
-
return result;
|
|
308
|
-
}
|
|
309
|
-
function sanitizeCapturedValue(value) {
|
|
310
|
-
return sanitizeValueWith(value, sanitizeString);
|
|
311
|
-
}
|
|
312
|
-
function sanitizeFreeTextValue(value) {
|
|
313
|
-
return sanitizeValueWith(value, sanitizeFreeText);
|
|
314
|
-
}
|
|
315
|
-
function sanitizeValueWith(value, sanitizeStringFn) {
|
|
316
|
-
if (null == value) return value;
|
|
317
|
-
if ('string' == typeof value) return sanitizeStringFn(value);
|
|
318
|
-
if (Array.isArray(value)) return value.map((item)=>sanitizeValueWith(item, sanitizeStringFn));
|
|
319
|
-
if (value instanceof Date) return value;
|
|
320
|
-
if ('object' != typeof value) return value;
|
|
321
|
-
const result = {};
|
|
322
|
-
for (const [key, nestedValue] of Object.entries(value))result[key] = shouldRedactKey(key) ? REDACTED_VALUE : sanitizeValueWith(nestedValue, sanitizeStringFn);
|
|
323
|
-
return result;
|
|
17
|
+
function mcp_payloads_sanitizeFreeTextValue(value) {
|
|
18
|
+
return sanitizeFreeTextValue(value, SANITIZATION_OPTIONS);
|
|
324
19
|
}
|
|
325
20
|
function buildCapturedMcpArguments(argumentsValue) {
|
|
326
|
-
if (!isRecord(argumentsValue)) return
|
|
21
|
+
if (!isRecord(argumentsValue)) return mcp_payloads_sanitizeCapturedValue(argumentsValue);
|
|
327
22
|
const capturedArguments = {};
|
|
328
|
-
for (const [key, value] of Object.entries(argumentsValue))if (key !== CONTEXT_ARGUMENT_NAME) capturedArguments[key] =
|
|
23
|
+
for (const [key, value] of Object.entries(argumentsValue))if (key !== CONTEXT_ARGUMENT_NAME) capturedArguments[key] = mcp_payloads_sanitizeCapturedValue(value);
|
|
329
24
|
return capturedArguments;
|
|
330
25
|
}
|
|
331
26
|
function buildCapturedMcpParams(params) {
|
|
332
|
-
if (!isRecord(params)) return
|
|
27
|
+
if (!isRecord(params)) return mcp_payloads_sanitizeCapturedValue(params);
|
|
333
28
|
const capturedParams = {};
|
|
334
|
-
for (const [key, value] of Object.entries(params))capturedParams[key] = 'arguments' === key ? buildCapturedMcpArguments(value) :
|
|
29
|
+
for (const [key, value] of Object.entries(params))capturedParams[key] = 'arguments' === key ? buildCapturedMcpArguments(value) : mcp_payloads_sanitizeCapturedValue(value);
|
|
335
30
|
return capturedParams;
|
|
336
31
|
}
|
|
337
32
|
function buildCapturedMcpParameters(request) {
|
|
338
33
|
if (!isRecord(request)) return {
|
|
339
|
-
request:
|
|
34
|
+
request: mcp_payloads_sanitizeCapturedValue(request)
|
|
340
35
|
};
|
|
341
36
|
const capturedRequest = {};
|
|
342
37
|
for (const key of [
|
|
343
38
|
'id',
|
|
344
39
|
'jsonrpc',
|
|
345
40
|
'method'
|
|
346
|
-
])if (key in request) capturedRequest[key] =
|
|
41
|
+
])if (key in request) capturedRequest[key] = mcp_payloads_sanitizeCapturedValue(request[key]);
|
|
347
42
|
if ('params' in request) capturedRequest.params = buildCapturedMcpParams(request.params);
|
|
348
43
|
return {
|
|
349
44
|
request: capturedRequest
|
|
350
45
|
};
|
|
351
46
|
}
|
|
352
|
-
export { buildCapturedMcpParameters,
|
|
47
|
+
export { buildCapturedMcpParameters, mcp_payloads_sanitizeCapturedValue as sanitizeCapturedValue, mcp_payloads_sanitizeFreeText as sanitizeFreeText, mcp_payloads_sanitizeFreeTextValue as sanitizeFreeTextValue, redactPii };
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "0.22.
|
|
1
|
+
export declare const version = "0.22.1";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
package/dist/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = "0.22.
|
|
1
|
+
const version = "0.22.1";
|
|
2
2
|
export { version };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/mcp",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"bugs": {
|
|
5
5
|
"url": "https://github.com/PostHog/posthog-js/issues"
|
|
6
6
|
},
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"module": "dist/index.mjs",
|
|
29
29
|
"types": "dist/index.d.ts",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@posthog/core": "^1.
|
|
31
|
+
"@posthog/core": "^1.57.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@babel/preset-env": "^7.27.1",
|