@listo-ai/mcp-observability 0.4.0 → 0.5.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 CHANGED
@@ -14,6 +14,7 @@ This SDK provides comprehensive observability for [Model Context Protocol (MCP)]
14
14
  - **Centralized analytics** -- Send telemetry data to a remote endpoint in production
15
15
  - **Automatic tracking** -- HTTP requests via Express middleware, MCP tool invocations via handler wrapper
16
16
  - **Payload sanitization** -- Built-in redaction of sensitive keys (`password`, `token`, `apiKey`, `secret`, `authorization`)
17
+ - **Platform detection** -- Automatically identify the AI platform (Claude, ChatGPT, or other) from request headers and metadata
17
18
  - **Sampling** -- Configurable sampling rates with guaranteed capture of errors and session events
18
19
  - **Zero runtime dependencies** -- Only relies on Node.js built-ins (`crypto`, `http`)
19
20
 
@@ -24,6 +25,7 @@ This SDK provides comprehensive observability for [Model Context Protocol (MCP)]
24
25
  - [Browser Client](#browser-client)
25
26
  - [How It Works](#how-it-works)
26
27
  - [API Reference](#api-reference)
28
+ - [Platform Detection](#detectplatformhints)
27
29
  - [Integration Guide](#integration-guide)
28
30
  - [Event Types](#event-types)
29
31
  - [Environment Variables](#environment-variables)
@@ -83,6 +85,7 @@ import { createTelemetryClient } from '@listo-ai/mcp-observability/client';
83
85
 
84
86
  const client = createTelemetryClient({
85
87
  endpoint: 'https://myapp.com/telemetry',
88
+ deviceId: localStorage.getItem('device_id') ?? undefined,
86
89
  });
87
90
 
88
91
  // Share the session ID across widget instances
@@ -237,6 +240,7 @@ observability.recordBusinessEvent('product_search', {
237
240
  status: 'ok',
238
241
  category: 'conversion',
239
242
  sessionId: 'sess-abc',
243
+ deviceId: 'device-xyz',
240
244
  tenantId: 'tenant-1',
241
245
  });
242
246
  ```
@@ -249,6 +253,7 @@ Options:
249
253
  | `status` | `'ok' \| 'error'?` | Event status. Error events bypass sampling |
250
254
  | `category` | `EventCategory?` | `'conversion'`, `'engagement'`, `'impression'`, `'navigation'`, or `'system'` |
251
255
  | `sessionId` | `string?` | Session identifier for journey tracking |
256
+ | `deviceId` | `string?` | Device identifier for cross-session user identification |
252
257
  | `tenantId` | `string?` | Tenant identifier for multi-tenant apps |
253
258
 
254
259
  ### `observability.recordUiEvent(event)`
@@ -267,15 +272,33 @@ observability.recordUiEvent({
267
272
  });
268
273
  ```
269
274
 
275
+ ### `detectPlatform(hints?)`
276
+
277
+ Identify the AI platform calling your MCP server. Returns `'claude'`, `'chatgpt'`, or `'other'`.
278
+
279
+ ```typescript
280
+ import { detectPlatform } from '@listo-ai/mcp-observability';
281
+
282
+ const platform = detectPlatform({
283
+ headers: request.headers, // HTTP headers (user-agent, x-openai-*, x-anthropic-*)
284
+ meta: mcpRequest.params?._meta, // _meta key prefixes (openai/*, anthropic/*)
285
+ clientInfo: mcpRequest.params?.clientInfo // clientInfo.name fallback
286
+ });
287
+ // → 'claude', 'chatgpt', or 'other'
288
+ ```
289
+
290
+ Detection checks three signal tiers in order (first match wins): HTTP headers, `_meta` key prefixes, then `clientInfo.name`. See [Platform Detection docs](./docs/platform-detection.md) for details.
291
+
270
292
  ### `observability.recordSession(event)`
271
293
 
272
- Record MCP session lifecycle events.
294
+ Record MCP session lifecycle events. Pass `platform` from `detectPlatform()` on session open to attribute the session to an AI platform.
273
295
 
274
296
  ```typescript
275
297
  observability.recordSession({
276
298
  type: 'mcp_session',
277
299
  action: 'open',
278
300
  sessionId: 'session-123',
301
+ platform: detectPlatform({ headers: request.headers }),
279
302
  });
280
303
  ```
281
304
 
@@ -409,6 +432,7 @@ Recorded via `recordSession()`. Always captured regardless of sample rate.
409
432
  type: 'mcp_session',
410
433
  action: 'open', // or 'close'
411
434
  sessionId: 'session-123',
435
+ platform: 'claude', // 'claude', 'chatgpt', or 'other'
412
436
  }
413
437
  ```
414
438
 
@@ -503,6 +527,7 @@ Full Amplitude-style documentation is available in the [`docs/`](./docs/) direct
503
527
  | [Track HTTP](./docs/track-http.md) | `expressTelemetry()` + `trackHttpRequest()` |
504
528
  | [Wrap MCP Handlers](./docs/wrap-mcp-handlers.md) | `wrapMcpHandler()`, context fields |
505
529
  | [Sessions](./docs/sessions.md) | `recordSession()`, always-capture behavior |
530
+ | [Platform Detection](./docs/platform-detection.md) | `detectPlatform()`, header/meta/clientInfo signals |
506
531
  | [Business Events](./docs/business-events.md) | `recordBusinessEvent()` |
507
532
  | [UI Events](./docs/ui-events.md) | `recordUiEvent()` + POST endpoint |
508
533
  | [Browser Client](./docs/client.md) | `TelemetryClient` for browser apps |
package/dist/client.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export interface TelemetryClientOptions {
2
2
  endpoint: string;
3
3
  sessionId?: string;
4
+ deviceId?: string;
4
5
  tenantId?: string;
5
6
  locale?: string;
6
7
  batchSize?: number;
@@ -11,6 +12,7 @@ export interface TelemetryClientOptions {
11
12
  export declare class TelemetryClient {
12
13
  private readonly endpoint;
13
14
  private readonly sessionId;
15
+ private readonly deviceId?;
14
16
  private readonly batchSize;
15
17
  private readonly flushIntervalMs;
16
18
  private readonly onError;
@@ -21,6 +23,7 @@ export declare class TelemetryClient {
21
23
  private destroyed;
22
24
  constructor(options: TelemetryClientOptions);
23
25
  getSessionId(): string;
26
+ getDeviceId(): string | undefined;
24
27
  track(name: string, properties?: Record<string, unknown>, category?: string): void;
25
28
  trackUi(name: string, options: {
26
29
  action?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAeD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,sBAAsB;IAsB3C,YAAY,IAAI,MAAM;IAItB,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;IAaP,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACtC,GACA,IAAI;IAgBP,UAAU,CAAC,GAAG,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAK7D,KAAK,IAAI,IAAI;IAMb,OAAO,IAAI,IAAI;IAef,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,IAAI;IA8BZ,OAAO,CAAC,sBAAsB,CAI5B;CACH;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAEjB"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAgBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,sBAAsB;IAuB3C,YAAY,IAAI,MAAM;IAItB,WAAW,IAAI,MAAM,GAAG,SAAS;IAIjC,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;IAcP,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACtC,GACA,IAAI;IAiBP,UAAU,CAAC,GAAG,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAK7D,KAAK,IAAI,IAAI;IAMb,OAAO,IAAI,IAAI;IAef,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,IAAI;IA8BZ,OAAO,CAAC,sBAAsB,CAI5B;CACH;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAEjB"}
package/dist/client.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export class TelemetryClient {
2
2
  endpoint;
3
3
  sessionId;
4
+ deviceId;
4
5
  batchSize;
5
6
  flushIntervalMs;
6
7
  onError;
@@ -12,6 +13,7 @@ export class TelemetryClient {
12
13
  constructor(options) {
13
14
  this.endpoint = options.endpoint.replace(/\/+$/, '');
14
15
  this.sessionId = options.sessionId ?? globalThis.crypto.randomUUID();
16
+ this.deviceId = options.deviceId;
15
17
  this.batchSize = options.batchSize ?? 20;
16
18
  this.flushIntervalMs = options.flushIntervalMs ?? 5000;
17
19
  this.onError = options.onError ?? (() => { });
@@ -28,6 +30,9 @@ export class TelemetryClient {
28
30
  getSessionId() {
29
31
  return this.sessionId;
30
32
  }
33
+ getDeviceId() {
34
+ return this.deviceId;
35
+ }
31
36
  track(name, properties, category) {
32
37
  if (this.destroyed)
33
38
  return;
@@ -35,6 +40,7 @@ export class TelemetryClient {
35
40
  name,
36
41
  timestamp: Date.now(),
37
42
  sessionId: this.sessionId,
43
+ deviceId: this.deviceId,
38
44
  tenantId: this.context.tenantId,
39
45
  locale: this.context.locale,
40
46
  category,
@@ -48,6 +54,7 @@ export class TelemetryClient {
48
54
  name,
49
55
  timestamp: Date.now(),
50
56
  sessionId: this.sessionId,
57
+ deviceId: this.deviceId,
51
58
  tenantId: this.context.tenantId,
52
59
  locale: this.context.locale,
53
60
  action: options.action,
@@ -1 +1 @@
1
- {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,YAAY,CAAC;AAEjE,QAAA,MAAM,kBAAkB,eAAsC,CAAC;AAC/D,QAAA,MAAM,iBAAiB,eAAsC,CAAC;AAe9D,iBAAS,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAEjD;AA2CD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,gBAAgB,IAChD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAW9D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,GAAG,OAySvD;AAED,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../src/endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,YAAY,CAAC;AAEjE,QAAA,MAAM,kBAAkB,eAAsC,CAAC;AAC/D,QAAA,MAAM,iBAAiB,eAAsC,CAAC;AAe9D,iBAAS,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAEjD;AA4CD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,gBAAgB,IAChD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAW9D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,GAAG,OAySvD;AAED,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC"}
package/dist/endpoints.js CHANGED
@@ -21,6 +21,7 @@ const UI_EVENT_FIELDS = new Set([
21
21
  'widgetId',
22
22
  'toolName',
23
23
  'sessionId',
24
+ 'deviceId',
24
25
  'tenantId',
25
26
  'locale',
26
27
  'properties',
package/dist/index.d.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  export type EventStatus = 'ok' | 'error';
3
3
  export type EventCategory = 'conversion' | 'engagement' | 'impression' | 'navigation' | 'system';
4
+ export type KnownPlatform = 'claude' | 'chatgpt' | 'other';
5
+ export type Platform = KnownPlatform;
6
+ export type McpClientInfo = {
7
+ name: string;
8
+ version?: string;
9
+ };
10
+ export type PlatformHints = {
11
+ headers?: Record<string, string | string[] | undefined>;
12
+ meta?: Record<string, unknown>;
13
+ clientInfo?: McpClientInfo;
14
+ };
4
15
  export type HttpRequestEvent = {
5
16
  type: 'http_request';
6
17
  timestamp: number;
@@ -33,6 +44,7 @@ export type McpRequestEvent = {
33
44
  latencyMs: number;
34
45
  tenantId?: string;
35
46
  sessionId?: string;
47
+ platform?: Platform;
36
48
  locale?: string;
37
49
  userAgent?: string;
38
50
  argsHash?: string;
@@ -55,6 +67,7 @@ export type McpSessionEvent = {
55
67
  environment?: string;
56
68
  action: 'open' | 'close';
57
69
  sessionId: string;
70
+ platform?: Platform;
58
71
  };
59
72
  export type BusinessEvent = {
60
73
  type: 'business_event';
@@ -66,6 +79,7 @@ export type BusinessEvent = {
66
79
  status?: EventStatus;
67
80
  category?: EventCategory;
68
81
  sessionId?: string;
82
+ deviceId?: string;
69
83
  tenantId?: string;
70
84
  properties?: Record<string, unknown>;
71
85
  };
@@ -81,6 +95,7 @@ export type UiEvent = {
81
95
  widgetId?: string;
82
96
  toolName?: string;
83
97
  sessionId?: string;
98
+ deviceId?: string;
84
99
  tenantId?: string;
85
100
  locale?: string;
86
101
  properties?: Record<string, unknown>;
@@ -93,6 +108,7 @@ export type ObservabilityOptions = {
93
108
  serviceName: string;
94
109
  serviceVersion?: string;
95
110
  environment?: string;
111
+ platform?: Platform;
96
112
  sinks?: EventSink[];
97
113
  sampleRate?: number;
98
114
  redactKeys?: string[];
@@ -106,6 +122,7 @@ type HttpTrackingContext = {
106
122
  type McpTrackingContext = {
107
123
  sessionId?: string;
108
124
  tenantId?: string;
125
+ platform?: Platform;
109
126
  locale?: string;
110
127
  userAgent?: string;
111
128
  requestId?: string;
@@ -231,6 +248,7 @@ export type BusinessEventOptions = {
231
248
  status?: EventStatus;
232
249
  category?: EventCategory;
233
250
  sessionId?: string;
251
+ deviceId?: string;
234
252
  tenantId?: string;
235
253
  };
236
254
  export declare class McpObservability {
@@ -253,6 +271,20 @@ export declare class McpObservability {
253
271
  private safeEmit;
254
272
  }
255
273
  export declare function createMcpObservability(options: ObservabilityOptions): McpObservability;
274
+ /**
275
+ * Detect the AI platform from available request signals.
276
+ *
277
+ * Returns 'claude', 'chatgpt', or 'other'. Unrecognised platforms
278
+ * are bucketed as 'other' — extend HEADER_RULES / META_PREFIX_MAP /
279
+ * CLIENT_NAME_MAP to add new known platforms.
280
+ *
281
+ * Detection order (first match wins):
282
+ * 1. HTTP headers — user-agent string and custom platform headers (e.g. x-openai-*, x-anthropic-*)
283
+ * 2. _meta key prefixes — namespaced keys in request.params._meta (e.g. "openai/session")
284
+ * 3. clientInfo.name — MCP initialize clientInfo (unreliable on some platforms)
285
+ * 4. Fallback — 'other' when any hints are provided but no known platform matched
286
+ */
287
+ export declare function detectPlatform(hints?: PlatformHints): Platform;
256
288
  export { RemoteSink, createRemoteSink, type RemoteSinkOptions, } from './remote-sink.js';
257
289
  export { createMcpObservabilityEasy, type EasySetupConfig, } from './easy-setup.js';
258
290
  export { createTelemetryRouter, expressTelemetry } from './endpoints.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -211,6 +211,7 @@ export class McpObservability {
211
211
  latencyMs: performance.now() - start,
212
212
  tenantId: metadata.tenantId,
213
213
  sessionId: metadata.sessionId,
214
+ platform: metadata.platform,
214
215
  locale: metadata.locale,
215
216
  userAgent: metadata.userAgent,
216
217
  conversationId: metadata.conversationId,
@@ -252,6 +253,7 @@ export class McpObservability {
252
253
  latencyMs: performance.now() - start,
253
254
  tenantId: metadata.tenantId,
254
255
  sessionId: metadata.sessionId,
256
+ platform: metadata.platform,
255
257
  locale: metadata.locale,
256
258
  userAgent: metadata.userAgent,
257
259
  conversationId: metadata.conversationId,
@@ -287,6 +289,7 @@ export class McpObservability {
287
289
  status: options?.status,
288
290
  category: options?.category,
289
291
  sessionId: options?.sessionId,
292
+ deviceId: options?.deviceId,
290
293
  tenantId: options?.tenantId,
291
294
  };
292
295
  this.safeEmit(event);
@@ -342,6 +345,94 @@ export class McpObservability {
342
345
  export function createMcpObservability(options) {
343
346
  return new McpObservability(options);
344
347
  }
348
+ const HEADER_RULES = [
349
+ // ChatGPT / OpenAI — user-agent contains "openai" or x-openai-* headers present
350
+ [
351
+ (ua, h) => ua.includes('openai') ||
352
+ Object.keys(h).some((k) => k.startsWith('x-openai-')),
353
+ 'chatgpt',
354
+ ],
355
+ // Claude / Anthropic — user-agent contains "claude" or "anthropic", or x-anthropic-* headers
356
+ [
357
+ (ua, h) => ua.includes('claude') ||
358
+ ua.includes('anthropic') ||
359
+ Object.keys(h).some((k) => k.startsWith('x-anthropic-')),
360
+ 'claude',
361
+ ],
362
+ ];
363
+ // _meta key prefixes → platform
364
+ const META_PREFIX_MAP = [
365
+ ['openai/', 'chatgpt'],
366
+ ['anthropic/', 'claude'],
367
+ ['claude/', 'claude'],
368
+ ];
369
+ // clientInfo.name fallback map
370
+ const CLIENT_NAME_MAP = {
371
+ 'claude-desktop': 'claude',
372
+ claude: 'claude',
373
+ chatgpt: 'chatgpt',
374
+ };
375
+ const IGNORED_CLIENT_NAMES = new Set([
376
+ 'unavailable',
377
+ 'unknown',
378
+ 'n/a',
379
+ 'none',
380
+ '',
381
+ ]);
382
+ /**
383
+ * Detect the AI platform from available request signals.
384
+ *
385
+ * Returns 'claude', 'chatgpt', or 'other'. Unrecognised platforms
386
+ * are bucketed as 'other' — extend HEADER_RULES / META_PREFIX_MAP /
387
+ * CLIENT_NAME_MAP to add new known platforms.
388
+ *
389
+ * Detection order (first match wins):
390
+ * 1. HTTP headers — user-agent string and custom platform headers (e.g. x-openai-*, x-anthropic-*)
391
+ * 2. _meta key prefixes — namespaced keys in request.params._meta (e.g. "openai/session")
392
+ * 3. clientInfo.name — MCP initialize clientInfo (unreliable on some platforms)
393
+ * 4. Fallback — 'other' when any hints are provided but no known platform matched
394
+ */
395
+ export function detectPlatform(hints) {
396
+ if (!hints)
397
+ return 'other';
398
+ // 1. Headers: normalise to lowercase keys, check user-agent + custom headers
399
+ if (hints.headers && Object.keys(hints.headers).length > 0) {
400
+ const lowerHeaders = {};
401
+ for (const [k, v] of Object.entries(hints.headers)) {
402
+ if (v !== undefined) {
403
+ lowerHeaders[k.toLowerCase()] = Array.isArray(v) ? v.join(', ') : v;
404
+ }
405
+ }
406
+ const ua = (lowerHeaders['user-agent'] ?? '').toLowerCase();
407
+ for (const [test, platform] of HEADER_RULES) {
408
+ if (test(ua, lowerHeaders))
409
+ return platform;
410
+ }
411
+ }
412
+ // 2. _meta key prefixes
413
+ if (hints.meta && typeof hints.meta === 'object') {
414
+ const keys = Object.keys(hints.meta);
415
+ for (const [prefix, platform] of META_PREFIX_MAP) {
416
+ if (keys.some((k) => k.toLowerCase().startsWith(prefix)))
417
+ return platform;
418
+ }
419
+ }
420
+ // 3. clientInfo.name fallback
421
+ if (hints.clientInfo?.name) {
422
+ const name = hints.clientInfo.name.toLowerCase().trim();
423
+ if (!IGNORED_CLIENT_NAMES.has(name)) {
424
+ if (CLIENT_NAME_MAP[name])
425
+ return CLIENT_NAME_MAP[name];
426
+ for (const [key, platform] of Object.entries(CLIENT_NAME_MAP)) {
427
+ if (name.startsWith(`${key}-`) || name.startsWith(`${key}/`)) {
428
+ return platform;
429
+ }
430
+ }
431
+ }
432
+ }
433
+ // 4. Nothing matched — bucket as 'other'
434
+ return 'other';
435
+ }
345
436
  function hashPayload(payload) {
346
437
  try {
347
438
  const json = JSON.stringify(payload);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@listo-ai/mcp-observability",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Lightweight telemetry SDK for MCP servers and web applications. Captures HTTP requests, MCP tool invocations, business events, and UI interactions with built-in payload sanitization.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",