@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.
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-payloads.d.ts","sourceRoot":"","sources":["../../src/extensions/mcp-payloads.ts"],"names":[],"mappings":"AAaA,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAiBzC,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0B7D;AA6BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAiBvE"}
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)) return '[binary data redacted - not supported by PostHog MCP analytics]';
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)) return '[binary data redacted - not supported by PostHog MCP analytics]';
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,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAS/C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,KAAK,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAmBrE"}
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";
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.1';
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';
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.1",
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.45.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
- "@posthog-tooling/tsconfig-base": "1.1.1",
43
- "posthog-node": "^5.46.1"
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 (value.length >= SIZE_GATE && BASE64_PATTERN.test(value)) {
26
- return '[binary data redacted - not supported by PostHog MCP analytics]'
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'
1
+ export const version = '0.10.2'