@posthog/mcp 0.7.0 → 0.9.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.
Files changed (84) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +51 -0
  3. package/dist/extensions/capture.d.ts.map +1 -1
  4. package/dist/extensions/capture.js +1 -0
  5. package/dist/extensions/capture.mjs +1 -0
  6. package/dist/extensions/compatibility.d.ts.map +1 -1
  7. package/dist/extensions/constants.d.ts +2 -0
  8. package/dist/extensions/constants.d.ts.map +1 -1
  9. package/dist/extensions/constants.js +2 -0
  10. package/dist/extensions/constants.mjs +2 -0
  11. package/dist/extensions/context-parameters.d.ts.map +1 -1
  12. package/dist/extensions/conversation-id.d.ts.map +1 -1
  13. package/dist/extensions/event-types.d.ts.map +1 -1
  14. package/dist/extensions/exceptions.d.ts.map +1 -1
  15. package/dist/extensions/ids.d.ts.map +1 -1
  16. package/dist/extensions/instrument-highlevel.d.ts.map +1 -1
  17. package/dist/extensions/instrument-lowlevel.d.ts.map +1 -1
  18. package/dist/extensions/instrumentation.d.ts.map +1 -1
  19. package/dist/extensions/instrumentation.js +39 -3
  20. package/dist/extensions/instrumentation.mjs +41 -5
  21. package/dist/extensions/intent.d.ts.map +1 -1
  22. package/dist/extensions/internal.d.ts.map +1 -1
  23. package/dist/extensions/logger.d.ts.map +1 -1
  24. package/dist/extensions/mcp-payloads.d.ts.map +1 -1
  25. package/dist/extensions/mcp-sdk-compat.d.ts.map +1 -1
  26. package/dist/extensions/posthog-events.d.ts.map +1 -1
  27. package/dist/extensions/posthog-events.js +6 -0
  28. package/dist/extensions/posthog-events.mjs +6 -0
  29. package/dist/extensions/posthog-mcp.d.ts.map +1 -1
  30. package/dist/extensions/posthog-mcp.js +2 -0
  31. package/dist/extensions/posthog-mcp.mjs +2 -0
  32. package/dist/extensions/sanitization.d.ts.map +1 -1
  33. package/dist/extensions/session-token.d.ts +46 -0
  34. package/dist/extensions/session-token.d.ts.map +1 -0
  35. package/dist/extensions/session-token.js +122 -0
  36. package/dist/extensions/session-token.mjs +76 -0
  37. package/dist/extensions/session.d.ts +5 -4
  38. package/dist/extensions/session.d.ts.map +1 -1
  39. package/dist/extensions/session.js +25 -33
  40. package/dist/extensions/session.mjs +22 -27
  41. package/dist/extensions/sink.d.ts.map +1 -1
  42. package/dist/extensions/tools.d.ts.map +1 -1
  43. package/dist/extensions/tracing-helpers.d.ts.map +1 -1
  44. package/dist/extensions/truncation.d.ts.map +1 -1
  45. package/dist/extensions/truncation.js +1 -0
  46. package/dist/extensions/truncation.mjs +1 -0
  47. package/dist/index.d.ts +3 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +15 -2
  50. package/dist/index.mjs +2 -1
  51. package/dist/types.d.ts +32 -2
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/version.d.ts +1 -1
  54. package/dist/version.js +1 -1
  55. package/dist/version.mjs +1 -1
  56. package/package.json +3 -3
  57. package/src/extensions/capture.ts +11 -3
  58. package/src/extensions/compatibility.ts +4 -3
  59. package/src/extensions/constants.ts +6 -3
  60. package/src/extensions/context-parameters.ts +4 -3
  61. package/src/extensions/conversation-id.ts +4 -3
  62. package/src/extensions/event-types.ts +4 -3
  63. package/src/extensions/exceptions.ts +4 -3
  64. package/src/extensions/ids.ts +4 -3
  65. package/src/extensions/instrument-highlevel.ts +4 -3
  66. package/src/extensions/instrument-lowlevel.ts +4 -3
  67. package/src/extensions/instrumentation.ts +85 -9
  68. package/src/extensions/intent.ts +4 -3
  69. package/src/extensions/internal.ts +4 -3
  70. package/src/extensions/logger.ts +4 -3
  71. package/src/extensions/mcp-payloads.ts +4 -3
  72. package/src/extensions/mcp-sdk-compat.ts +4 -3
  73. package/src/extensions/posthog-events.ts +19 -3
  74. package/src/extensions/posthog-mcp.ts +2 -0
  75. package/src/extensions/sanitization.ts +4 -3
  76. package/src/extensions/session-token.ts +168 -0
  77. package/src/extensions/session.ts +42 -40
  78. package/src/extensions/sink.ts +4 -3
  79. package/src/extensions/tools.ts +4 -3
  80. package/src/extensions/tracing-helpers.ts +4 -3
  81. package/src/extensions/truncation.ts +5 -3
  82. package/src/index.ts +14 -4
  83. package/src/types.ts +38 -5
  84. package/src/version.ts +1 -1
