feat(telemetry): optional OpenTelemetry instrumentation for MCP operations - #129
Open
getlarge wants to merge 8 commits into
Open
feat(telemetry): optional OpenTelemetry instrumentation for MCP operations#129getlarge wants to merge 8 commits into
getlarge wants to merge 8 commits into
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- withSpan() helper wraps fn execution in an active OTel span, loading @opentelemetry/api dynamically on first use so users without the peer dep pay zero cost - MCP_ATTR constants and buildSpanAttributes() live in telemetry-constants.ts with no OTel dependency, so they can be imported statically by any module - Attribute keys are inlined rather than sourced from @opentelemetry/semantic-conventions: the JS semconv package only exports 4 of the 6 MCP attrs as of 1.40.0, under an explicitly unstable /experimental path. See telemetry-constants.ts for the full rationale. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TracerLike is a structural interface compatible with @opentelemetry/api's Tracer, defined locally so consumers don't need @opentelemetry/api installed just to import plugin types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- handleRequest wraps each JSON-RPC dispatch in withSpan when a tracer is configured on HandlerDependencies - Span names match the JSON-RPC method; span attributes use MCP semconv keys (mcp.method.name, mcp.session.id, plus mcp.tool.name / mcp.resource.uri / mcp.prompt.name for method-specific dispatches) - The telemetry module is loaded lazily via dynamic import inside the per-request wrap, so users without a tracer configured never touch @opentelemetry/api - Routes thread opts.telemetry?.tracer into processMessage - HandlerDependencies is now exported for advanced consumers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Export MCP_ATTR, buildSpanAttributes, withSpan, TracerLike, and HandlerDependencies from the package root so advanced consumers can build their own span wiring on top of the plugin. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- test/telemetry.test.ts: unit tests for withSpan (success/error paths, no-tracer fallthrough) and buildSpanAttributes - test/telemetry-types.test.ts: type-level tests for MCPPluginOptions.telemetry - test/telemetry-integration.test.ts: end-to-end plugin -> tracer wiring, driving tools/call and tools/list through the HTTP surface and asserting span names, attributes, and per-method extras (mcp.tool.name) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Member
|
Can you fix the conflicts? |
…tation # Conflicts: # package-lock.json # src/handlers.ts # src/routes/mcp.ts # src/types.ts
…tation # Conflicts: # src/handlers.ts # src/types.ts
Contributor
Author
|
@mcollina done, also updated to reflect progress in https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/mcp.md#recording-mcp-transport |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #128.
Adds optional OpenTelemetry tracing for MCP server operations. There is no telemetry-path overhead when no tracer is configured;
@opentelemetry/apiremains an optional peer dependency and is loaded dynamically only when tracing is enabled.What's included
telemetry?: { tracer: TracerLike }onMCPPluginOptions.TracerLikeis structural, so consumers do not need@opentelemetry/apiinstalled merely to import plugin types.SERVERspans.{mcp.method.name} {target}for tool and prompt operations, for exampletools/call echo.mcp.method.name,mcp.session.id, andmcp.protocol.versiongen_ai.tool.name,gen_ai.prompt.name, andgen_ai.operation.namejsonrpc.request.id,rpc.response.status_code, anderror.typemcp.resource.uriwhere applicablenetwork.transportand HTTPnetwork.protocol.*attributesclient.addressandclient.portwhen availableparams._metathrough the configured OpenTelemetry propagator. When a remote MCP parent is present, the ambient HTTP span is linked rather than used as the MCP span parent.network.transport = pipe.UNSETrather than being forced toOK.withSpan,buildSpanAttributes,MCP_ATTR,TracerLike, andHandlerDependenciesare exported for advanced consumers.Usage
Design note: local semantic-convention constants
The MCP conventions are still marked Development and now live in the OpenTelemetry GenAI semantic-conventions repository. The current convention uses
gen_ai.tool.nameandgen_ai.prompt.name; the oldermcp.tool.nameandmcp.prompt.namenames are not used.@opentelemetry/semantic-conventionsdoes not provide the complete current set through its stable entry point. Its earlier MCP exports were incubating, and version 1.42 deprecated them after MCP/GenAI conventions moved to the separate GenAI repository. The package also recommends copying unstable definitions into instrumentation libraries instead of importing the incubating entry point at runtime.For those reasons, this PR keeps the small set of required keys in
src/telemetry-constants.ts, with a source link to the current GenAI MCP specification. This avoids adding a runtime semantic-conventions dependency while making convention drift explicit and reviewable.Upstream reconciliation
The branch includes upstream
mainthrough v2.4.0 and preserves the newer tool authorization, task, andonToolCallCompletebehavior alongside telemetry instrumentation.Test plan
npm run typechecknpm run lintnpm run test:typesnpm run build