@posthog/mcp 0.10.1 → 0.10.2
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.map +1 -1
- package/dist/extensions/mcp-payloads.js +17 -1
- package/dist/extensions/mcp-payloads.mjs +17 -1
- package/dist/extensions/sanitization.d.ts.map +1 -1
- package/dist/extensions/sanitization.js +11 -0
- package/dist/extensions/sanitization.mjs +11 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +4 -4
- package/src/extensions/mcp-payloads.ts +28 -2
- package/src/extensions/sanitization.ts +23 -1
- package/src/version.ts +1 -1
|
@@ -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":"AAkBA,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAsCzC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0B7D;AA6BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBvE"}
|
|
@@ -29,7 +29,12 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
});
|
|
30
30
|
const CONTEXT_ARGUMENT_NAME = 'context';
|
|
31
31
|
const REDACTED_VALUE = '[redacted]';
|
|
32
|
+
const BINARY_REDACTED_VALUE = '[binary data redacted - not supported by PostHog MCP analytics]';
|
|
32
33
|
const BASE64_PATTERN = /^[A-Za-z0-9+/\n\r]+=*$/;
|
|
34
|
+
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+={0,2}$/;
|
|
35
|
+
const BASE64URL_SPECIFIC_CHAR_PATTERN = /[-_]/;
|
|
36
|
+
const BASE64_DATA_URL_PREFIX_PATTERN = /^data:[^,\s]*;base64,/i;
|
|
37
|
+
const BASE64_DATA_URL_PAYLOAD_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/;
|
|
33
38
|
const SIZE_GATE = 10240;
|
|
34
39
|
const POSTHOG_TOKEN_PATTERN = /\bph[a-z]_[A-Za-z0-9_-]{20,}\b/g;
|
|
35
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;
|
|
@@ -39,8 +44,19 @@ function isRecord(value) {
|
|
|
39
44
|
function shouldRedactKey(key) {
|
|
40
45
|
return SENSITIVE_KEY_PATTERN.test(key);
|
|
41
46
|
}
|
|
47
|
+
function isBase64DataUrl(value) {
|
|
48
|
+
const prefix = BASE64_DATA_URL_PREFIX_PATTERN.exec(value);
|
|
49
|
+
if (!prefix) return false;
|
|
50
|
+
let payload;
|
|
51
|
+
try {
|
|
52
|
+
payload = decodeURIComponent(value.slice(prefix[0].length));
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return BASE64_DATA_URL_PAYLOAD_PATTERN.test(payload.replace(/[\r\n]/g, ''));
|
|
57
|
+
}
|
|
42
58
|
function sanitizeString(value) {
|
|
43
|
-
if (value.length >= SIZE_GATE && BASE64_PATTERN.test(value)
|
|
59
|
+
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;
|
|
44
60
|
return value.replace(POSTHOG_TOKEN_PATTERN, REDACTED_VALUE);
|
|
45
61
|
}
|
|
46
62
|
function sanitizeCapturedValue(value) {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
const CONTEXT_ARGUMENT_NAME = 'context';
|
|
2
2
|
const REDACTED_VALUE = '[redacted]';
|
|
3
|
+
const BINARY_REDACTED_VALUE = '[binary data redacted - not supported by PostHog MCP analytics]';
|
|
3
4
|
const BASE64_PATTERN = /^[A-Za-z0-9+/\n\r]+=*$/;
|
|
5
|
+
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+={0,2}$/;
|
|
6
|
+
const BASE64URL_SPECIFIC_CHAR_PATTERN = /[-_]/;
|
|
7
|
+
const BASE64_DATA_URL_PREFIX_PATTERN = /^data:[^,\s]*;base64,/i;
|
|
8
|
+
const BASE64_DATA_URL_PAYLOAD_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/;
|
|
4
9
|
const SIZE_GATE = 10240;
|
|
5
10
|
const POSTHOG_TOKEN_PATTERN = /\bph[a-z]_[A-Za-z0-9_-]{20,}\b/g;
|
|
6
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;
|
|
@@ -10,8 +15,19 @@ function isRecord(value) {
|
|
|
10
15
|
function shouldRedactKey(key) {
|
|
11
16
|
return SENSITIVE_KEY_PATTERN.test(key);
|
|
12
17
|
}
|
|
18
|
+
function isBase64DataUrl(value) {
|
|
19
|
+
const prefix = BASE64_DATA_URL_PREFIX_PATTERN.exec(value);
|
|
20
|
+
if (!prefix) return false;
|
|
21
|
+
let payload;
|
|
22
|
+
try {
|
|
23
|
+
payload = decodeURIComponent(value.slice(prefix[0].length));
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return BASE64_DATA_URL_PAYLOAD_PATTERN.test(payload.replace(/[\r\n]/g, ''));
|
|
28
|
+
}
|
|
13
29
|
function sanitizeString(value) {
|
|
14
|
-
if (value.length >= SIZE_GATE && BASE64_PATTERN.test(value)
|
|
30
|
+
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;
|
|
15
31
|
return value.replace(POSTHOG_TOKEN_PATTERN, REDACTED_VALUE);
|
|
16
32
|
}
|
|
17
33
|
function sanitizeCapturedValue(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../../src/extensions/sanitization.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../../src/extensions/sanitization.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAmB,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAShE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAuBrE"}
|
|
@@ -37,8 +37,19 @@ function sanitizeEvent(event) {
|
|
|
37
37
|
if (null != result.response) result.response = sanitizeResponse(result.response);
|
|
38
38
|
if (null != result.parameters) result.parameters = sanitizeParameters(result.parameters);
|
|
39
39
|
if (null != result.userIntent) result.userIntent = (0, external_mcp_payloads_js_namespaceObject.sanitizeCapturedValue)(result.userIntent);
|
|
40
|
+
if (null != result.error) result.error = sanitizeExceptionValues(result.error);
|
|
40
41
|
return result;
|
|
41
42
|
}
|
|
43
|
+
function sanitizeExceptionValues(error) {
|
|
44
|
+
if (!Array.isArray(error.$exception_list)) return error;
|
|
45
|
+
return {
|
|
46
|
+
...error,
|
|
47
|
+
$exception_list: error.$exception_list.map((exception)=>({
|
|
48
|
+
...exception,
|
|
49
|
+
value: (0, external_mcp_payloads_js_namespaceObject.sanitizeCapturedValue)(exception.value)
|
|
50
|
+
}))
|
|
51
|
+
};
|
|
52
|
+
}
|
|
42
53
|
function sanitizeResponse(response) {
|
|
43
54
|
if (null == response || 'object' != typeof response) return (0, external_mcp_payloads_js_namespaceObject.sanitizeCapturedValue)(response);
|
|
44
55
|
const sanitized = (0, external_mcp_payloads_js_namespaceObject.sanitizeCapturedValue)(response);
|
|
@@ -9,8 +9,19 @@ function sanitizeEvent(event) {
|
|
|
9
9
|
if (null != result.response) result.response = sanitizeResponse(result.response);
|
|
10
10
|
if (null != result.parameters) result.parameters = sanitizeParameters(result.parameters);
|
|
11
11
|
if (null != result.userIntent) result.userIntent = sanitizeCapturedValue(result.userIntent);
|
|
12
|
+
if (null != result.error) result.error = sanitizeExceptionValues(result.error);
|
|
12
13
|
return result;
|
|
13
14
|
}
|
|
15
|
+
function sanitizeExceptionValues(error) {
|
|
16
|
+
if (!Array.isArray(error.$exception_list)) return error;
|
|
17
|
+
return {
|
|
18
|
+
...error,
|
|
19
|
+
$exception_list: error.$exception_list.map((exception)=>({
|
|
20
|
+
...exception,
|
|
21
|
+
value: sanitizeCapturedValue(exception.value)
|
|
22
|
+
}))
|
|
23
|
+
};
|
|
24
|
+
}
|
|
14
25
|
function sanitizeResponse(response) {
|
|
15
26
|
if (null == response || 'object' != typeof response) return sanitizeCapturedValue(response);
|
|
16
27
|
const sanitized = sanitizeCapturedValue(response);
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "0.10.
|
|
1
|
+
export declare const version = "0.10.2";
|
|
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.10.
|
|
29
|
+
const version = '0.10.2';
|
|
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.10.
|
|
1
|
+
const version = '0.10.2';
|
|
2
2
|
export { version };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/mcp",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
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.46.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@babel/preset-env": "^7.27.1",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"@types/node": "^20.0.0",
|
|
40
40
|
"jest": "29.7.0",
|
|
41
41
|
"zod": "^3.25.0",
|
|
42
|
-
"
|
|
43
|
-
"posthog-
|
|
42
|
+
"posthog-node": "^5.47.2",
|
|
43
|
+
"@posthog-tooling/tsconfig-base": "1.1.1"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@modelcontextprotocol/sdk": ">=1.26.0",
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
const CONTEXT_ARGUMENT_NAME = 'context'
|
|
7
7
|
const REDACTED_VALUE = '[redacted]'
|
|
8
|
+
const BINARY_REDACTED_VALUE = '[binary data redacted - not supported by PostHog MCP analytics]'
|
|
8
9
|
const BASE64_PATTERN = /^[A-Za-z0-9+/\n\r]+=*$/
|
|
10
|
+
const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+={0,2}$/
|
|
11
|
+
const BASE64URL_SPECIFIC_CHAR_PATTERN = /[-_]/
|
|
12
|
+
const BASE64_DATA_URL_PREFIX_PATTERN = /^data:[^,\s]*;base64,/i
|
|
13
|
+
const BASE64_DATA_URL_PAYLOAD_PATTERN = /^[A-Za-z0-9+/_-]+={0,2}$/
|
|
9
14
|
const SIZE_GATE = 10_240
|
|
10
15
|
const POSTHOG_TOKEN_PATTERN = /\bph[a-z]_[A-Za-z0-9_-]{20,}\b/g
|
|
11
16
|
const SENSITIVE_KEY_PATTERN =
|
|
@@ -21,9 +26,30 @@ function shouldRedactKey(key: string): boolean {
|
|
|
21
26
|
return SENSITIVE_KEY_PATTERN.test(key)
|
|
22
27
|
}
|
|
23
28
|
|
|
29
|
+
function isBase64DataUrl(value: string): boolean {
|
|
30
|
+
const prefix = BASE64_DATA_URL_PREFIX_PATTERN.exec(value)
|
|
31
|
+
if (!prefix) {
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let payload: string
|
|
36
|
+
try {
|
|
37
|
+
payload = decodeURIComponent(value.slice(prefix[0].length))
|
|
38
|
+
} catch {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return BASE64_DATA_URL_PAYLOAD_PATTERN.test(payload.replace(/[\r\n]/g, ''))
|
|
43
|
+
}
|
|
44
|
+
|
|
24
45
|
function sanitizeString(value: string): string {
|
|
25
|
-
if (
|
|
26
|
-
|
|
46
|
+
if (
|
|
47
|
+
value.length >= SIZE_GATE &&
|
|
48
|
+
(BASE64_PATTERN.test(value) ||
|
|
49
|
+
isBase64DataUrl(value) ||
|
|
50
|
+
(BASE64URL_SPECIFIC_CHAR_PATTERN.test(value) && BASE64URL_PATTERN.test(value)))
|
|
51
|
+
) {
|
|
52
|
+
return BINARY_REDACTED_VALUE
|
|
27
53
|
}
|
|
28
54
|
return value.replace(POSTHOG_TOKEN_PATTERN, REDACTED_VALUE)
|
|
29
55
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Copyright (c) 2025 AgentCat, Inc. (formerly MCPcat)
|
|
4
4
|
// Licensed under the MIT License: https://github.com/agentcathq/agentcat-typescript-sdk/blob/main/LICENSE
|
|
5
5
|
|
|
6
|
-
import type { Event, McpEvent } from '../types'
|
|
6
|
+
import type { ErrorProperties, Event, McpEvent } from '../types'
|
|
7
7
|
import { sanitizeCapturedValue } from './mcp-payloads'
|
|
8
8
|
|
|
9
9
|
type SanitizedRecord = Record<string, unknown>
|
|
@@ -39,9 +39,31 @@ export function sanitizeEvent<T extends Event | McpEvent>(event: T): T {
|
|
|
39
39
|
result.userIntent = sanitizeCapturedValue(result.userIntent) as string
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
if (result.error != null) {
|
|
43
|
+
result.error = sanitizeExceptionValues(result.error)
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
return result
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Sanitizes exception messages before they fan out to both the primary MCP
|
|
51
|
+
* event's error-message property and the `$exception` sibling.
|
|
52
|
+
*/
|
|
53
|
+
function sanitizeExceptionValues(error: ErrorProperties): ErrorProperties {
|
|
54
|
+
if (!Array.isArray(error.$exception_list)) {
|
|
55
|
+
return error
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
...error,
|
|
60
|
+
$exception_list: error.$exception_list.map((exception) => ({
|
|
61
|
+
...exception,
|
|
62
|
+
value: sanitizeCapturedValue(exception.value) as string,
|
|
63
|
+
})),
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
45
67
|
/**
|
|
46
68
|
* Sanitizes response content blocks by replacing non-text content types
|
|
47
69
|
* with informative redaction messages.
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '0.10.
|
|
1
|
+
export const version = '0.10.2'
|