@@ -0,0 +1,122 @@
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
+ MCP_SESSION_HEADER: ()=>MCP_SESSION_HEADER,
28
+ decodeSessionId: ()=>decodeSessionId,
29
+ encodeSessionId: ()=>encodeSessionId,
30
+ readMcpSessionHeader: ()=>readMcpSessionHeader,
31
+ writeSessionIdToTransport: ()=>writeSessionIdToTransport
32
+ });
33
+ const MCP_SESSION_HEADER = 'mcp-session-id';
34
+ const MAX_TOKEN_LENGTH = 4096;
35
+ const MAX_SESSION_ID_LENGTH = 128;
36
+ const MAX_CLIENT_FIELD_LENGTH = 200;
37
+ const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+={0,2}$/;
38
+ function encodeSessionId(payload) {
39
+ if (!payload || 'string' != typeof payload.sessionId || 0 === payload.sessionId.length) throw new Error('encodeSessionId requires a non-empty `sessionId` (use newSessionId())');
40
+ const wire = {
41
+ sid: payload.sessionId
42
+ };
43
+ if ('string' == typeof payload.clientName && payload.clientName.length > 0) wire.cn = payload.clientName.slice(0, MAX_CLIENT_FIELD_LENGTH);
44
+ if ('string' == typeof payload.clientVersion && payload.clientVersion.length > 0) wire.cv = payload.clientVersion.slice(0, MAX_CLIENT_FIELD_LENGTH);
45
+ return utf8ToBase64Url(JSON.stringify(wire));
46
+ }
47
+ function decodeSessionId(value) {
48
+ if ('string' != typeof value || 0 === value.length || value.length > MAX_TOKEN_LENGTH) return null;
49
+ if (!BASE64URL_PATTERN.test(value)) return null;
50
+ let parsed;
51
+ try {
52
+ parsed = JSON.parse(base64UrlToUtf8(value));
53
+ } catch {
54
+ return null;
55
+ }
56
+ if (!parsed || 'object' != typeof parsed || Array.isArray(parsed)) return null;
57
+ const wire = parsed;
58
+ if ('string' != typeof wire.sid || 0 === wire.sid.length || wire.sid.length > MAX_SESSION_ID_LENGTH) return null;
59
+ const payload = {
60
+ sessionId: wire.sid
61
+ };
62
+ if ('string' == typeof wire.cn && wire.cn.length > 0) payload.clientName = wire.cn.slice(0, MAX_CLIENT_FIELD_LENGTH);
63
+ if ('string' == typeof wire.cv && wire.cv.length > 0) payload.clientVersion = wire.cv.slice(0, MAX_CLIENT_FIELD_LENGTH);
64
+ return payload;
65
+ }
66
+ function readMcpSessionHeader(headers) {
67
+ if (!headers || 'object' != typeof headers) return;
68
+ const record = headers;
69
+ let value = record[MCP_SESSION_HEADER];
70
+ if (void 0 === value) {
71
+ const key = Object.keys(record).find((k)=>k.toLowerCase() === MCP_SESSION_HEADER);
72
+ value = void 0 === key ? void 0 : record[key];
73
+ }
74
+ const first = Array.isArray(value) ? value[0] : value;
75
+ if ('string' != typeof first) return;
76
+ const trimmed = first.trim();
77
+ return trimmed.length > 0 ? trimmed : void 0;
78
+ }
79
+ function writeSessionIdToTransport(transport, token) {
80
+ if (!transport || 'object' != typeof transport) return false;
81
+ const outer = transport;
82
+ try {
83
+ outer.sessionId = token;
84
+ } catch {}
85
+ if (outer.sessionId === token) return true;
86
+ const inner = outer._webStandardTransport;
87
+ if (inner && 'object' == typeof inner) try {
88
+ inner.sessionId = token;
89
+ } catch {}
90
+ return outer.sessionId === token;
91
+ }
92
+ function utf8ToBase64Url(input) {
93
+ if ('undefined' != typeof Buffer && 'function' == typeof Buffer.from) return Buffer.from(input, 'utf8').toString('base64url');
94
+ const bytes = new TextEncoder().encode(input);
95
+ let binary = '';
96
+ for(let i = 0; i < bytes.length; i++)binary += String.fromCharCode(bytes[i]);
97
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
98
+ }
99
+ function base64UrlToUtf8(input) {
100
+ const normalized = input.replace(/-/g, '+').replace(/_/g, '/').replace(/=+$/, '');
101
+ const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);
102
+ if ('undefined' != typeof Buffer && 'function' == typeof Buffer.from) return Buffer.from(padded, 'base64').toString('utf8');
103
+ const binary = atob(padded);
104
+ const bytes = new Uint8Array(binary.length);
105
+ for(let i = 0; i < binary.length; i++)bytes[i] = binary.charCodeAt(i);
106
+ return new TextDecoder().decode(bytes);
107
+ }
108
+ exports.MCP_SESSION_HEADER = __webpack_exports__.MCP_SESSION_HEADER;
109
+ exports.decodeSessionId = __webpack_exports__.decodeSessionId;
110
+ exports.encodeSessionId = __webpack_exports__.encodeSessionId;
111
+ exports.readMcpSessionHeader = __webpack_exports__.readMcpSessionHeader;
112
+ exports.writeSessionIdToTransport = __webpack_exports__.writeSessionIdToTransport;
113
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
114
+ "MCP_SESSION_HEADER",
115
+ "decodeSessionId",
116
+ "encodeSessionId",
117
+ "readMcpSessionHeader",
118
+ "writeSessionIdToTransport"
119
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
120
+ Object.defineProperty(exports, '__esModule', {
121
+ value: true
122
+ });
@@ -0,0 +1,76 @@
1
+ const MCP_SESSION_HEADER = 'mcp-session-id';
2
+ const MAX_TOKEN_LENGTH = 4096;
3
+ const MAX_SESSION_ID_LENGTH = 128;
4
+ const MAX_CLIENT_FIELD_LENGTH = 200;
5
+ const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+={0,2}$/;
6
+ function encodeSessionId(payload) {
7
+ if (!payload || 'string' != typeof payload.sessionId || 0 === payload.sessionId.length) throw new Error('encodeSessionId requires a non-empty `sessionId` (use newSessionId())');
8
+ const wire = {
9
+ sid: payload.sessionId
10
+ };
11
+ if ('string' == typeof payload.clientName && payload.clientName.length > 0) wire.cn = payload.clientName.slice(0, MAX_CLIENT_FIELD_LENGTH);
12
+ if ('string' == typeof payload.clientVersion && payload.clientVersion.length > 0) wire.cv = payload.clientVersion.slice(0, MAX_CLIENT_FIELD_LENGTH);
13
+ return utf8ToBase64Url(JSON.stringify(wire));
14
+ }
15
+ function decodeSessionId(value) {
16
+ if ('string' != typeof value || 0 === value.length || value.length > MAX_TOKEN_LENGTH) return null;
17
+ if (!BASE64URL_PATTERN.test(value)) return null;
18
+ let parsed;
19
+ try {
20
+ parsed = JSON.parse(base64UrlToUtf8(value));
21
+ } catch {
22
+ return null;
23
+ }
24
+ if (!parsed || 'object' != typeof parsed || Array.isArray(parsed)) return null;
25
+ const wire = parsed;
26
+ if ('string' != typeof wire.sid || 0 === wire.sid.length || wire.sid.length > MAX_SESSION_ID_LENGTH) return null;
27
+ const payload = {
28
+ sessionId: wire.sid
29
+ };
30
+ if ('string' == typeof wire.cn && wire.cn.length > 0) payload.clientName = wire.cn.slice(0, MAX_CLIENT_FIELD_LENGTH);
31
+ if ('string' == typeof wire.cv && wire.cv.length > 0) payload.clientVersion = wire.cv.slice(0, MAX_CLIENT_FIELD_LENGTH);
32
+ return payload;
33
+ }
34
+ function readMcpSessionHeader(headers) {
35
+ if (!headers || 'object' != typeof headers) return;
36
+ const record = headers;
37
+ let value = record[MCP_SESSION_HEADER];
38
+ if (void 0 === value) {
39
+ const key = Object.keys(record).find((k)=>k.toLowerCase() === MCP_SESSION_HEADER);
40
+ value = void 0 === key ? void 0 : record[key];
41
+ }
42
+ const first = Array.isArray(value) ? value[0] : value;
43
+ if ('string' != typeof first) return;
44
+ const trimmed = first.trim();
45
+ return trimmed.length > 0 ? trimmed : void 0;
46
+ }
47
+ function writeSessionIdToTransport(transport, token) {
48
+ if (!transport || 'object' != typeof transport) return false;
49
+ const outer = transport;
50
+ try {
51
+ outer.sessionId = token;
52
+ } catch {}
53
+ if (outer.sessionId === token) return true;
54
+ const inner = outer._webStandardTransport;
55
+ if (inner && 'object' == typeof inner) try {
56
+ inner.sessionId = token;
57
+ } catch {}
58
+ return outer.sessionId === token;
59
+ }
60
+ function utf8ToBase64Url(input) {
61
+ if ('undefined' != typeof Buffer && 'function' == typeof Buffer.from) return Buffer.from(input, 'utf8').toString('base64url');
62
+ const bytes = new TextEncoder().encode(input);
63
+ let binary = '';
64
+ for(let i = 0; i < bytes.length; i++)binary += String.fromCharCode(bytes[i]);
65
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
66
+ }
67
+ function base64UrlToUtf8(input) {
68
+ const normalized = input.replace(/-/g, '+').replace(/_/g, '/').replace(/=+$/, '');
69
+ const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);
70
+ if ('undefined' != typeof Buffer && 'function' == typeof Buffer.from) return Buffer.from(padded, 'base64').toString('utf8');
71
+ const binary = atob(padded);
72
+ const bytes = new Uint8Array(binary.length);
73
+ for(let i = 0; i < binary.length; i++)bytes[i] = binary.charCodeAt(i);
74
+ return new TextDecoder().decode(bytes);
75
+ }
76
+ export { MCP_SESSION_HEADER, decodeSessionId, encodeSessionId, readMcpSessionHeader, writeSessionIdToTransport };
@@ -6,11 +6,12 @@ export declare function newSessionId(): string;
6
6
  */
