opentel-mcp 0.1.1 → 0.2.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 (2) hide show
  1. package/package.json +11 -6
  2. package/src/index.d.ts +97 -0
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "opentel-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "One-line OpenTelemetry instrumentation for Model Context Protocol (MCP) servers",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
+ "types": "./src/index.d.ts",
7
8
  "exports": {
8
- ".": "./src/index.js"
9
+ ".": {
10
+ "types": "./src/index.d.ts",
11
+ "default": "./src/index.js"
12
+ }
9
13
  },
10
14
  "files": [
11
15
  "src",
@@ -46,13 +50,14 @@
46
50
  "@opentelemetry/api": "^1.9.0"
47
51
  },
48
52
  "dependencies": {
49
- "@opentelemetry/sdk-trace-node": "^2.9.0",
50
53
  "@opentelemetry/exporter-trace-otlp-http": "^0.220.0",
51
- "@opentelemetry/resources": "^2.9.0"
54
+ "@opentelemetry/resources": "^2.9.0",
55
+ "@opentelemetry/sdk-trace-node": "^2.9.0"
52
56
  },
53
57
  "devDependencies": {
54
- "vitest": "^2.1.8",
55
58
  "@opentelemetry/api": "^1.9.0",
56
- "@opentelemetry/sdk-trace-base": "^2.9.0"
59
+ "@opentelemetry/sdk-trace-base": "^2.9.0",
60
+ "typescript": "^7.0.2",
61
+ "vitest": "^2.1.8"
57
62
  }
58
63
  }
package/src/index.d.ts ADDED
@@ -0,0 +1,97 @@
1
+ import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+
4
+ /**
5
+ * Options for {@link instrumentMcpServer}.
6
+ */
7
+ export interface InstrumentOptions {
8
+ /**
9
+ * Names the resource of the `NodeTracerProvider` this library creates.
10
+ *
11
+ * Required (and must be a non-empty string) when `setupNodeSdk` is `true` —
12
+ * omitting it in that mode throws at runtime. Has no effect when
13
+ * `setupNodeSdk` is `false` or omitted; in that mode, resource attributes
14
+ * (including `service.name`) come from whatever `TracerProvider` the host
15
+ * application has already registered, and passing `serviceName` anyway is
16
+ * harmless but logs a one-time `diag.warn`.
17
+ */
18
+ serviceName?: string;
19
+
20
+ /**
21
+ * OTLP/HTTP traces endpoint (e.g. `'http://localhost:4318/v1/traces'`).
22
+ *
23
+ * Only takes effect when `setupNodeSdk` is `true`.
24
+ */
25
+ exporterUrl?: string;
26
+
27
+ /**
28
+ * Set to `false` to disable instrumentation entirely; {@link instrumentMcpServer}
29
+ * becomes a no-op.
30
+ *
31
+ * @default true
32
+ */
33
+ enabled?: boolean;
34
+
35
+ /**
36
+ * When `true`, {@link instrumentMcpServer} creates and registers its own
37
+ * `NodeTracerProvider` (always exporting to stderr; additionally to
38
+ * `exporterUrl` via OTLP/HTTP if set).
39
+ *
40
+ * When `false` (the default), spans are emitted via whatever OpenTelemetry
41
+ * `TracerProvider` the host application has already registered globally —
42
+ * or dropped silently if none has been registered. This default keeps
43
+ * {@link instrumentMcpServer} from ever overriding a host application's own
44
+ * OpenTelemetry setup.
45
+ *
46
+ * @default false
47
+ */
48
+ setupNodeSdk?: boolean;
49
+ }
50
+
51
+ /**
52
+ * A high-level McpServer-like object, matched structurally the same way
53
+ * {@link instrumentMcpServer} itself matches it at runtime (see ADR 001):
54
+ * an object exposing a `.server` that looks like a low-level `Server` (has
55
+ * `setRequestHandler`), plus a `.tool` or `.registerTool` method.
56
+ *
57
+ * This structural fallback exists because the imported `McpServer` class
58
+ * has private fields, which makes TypeScript treat assignability to it as
59
+ * effectively nominal — an `McpServer` instance created by a *different*
60
+ * resolved copy of `@modelcontextprotocol/sdk` (e.g. a hoisting mismatch in
61
+ * a monorepo) would otherwise fail the type check even though it works
62
+ * fine at runtime, since the runtime never uses `instanceof McpServer` in
63
+ * the first place. This type mirrors the duck-typing the runtime already
64
+ * performs instead of relying on class identity.
65
+ */
66
+ export type DuckTypedMcpServer = {
67
+ server: { setRequestHandler: (...args: any[]) => any };
68
+ tool?: (...args: any[]) => any;
69
+ registerTool?: (...args: any[]) => any;
70
+ };
71
+
72
+ /**
73
+ * Instruments an MCP server so every tool call emits an OpenTelemetry span.
74
+ *
75
+ * Accepts either a low-level `Server` (from
76
+ * `@modelcontextprotocol/sdk/server/index.js`) or a high-level `McpServer`
77
+ * (from `@modelcontextprotocol/sdk/server/mcp.js`). Must be called before any
78
+ * `tools/call` handler is registered — i.e. before any
79
+ * `server.setRequestHandler(CallToolRequestSchema, ...)` (low-level) or
80
+ * `.tool()`/`.registerTool()` (McpServer) calls. Idempotent: calling this
81
+ * more than once — on the same object, or on the outer `McpServer` and its
82
+ * inner `Server` interchangeably — is a no-op after the first call.
83
+ *
84
+ * @param server - The server instance to instrument.
85
+ * @param options - Instrumentation options.
86
+ * @returns The same object that was passed in, for chaining. When
87
+ * `options.setupNodeSdk` is `true`, the returned object also gets a
88
+ * `shutdown()` method that flushes and shuts down the `NodeTracerProvider`
89
+ * created for it — call it during your process's own shutdown sequence to
90
+ * avoid losing buffered spans. `shutdown` is typed as optional because it
91
+ * is only attached at runtime when `setupNodeSdk` is `true`; check for its
92
+ * presence before calling.
93
+ */
94
+ export function instrumentMcpServer<T extends Server | McpServer | DuckTypedMcpServer>(
95
+ server: T,
96
+ options?: InstrumentOptions,
97
+ ): T & { shutdown?: () => Promise<void> };