mcptest docs GitHub

OpenTelemetry tracing

MCP 2026-07-28 (SEP-414) folds tracing into the protocol: a client that wants its child operations attached to a parent span passes the W3C Trace Context (traceparent / tracestate) in the request _meta block. Servers that re-emit traces use these headers to build the parent / child relationship.

mcptest ships the library for that propagation today. Wiring it to a real OpenTelemetry SDK so a run lands spans in Jaeger / otel-cli / any OTLP collector is a follow-up.

Library surface

mcptest_core::otel:

ItemPurpose
TraceParent { trace_id, parent_id, flags }Typed W3C traceparent per RFC 9462.
TraceState(String)Opaque vendor list (round-trip lossless).
TraceFlags(u8)Sampling + reserved bits with .sampled() accessor.
TraceContextErrorTyped parse errors (BadShape / UnsupportedVersion / BadTraceId / ...).
TraceParent::parse(s)Strict parser (lowercase hex, length-checked, refuses all-zero ids).
TraceParent::to_wire()Format back to the wire form, byte-stable.
inject_into_meta(&mut meta, parent, state)Set _meta.traceparent + optional tracestate.
extract_from_meta(meta) -> Option<...>Read trace context off _meta.
RUN_SPAN_NAME / TEST_SPAN_NAME / tool_call_span_name(method)Stable span-name conventions.

Wire shape

A request that propagates a parent span:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "weather",
    "arguments": { "loc": "SFO" },
    "_meta": {
      "traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
      "tracestate":  "vendor1=opaqueValue,vendor2=opaqueValue"
    }
  }
}

traceparent is required when propagating. tracestate is optional (an empty vendor list is omitted by spec); the library mirrors that by skipping the key when the value is empty.

Strict parsing

TraceParent::parse matches RFC 9462 exactly:

Anything else returns a typed [TraceContextError].

Span naming

The conventions in span_names.rs align with the OTel semantic convention for RPC clients:

SpanNameNotes
Top-level runmcptest.runOne per mcptest run invocation.
Per-testmcptest.testTest name on the span attributes (mcptest.test.name), not the span name (cardinality).
Per tool callmcp/<method>Tool name is an attribute.

What ships today

Planned follow-up

Cross-references