7
7
  export declare function deriveSessionIdFromMCPSession(mcpSessionId: string): string;
8
8
  /**
9
- * Resolves the session id for a request, preferring the MCP protocol sessionId
10
- * over an SDK-generated one so a transport-supplied session wins.
9
+ * Resolves the session id for a request: from the replayed session token, from
10
+ * the transport's MCP session id, or — when the request carries nothing — from
11
+ * this instance's memory. Also saves the token's client name/version so events
12
+ * built later in the request can use them (see getSessionInfo).
11
13
  */
12
- export declare function getServerSessionId(server: MCPServerLike, extra?: CompatibleRequestHandlerExtra): string;
13
- export declare function setLastActivity(server: MCPServerLike): void;
14
+ export declare function getSessionId(server: MCPServerLike, extra?: CompatibleRequestHandlerExtra): string;
14
15
  /**
15
16
  * Builds the session metadata stamped onto an event. The caller passes the
16
17
  * session id resolved for *this* request so identity attribution can't be
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/extensions/session.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,UAAU,CAAA;AAKjB,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,6BAA6B,GAAG,MAAM,CAoCvG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAS3D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,GAAG,SAAS,EAClC,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,CAgCb"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/extensions/session.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,UAAU,CAAA;AAMjB,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,6BAA6B,GAAG,MAAM,CA+BjG;AAgBD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,GAAG,SAAS,EAClC,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,CAgCb"}
@@ -24,8 +24,7 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
- setLastActivity: ()=>setLastActivity,
28
- getServerSessionId: ()=>getServerSessionId,
27
+ getSessionId: ()=>getSessionId,
29
28
  deriveSessionIdFromMCPSession: ()=>deriveSessionIdFromMCPSession,
30
29
  getSessionInfo: ()=>getSessionInfo,
31
30
  newSessionId: ()=>newSessionId
@@ -34,43 +33,38 @@ const external_version_js_namespaceObject = require("../version.js");
34
33
  const external_constants_js_namespaceObject = require("./constants.js");
35
34
  const external_ids_js_namespaceObject = require("./ids.js");
36
35
  const external_internal_js_namespaceObject = require("./internal.js");
36
+ const external_session_token_js_namespaceObject = require("./session-token.js");
37
37
  function newSessionId() {
38
38
  return (0, external_ids_js_namespaceObject.newPrefixedId)('ses');
39
39
  }
40
40
  function deriveSessionIdFromMCPSession(mcpSessionId) {
41
41
  return (0, external_ids_js_namespaceObject.deterministicPrefixedId)('ses', mcpSessionId);
42
42
  }
43
- function getServerSessionId(server, extra) {
43
+ function getSessionId(server, extra) {
44
44
  const data = (0, external_internal_js_namespaceObject.getServerTrackingData)(server);
45
45
  if (!data) throw new Error('Server tracking data not found');
46
- const mcpSessionId = extra?.sessionId;
47
- if (mcpSessionId) {
48
- data.sessionId = deriveSessionIdFromMCPSession(mcpSessionId);
49
- data.lastMcpSessionId = mcpSessionId;
46
+ const sessionHeader = (0, external_session_token_js_namespaceObject.readMcpSessionHeader)(extra?.requestInfo?.headers);
47
+ const token = (0, external_session_token_js_namespaceObject.decodeSessionId)(sessionHeader);
48
+ let sessionId;
49
+ if (token) {
50
+ data.sessionSource = 'token';
51
+ data.sessionInfo.clientName = token.clientName;
52
+ data.sessionInfo.clientVersion = token.clientVersion;
53
+ sessionId = token.sessionId;
54
+ } else if (extra?.sessionId) {
50
55
  data.sessionSource = 'mcp';
51
- (0, external_internal_js_namespaceObject.setServerTrackingData)(server, data);
52
- setLastActivity(server);
53
- return data.sessionId;
54
- }
55
- if ('mcp' === data.sessionSource && data.lastMcpSessionId) {
56
- setLastActivity(server);
57
- return data.sessionId;
58
- }
59
- const now = Date.now();
60
- const timeoutMs = 60 * external_constants_js_namespaceObject.INACTIVITY_TIMEOUT_IN_MINUTES * 1000;
61
- if (now - data.lastActivity.getTime() > timeoutMs) {
62
- data.sessionId = newSessionId();
63
- data.sessionSource = 'generated';
64
- (0, external_internal_js_namespaceObject.setServerTrackingData)(server, data);
65
- }
66
- setLastActivity(server);
67
- return data.sessionId;
68
- }
69
- function setLastActivity(server) {
70
- const data = (0, external_internal_js_namespaceObject.getServerTrackingData)(server);
71
- if (!data) throw new Error('Server tracking data not found');
56
+ sessionId = deriveSessionIdFromMCPSession(extra.sessionId);
57
+ } else sessionId = getSessionIdFromMemory(data);
58
+ data.sessionId = sessionId;
72
59
  data.lastActivity = new Date();
73
60
  (0, external_internal_js_namespaceObject.setServerTrackingData)(server, data);
61
+ return sessionId;
62
+ }
63
+ function getSessionIdFromMemory(data) {
64
+ const timeoutMs = 60 * external_constants_js_namespaceObject.INACTIVITY_TIMEOUT_IN_MINUTES * 1000;
65
+ const isStale = Date.now() - data.lastActivity.getTime() > timeoutMs;
66
+ if ('generated' === data.sessionSource && isStale) return newSessionId();
67
+ return data.sessionId;
74
68
  }
75
69
  function getSessionInfo(server, data, sessionId) {
76
70
  let clientInfo;
@@ -97,16 +91,14 @@ function getSessionInfo(server, data, sessionId) {
97
91
  return data.sessionInfo;
98
92
  }
99
93
  exports.deriveSessionIdFromMCPSession = __webpack_exports__.deriveSessionIdFromMCPSession;
100
- exports.getServerSessionId = __webpack_exports__.getServerSessionId;
94
+ exports.getSessionId = __webpack_exports__.getSessionId;
101
95
  exports.getSessionInfo = __webpack_exports__.getSessionInfo;
102
96
  exports.newSessionId = __webpack_exports__.newSessionId;
103
- exports.setLastActivity = __webpack_exports__.setLastActivity;
104
97
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
105
98
  "deriveSessionIdFromMCPSession",
106
- "getServerSessionId",
99
+ "getSessionId",
107
100
  "getSessionInfo",
108
- "newSessionId",
109
- "setLastActivity"
101
+ "newSessionId"
110
102
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
111
103
  Object.defineProperty(exports, '__esModule', {
112
104
  value: true
@@ -2,43 +2,38 @@ import { version } from "../version.mjs";
2
2
  import { INACTIVITY_TIMEOUT_IN_MINUTES } from "./constants.mjs";
3
3
  import { deterministicPrefixedId, newPrefixedId } from "./ids.mjs";
4
4
  import { getServerTrackingData, setServerTrackingData } from "./internal.mjs";
5
+ import { decodeSessionId, readMcpSessionHeader } from "./session-token.mjs";
5
6
  function newSessionId() {
6
7
  return newPrefixedId('ses');
7
8
  }
8
9
  function deriveSessionIdFromMCPSession(mcpSessionId) {
9
10
  return deterministicPrefixedId('ses', mcpSessionId);
10
11
  }
11
- function getServerSessionId(server, extra) {
12
+ function getSessionId(server, extra) {
12
13
  const data = getServerTrackingData(server);
13
14
  if (!data) throw new Error('Server tracking data not found');
14
- const mcpSessionId = extra?.sessionId;
15
- if (mcpSessionId) {
16
- data.sessionId = deriveSessionIdFromMCPSession(mcpSessionId);
17
- data.lastMcpSessionId = mcpSessionId;
15
+ const sessionHeader = readMcpSessionHeader(extra?.requestInfo?.headers);
16
+ const token = decodeSessionId(sessionHeader);
17
+ let sessionId;
18
+ if (token) {
19
+ data.sessionSource = 'token';
20
+ data.sessionInfo.clientName = token.clientName;
21
+ data.sessionInfo.clientVersion = token.clientVersion;
22
+ sessionId = token.sessionId;
23
+ } else if (extra?.sessionId) {
18
24
  data.sessionSource = 'mcp';
19
- setServerTrackingData(server, data);
20
- setLastActivity(server);
21
- return data.sessionId;
22
- }
23
- if ('mcp' === data.sessionSource && data.lastMcpSessionId) {
24
- setLastActivity(server);
25
- return data.sessionId;
26
- }
27
- const now = Date.now();
28
- const timeoutMs = 60 * INACTIVITY_TIMEOUT_IN_MINUTES * 1000;
29
- if (now - data.lastActivity.getTime() > timeoutMs) {
30
- data.sessionId = newSessionId();
31
- data.sessionSource = 'generated';
32
- setServerTrackingData(server, data);
33
- }
34
- setLastActivity(server);
35
- return data.sessionId;
36
- }
37
- function setLastActivity(server) {
38
- const data = getServerTrackingData(server);
39
- if (!data) throw new Error('Server tracking data not found');
25
+ sessionId = deriveSessionIdFromMCPSession(extra.sessionId);
26
+ } else sessionId = getSessionIdFromMemory(data);
27
+ data.sessionId = sessionId;
40
28
  data.lastActivity = new Date();
41
29
  setServerTrackingData(server, data);
30
+ return sessionId;
31
+ }
32
+ function getSessionIdFromMemory(data) {
33
+ const timeoutMs = 60 * INACTIVITY_TIMEOUT_IN_MINUTES * 1000;
34
+ const isStale = Date.now() - data.lastActivity.getTime() > timeoutMs;
35
+ if ('generated' === data.sessionSource && isStale) return newSessionId();
36
+ return data.sessionId;
42
37
  }
43
38
  function getSessionInfo(server, data, sessionId) {
44
39
  let clientInfo;
@@ -64,4 +59,4 @@ function getSessionInfo(server, data, sessionId) {
64
59
  setServerTrackingData(server, data);
65
60
  return data.sessionInfo;
66
61
  }
67
- export { deriveSessionIdFromMCPSession, getServerSessionId, getSessionInfo, newSessionId, setLastActivity };
62
+ export { deriveSessionIdFromMCPSession, getSessionId, getSessionInfo, newSessionId };
@@ -1 +1 @@
1
- {"version":3,"file":"sink.d.ts","sourceRoot":"","sources":["../../src/extensions/sink.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAE7D,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,GACzB,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BnE;AA4BD;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAE7C;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;CAmC1E"}
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;AAE7D,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,GACzB,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BnE;AA4BD;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAE7C;;;;OAIG;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":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAA;AAG9F,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,CA6B9G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CASnD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAG7E"}
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;AAG9F,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,CA6B9G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CASnD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAG7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"tracing-helpers.d.ts","sourceRoot":"","sources":["../../src/extensions/tracing-helpers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGzG;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAG9E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAExD"}
1
+ {"version":3,"file":"tracing-helpers.d.ts","sourceRoot":"","sources":["../../src/extensions/tracing-helpers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGzG;;;;;;GAMG;AAEH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAG9E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAExD"}
@@ -1 +1 @@
1
- {"version":3,"file":"truncation.d.ts","sourceRoot":"","sources":["../../src/extensions/truncation.ts"],"names":[],"mappings":"AAIA,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,CAmCrE"}
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,CAoCrE"}
@@ -250,6 +250,7 @@ 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.errorType = truncateString(result.errorType, MAX_METADATA_LENGTH);
253
254
  if (null != result.error && 'object' == typeof result.error) result.error = truncateExceptionList(result.error);
254
255
  result.response = truncateResponseContent(result.response);
255
256
  if (null != result.parameters) result.parameters = normalize(result.parameters);
@@ -217,6 +217,7 @@ 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.errorType = truncateString(result.errorType, MAX_METADATA_LENGTH);
220
221
  if (null != result.error && 'object' == typeof result.error) result.error = truncateExceptionList(result.error);
221
222
  result.response = truncateResponseContent(result.response);
222
223
  if (null != result.parameters) result.parameters = normalize(result.parameters);
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { PostHog } from 'posthog-node';
2
- import { deriveSessionIdFromMCPSession } from './extensions/session';
2
+ import { deriveSessionIdFromMCPSession, newSessionId } from './extensions/session';
3
3
  import type { McpAnalytics, MCPAnalyticsOptions } from './types';
4
4
  /**
5
5
  * Instruments an MCP server so PostHog auto-captures tool calls, tool listings, initialize
@@ -47,7 +47,8 @@ declare function instrument(server: unknown, posthog: PostHog, options?: MCPAnal
47
47
  * @returns A `(server) => server` mutator that instruments the server and returns it.
48
48
  */
