feat(server): add WithMeter for OTEL-style metrics on requests and tools - #893
feat(server): add WithMeter for OTEL-style metrics on requests and tools#893QuentinBisson wants to merge 1 commit into
Conversation
|
Connected to Huly®: MCP_G-458 |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ddf0bd3 to
2388bb5
Compare
Mirror WithTracer's design for metrics. A new abstract metrics/ package
exposes Meter / Counter / Histogram / Attribute interfaces with a noop
default, so mcp-go itself stays free of any OTEL dependency. A new
server.WithMeter(metrics.Meter) installs the meter and registers the
following instruments:
- mcp.request.calls (counter, "{call}") with attributes mcp.method,
mcp.session.id (when set), mcp.protocol.version (from the
Mcp-Protocol-Version header), outcome (ok|error).
- mcp.request.duration (histogram, "s") with the same attributes.
- mcp.tool.calls (counter, "{call}") with attributes mcp.tool.name,
outcome (ok|error|error_result).
- mcp.tool.duration (histogram, "s") with the same attributes.
When a Tracer is also installed via WithTracer, the OTEL SDK attaches
exemplars carrying the active span's TraceID/SpanID to histogram
observations (the SDK does this automatically with its default
TraceBasedFilter), enabling "click latency bucket → jump to trace"
pivots in Grafana / Tempo.
The OpenTelemetry adapter at github.com/mark3labs/mcp-go/otel grows
WithServerMetrics(otelmetric.Meter) plus a NewMeter helper, matching
the existing tracer adapter API.
2388bb5 to
39b2f2e
Compare
|
@ezynda3 — would love your read on the design before this goes further. Two questions:
The instrument set is opinionated but small enough that splitting (request vs tool, counter vs histogram) is straightforward if you'd rather land just one slice first. |
Why
The server has `WithTracer` for OTEL spans on every dispatched JSON-RPC method (#856) but no symmetric primitive for metrics. Authors who want per-method or per-tool latency histograms today wrap individual tool handlers in their own `ToolHandlerMiddleware`, which only sees `tools/call` and never `initialize`, `tools/list`, `resources/read`, etc.
What
Three changes, all mirroring the existing `WithTracer` shape:
`metrics/` package — abstract `Meter` / `Counter` / `Histogram` interfaces with a noop default. mcp-go itself takes no OTEL (or any specific metrics library) dependency, mirroring how the `tracing` package abstracts `Tracer` / `Span`.
`server.WithMeter(metrics.Meter) ServerOption` — installs the meter and registers four instruments:
When a Tracer is also installed via `WithTracer`, the OTEL SDK attaches exemplars carrying the active span's TraceID/SpanID to histogram observations (default `TraceBasedFilter` does this automatically), enabling "click latency bucket → jump to trace" pivots in Grafana / Tempo.
`mcp-go/otel` adapter — gains `WithServerMetrics(otelmetric.Meter)` and `NewMeter`, mirroring the existing `WithServerTracing` / `NewTracer` pair.
Design parity with WithTracer
Validation