49
49
  declare function instrumentMutator<TServer>(posthog: PostHog, options?: MCPAnalyticsOptions): (server: TServer) => TServer;
50
- export { deriveSessionIdFromMCPSession };
50
+ export { deriveSessionIdFromMCPSession, newSessionId };
51
+ export { MCP_SESSION_HEADER, decodeSessionId, encodeSessionId, type SessionTokenPayload, } from './extensions/session-token';
51
52
  export { POSTHOG_MCP_ANALYTICS_SOURCE, PostHogMCPAnalyticsEvent, PostHogMCPAnalyticsProperty, } from './extensions/constants';
52
53
  export { PostHogMCP, type PostHogMCPOptions } from './extensions/posthog-mcp';
53
54
  export { getMoreToolsResult } from './extensions/tools';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAQ3C,OAAO,EAAE,6BAA6B,EAAgC,MAAM,sBAAsB,CAAA;AAGlG,OAAO,KAAK,EAGV,YAAY,EAEZ,mBAAmB,EAGpB,MAAM,SAAS,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAS,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,mBAAwB,GAAG,YAAY,CAkCtG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAKjH;AAmFD,OAAO,EAAE,6BAA6B,EAAE,CAAA;AACxC,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAI/C,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC3D,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,EACxB,mBAAmB,EACnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,SAAS,CAAA;AAChB,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAQ3C,OAAO,EAAE,6BAA6B,EAAkB,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAGlG,OAAO,KAAK,EAGV,YAAY,EAEZ,mBAAmB,EAGpB,MAAM,SAAS,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAS,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,mBAAwB,GAAG,YAAY,CAkCtG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAKjH;AAmFD,OAAO,EAAE,6BAA6B,EAAE,YAAY,EAAE,CAAA;AAItD,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAI/C,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAC3D,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,EACxB,mBAAmB,EACnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,GACb,MAAM,SAAS,CAAA;AAChB,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAA"}
package/dist/index.js CHANGED
@@ -24,14 +24,18 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ setLogger: ()=>logger_js_namespaceObject.setLogger,
27
28
  PostHog: ()=>external_posthog_node_namespaceObject.PostHog,
28
29
  PostHogMCP: ()=>posthog_mcp_js_namespaceObject.PostHogMCP,
29
- deriveSessionIdFromMCPSession: ()=>session_js_namespaceObject.deriveSessionIdFromMCPSession,
30
30
  POSTHOG_MCP_ANALYTICS_SOURCE: ()=>constants_js_namespaceObject.POSTHOG_MCP_ANALYTICS_SOURCE,
31
+ deriveSessionIdFromMCPSession: ()=>session_js_namespaceObject.deriveSessionIdFromMCPSession,
31
32
  instrument: ()=>instrument,
33
+ decodeSessionId: ()=>session_token_js_namespaceObject.decodeSessionId,
34
+ newSessionId: ()=>session_js_namespaceObject.newSessionId,
35
+ MCP_SESSION_HEADER: ()=>session_token_js_namespaceObject.MCP_SESSION_HEADER,
32
36
  instrumentMutator: ()=>instrumentMutator,
33
- setLogger: ()=>logger_js_namespaceObject.setLogger,
34
37
  PostHogMCPAnalyticsEvent: ()=>constants_js_namespaceObject.PostHogMCPAnalyticsEvent,
38
+ encodeSessionId: ()=>session_token_js_namespaceObject.encodeSessionId,
35
39
  getMoreToolsResult: ()=>tools_js_namespaceObject.getMoreToolsResult,
36
40
  PostHogMCPAnalyticsProperty: ()=>constants_js_namespaceObject.PostHogMCPAnalyticsProperty
37
41
  });
@@ -45,6 +49,7 @@ const lib_identity_js_namespaceObject = require("./extensions/lib-identity.js");
45
49
  const session_js_namespaceObject = require("./extensions/session.js");
46
50
  const instrument_lowlevel_js_namespaceObject = require("./extensions/instrument-lowlevel.js");
47
51
  const instrument_highlevel_js_namespaceObject = require("./extensions/instrument-highlevel.js");
52
+ const session_token_js_namespaceObject = require("./extensions/session-token.js");
48
53
  const constants_js_namespaceObject = require("./extensions/constants.js");
49
54
  const posthog_mcp_js_namespaceObject = require("./extensions/posthog-mcp.js");
50
55
  const tools_js_namespaceObject = require("./extensions/tools.js");
@@ -132,26 +137,34 @@ async function captureCustomEvent(lowLevelServer, eventData) {
132
137
  await (0, capture_js_namespaceObject.captureEvent)(lowLevelServer, event);
133
138
  (0, logger_js_namespaceObject.log)(`Captured event "${eventData.event}" for session ${trackingData.sessionId}`);
134
139
  }
140
+ exports.MCP_SESSION_HEADER = __webpack_exports__.MCP_SESSION_HEADER;
135
141
  exports.POSTHOG_MCP_ANALYTICS_SOURCE = __webpack_exports__.POSTHOG_MCP_ANALYTICS_SOURCE;
136
142
  exports.PostHog = __webpack_exports__.PostHog;
137
143
  exports.PostHogMCP = __webpack_exports__.PostHogMCP;
138
144
  exports.PostHogMCPAnalyticsEvent = __webpack_exports__.PostHogMCPAnalyticsEvent;
139
145
  exports.PostHogMCPAnalyticsProperty = __webpack_exports__.PostHogMCPAnalyticsProperty;
146
+ exports.decodeSessionId = __webpack_exports__.decodeSessionId;
140
147
  exports.deriveSessionIdFromMCPSession = __webpack_exports__.deriveSessionIdFromMCPSession;
148
+ exports.encodeSessionId = __webpack_exports__.encodeSessionId;
141
149
  exports.getMoreToolsResult = __webpack_exports__.getMoreToolsResult;
142
150
  exports.instrument = __webpack_exports__.instrument;
143
151
  exports.instrumentMutator = __webpack_exports__.instrumentMutator;
152
+ exports.newSessionId = __webpack_exports__.newSessionId;
144
153
  exports.setLogger = __webpack_exports__.setLogger;
145
154
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
155
+ "MCP_SESSION_HEADER",
146
156
  "POSTHOG_MCP_ANALYTICS_SOURCE",
147
157
  "PostHog",
148
158
  "PostHogMCP",
149
159
  "PostHogMCPAnalyticsEvent",
150
160
  "PostHogMCPAnalyticsProperty",
161
+ "decodeSessionId",
151
162
  "deriveSessionIdFromMCPSession",
163
+ "encodeSessionId",
152
164
  "getMoreToolsResult",
153
165
  "instrument",
154
166
  "instrumentMutator",
167
+ "newSessionId",
155
168
  "setLogger"
156
169
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
157
170
  Object.defineProperty(exports, '__esModule', {
package/dist/index.mjs CHANGED
@@ -8,6 +8,7 @@ import { applyMcpLibIdentity } from "./extensions/lib-identity.mjs";
8
8
  import { deriveSessionIdFromMCPSession, getSessionInfo, newSessionId } from "./extensions/session.mjs";
9
9
  import { instrumentLowLevelServer } from "./extensions/instrument-lowlevel.mjs";
10
10
  import { instrumentHighLevelServer } from "./extensions/instrument-highlevel.mjs";
11
+ import { MCP_SESSION_HEADER, decodeSessionId, encodeSessionId } from "./extensions/session-token.mjs";
11
12
  import { POSTHOG_MCP_ANALYTICS_SOURCE, PostHogMCPAnalyticsEvent, PostHogMCPAnalyticsProperty } from "./extensions/constants.mjs";
12
13
  import { PostHogMCP } from "./extensions/posthog-mcp.mjs";
13
14
  import { getMoreToolsResult } from "./extensions/tools.mjs";
@@ -95,4 +96,4 @@ async function captureCustomEvent(lowLevelServer, eventData) {
95
96
  await captureEvent(lowLevelServer, event);
96
97
  log(`Captured event "${eventData.event}" for session ${trackingData.sessionId}`);
97
98
  }
98
- export { POSTHOG_MCP_ANALYTICS_SOURCE, PostHog, PostHogMCP, PostHogMCPAnalyticsEvent, PostHogMCPAnalyticsProperty, deriveSessionIdFromMCPSession, getMoreToolsResult, instrument, instrumentMutator, setLogger };
99
+ export { MCP_SESSION_HEADER, POSTHOG_MCP_ANALYTICS_SOURCE, PostHog, PostHogMCP, PostHogMCPAnalyticsEvent, PostHogMCPAnalyticsProperty, decodeSessionId, deriveSessionIdFromMCPSession, encodeSessionId, getMoreToolsResult, instrument, instrumentMutator, newSessionId, setLogger };
package/dist/types.d.ts CHANGED
@@ -114,6 +114,13 @@ export interface Event {
114
114
  conversationId?: string;
115
115
  duration?: number;
116
116
  error?: ErrorProperties | null;
117
+ /**
118
+ * Coarse failure category → `$mcp_error_type`. An explicit, low-cardinality
119
+ * label the host can supply (e.g. `validation`, `permission`, `timeout`).
120
+ * When omitted on an errored call, it falls back to the thrown error's type
121
+ * (the `$exception_list` entry's `type`).
122
+ */
123
+ errorType?: string;
117
124
  eventId?: string;
118
125
  eventType: MCPAnalyticsEventType;
119
126
  groups?: Record<string, string>;
@@ -148,9 +155,16 @@ export interface Event {
148
155
  }
149
156
  /** A partially-built MCP event as it flows through the SDK before capture. */
150
157
  export type McpEvent = Partial<Event>;
158
+ /** HTTP request info the SDK's Streamable HTTP transports attach per request. */
159
+ export interface CompatibleRequestInfoLike {
160
+ headers?: Record<string, string | string[] | undefined>;
161
+ [key: string]: unknown;
162
+ }
151
163
  export interface CompatibleRequestHandlerExtra {
152
164
  headers?: Record<string, string | string[]>;
153
165
  sessionId?: string;
166
+ /** Present on HTTP transports only — headers ride every request, unlike `clientInfo`. */
167
+ requestInfo?: CompatibleRequestInfoLike;
154
168
  [key: string]: unknown;
155
169
  }
156
170
  export interface ServerClientInfoLike {
@@ -170,9 +184,16 @@ export interface HighLevelMCPServerLike {
170
184
  tool?(name: string, paramsSchema: unknown, cb: ToolCallback): void;
171
185
  tool?(name: string, description: string, paramsSchema: unknown, cb: ToolCallback): void;
172
186
  }
187
+ /** The connected transport as exposed by the SDK's `Protocol.transport` getter. */
188
+ export interface CompatibleTransportLike {
189
+ sessionId?: string;
190
+ [key: string]: unknown;
191
+ }
173
192
  export interface MCPServerLike {
174
193
  _requestHandlers: Map<string, (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise<unknown>>;
175
194
  _serverInfo?: ServerClientInfoLike;
195
+ /** Optional so older SDKs (and bare test doubles) still validate. */
196
+ transport?: CompatibleTransportLike;
176
197
  getClientVersion(): ServerClientInfoLike | undefined;
177
198
  setRequestHandler(schema: unknown, handler: (request: MCPRequestLike, extra?: CompatibleRequestHandlerExtra) => Promise<unknown>): void;
178
199
  }
@@ -210,11 +231,11 @@ export interface MCPAnalyticsData {
210
231
  sink: McpEventSink | undefined;
211
232
  identifiedSessions: IdentityCache;
212
233
  lastActivity: Date;
213
- lastMcpSessionId?: string;
214
234
  options: MCPAnalyticsOptions;
215
235
  sessionId: string;
216
236
  sessionInfo: SessionInfo;
217
- sessionSource: 'generated' | 'mcp';
237
+ /** `token` = recovered from a self-encoded `Mcp-Session-Id` token (see session-token.ts). */
238
+ sessionSource: 'generated' | 'mcp' | 'token';
218
239
  toolCategories: Map<string, string>;
219
240
  toolDescriptions: Map<string, string>;
220
241
  }
@@ -286,6 +307,13 @@ export interface ToolCallCaptureData extends McpCaptureCommon {
286
307
  * synthesized from the tool name.
287
308
  */
288
309
  error?: unknown;
310
+ /**
311
+ * Coarse failure category → `$mcp_error_type` (e.g. `validation`,
312
+ * `permission`, `timeout`, `rate_limited`). A low-cardinality label that lets
313
+ * the dashboard break failures down by reason without joining to `$exception`.
314
+ * When omitted on an error, the SDK falls back to the thrown error's type.
315
+ */
316
+ errorType?: string;
289
317
  }
290
318
  /** Payload for {@link PostHogMCP.captureInitialize}. Emits `$mcp_initialize`. */
291
319
  export interface InitializeCaptureData extends McpCaptureCommon {
@@ -317,6 +345,8 @@ export interface ToolsListCaptureData extends McpCaptureCommon {
317
345
  isError?: boolean;
318
346
  /** The thrown value when `isError` is true → fans out an `$exception` sibling. */
319
347
  error?: unknown;
348
+ /** Coarse failure category → `$mcp_error_type`. Falls back to the thrown error's type. */
349
+ errorType?: string;
320
350
  }
321
351
  /** Options for {@link PostHogMCP.prepareToolList}. */
322
352
  export interface PrepareToolListOptions {