SEP-414: Document OpenTelemetry Trace Context Propagation Conventions#414
Conversation
|
I would love the text in the spec to include more of what you have written in the PR description, and that the recommendation is to use It could be labelled as "Optional: OpenTelemetry context". I hope that SDKs decide to implement it where they have existing OTel ecosystems that they can leverage. MCP clients are not required to send it, and MCP servers that do not support OTel can safely ignore those parameters. This may be too much for the index file, but they could be added to the typescript and documentation. |
|
@samsp-msft, thanks for your thoughtful feedback! I’ve updated the "Basic" section to keep it neutral and avoid implying MCP defines OpenTelemetry (OTel) specifics: Updated Rationale:This keeps Specifically, we want to make room in otel for what's likely an inevitable OTEP for MCP. I say inevitable because the other discussion includes transport details (e.g. OTLP which is not propagation). This feels a lot like past discussions that led to specification clarifications including env variable propagation and how to handle messaging. In fact, there's already work in Otel for semantic conventions (thanks for participating in that). Ideally an engineer will be able to see the otel details coherently in one place (e.g. an OTEP). Long story short, deferring OTel keeps MCP focused on protocol mechanics, not telemetry details. By adding an example, we hint of how to hand-over to otel for clarity on telemetry. Does this address your concern? |
6c55543 to
2081ae2
Compare
|
I took time to update the description with feedback in the comments and also relating to discussions by @zengyizhao here and @wdawson here. Hope we can land this soon! |
|
@dsp-ant @jspahrsummers So, for anecdotal context. What drove me to the discussion leading to this and the PR itself was your podcast on latent space with @FanaHOVA and @swyxio Was a knock-out episode, and since working in oss since 2008 this made me feel the best:
So, my goal with this change was to make the absolutely least change possible, with the highest rigor. Even if it is a no, all good. Thanks for inspiring me to give it a go. I love the do the work, then let's talk approach to change. |
LGTM There is a balance between what needs to go into the base specification - providing the place to pass context - and having agreement amongst the SDK as to how they will use the extensibility mechanisms to implement telemetry propagation. The details of which key values pairs should be used and their values can probably be delegated to docs in the OTel space. It can probably go in the docs for the semantic conventions. I am hoping that we can get common agreement amongst most MCP SDKs about how to incorporate telemetry so that they can interoperate nicely, and it doesn't need major retrofits later. |
|
@samsp-msft thanks for the support. PS I raised a PR to csharp-sdk to change the carrier from |
757a83e to
8a5e71f
Compare
|
Earlier I mis-attributed I've revised the spec change to link to the progress spec, and also shored up the description accordingly. |
|
@dsp-ant do you have any advice for us on how to progress this PR? I'm happy to revise it, but it seems stalled. |
|
Right now, by naming convention ( Specifically, this PR describes some use cases:
Whereas in the schema today, there are 13 occurrences of this advice on
The recent work by @findleyr and friends on the Go SDK design implies code generation, and there's a small gap you can see if you look carefully here.
There are a number of ways to address code generation coherency.. we could make a single "meta" type and use that for Finally, we can decide to not solve it strictly in the schema. Rather, stick with advice here and mention to code generator authors that there's a relationship with anything ending in Request, Response etc that should have special casing. I don't have a preferred way out, but I would like to help close out this topic. Any thoughts? |
|
added a section to the description that it is possible a future JSON-RPC 2.1 could formalize "_meta". That said, I don't expect this to change any current practice. cc @mpcm |
|
@codefromthecrypt See recently posted: https://groups.google.com/g/json-rpc/c/pFFuI0JN8Cs |
|
In the JSON-RPC group discussion, I mentioned that responses could benefit from a The protocol currently uses |
|
@jonathanhefner Thanks for the suggestion - personally, if the compatibility issue is acceptable I would suggest top level |
|
We have a similar need. I too would prefer something outside of the params, although it's a good way to experiment for the time being. |
|
going to close this out as it hasn't moved forward in a month. happy to re-open when maintainers are interested in a change. Meanwhile, per the description, there are enough artifacts here and there to suggest |
|
FWIW, i was able to abuse the protocol's sending: https://github.com/dylibso/mcp-otel/blob/2407c736c92d6a5e71b454845d839f33dabbbfca/src/agent.ts#L122 I think this should be safe if you do your best to avoid name collisions, but going to ask around. Doing the actual context propagation and naming of everything works, but is a little tedious if you're not familiar with it. This could perhaps be part of an otel adapter for the SDKs, or one day adopted with the SDKs if some things can be agreed upon. |
|
@bhelx thx for the feedback. I will add to the description your use of this pattern which aligns with others mentioned there including Arize Openinference which is an otel SDK. That way folks don't have to scroll through comments should there be a desire to formalize this later. |
## Motivation and Context SEP-414 (modelcontextprotocol/modelcontextprotocol#414, merged for the 2026-07-28 spec release) documents OpenTelemetry trace context propagation conventions for MCP: the un-prefixed `_meta` keys `traceparent`, `tracestate`, and `baggage` are reserved (an explicit exception to the reverse-DNS prefix rule) so trace context can flow between MCP clients and servers per the W3C Trace Context and Baggage specifications. This follows the TypeScript SDK's approach (typescript-sdk#2270): guarantee `_meta` passthrough, export constants for the reserved key names, and lock the behavior in with regression tests and documentation, without adding an OpenTelemetry dependency (the Python SDK's python-sdk#2381 makes `opentelemetry-api` a hard dependency instead, which conflicts with this SDK's keep-dependencies-minimal policy): - New `MCP::TraceContext` module exposing `TRACEPARENT_META_KEY`, `TRACESTATE_META_KEY`, `BAGGAGE_META_KEY`, and `META_KEYS`. - The server side already passes incoming request `_meta` to tool and prompt handlers untouched via `server_context[:_meta]`; new regression tests pin that guarantee for the three reserved keys. - Every `MCP::Client` request method (`call_tool`, `read_resource`, `get_prompt`, `complete`, `ping`, and the `list_*` methods) gains a `meta:` keyword so Ruby clients can inject trace context (or any other `_meta` entries) into outgoing requests; per SEP-414, trace context should flow on every request, not only tool calls. The caller's hash is never mutated. On `call_tool`, `progress_token` takes precedence over a `progressToken` entry in `meta`, and an empty merge result omits `_meta` entirely, preserving the existing wire format. - README documents the convention and how to bridge the values to a tracing system such as the `opentelemetry-ruby` gems. Scope is intentionally client-to-server: server-initiated requests (`sampling/createMessage`, `roots/list`, `elicitation/create`) do not accept `meta:` yet; propagating trace context on those is a separate follow-up. Resolves #374. ## How Has This Been Tested? - New `test/mcp/trace_context_test.rb` pins the exact reserved key names and the frozen `META_KEYS` list. - New tests in `test/mcp/server_test.rb` assert that `tools/call` and `prompts/get` deliver `traceparent`, `tracestate`, and `baggage` (alongside `progressToken`) to handlers through `server_context[:_meta]` unchanged. - New tests in `test/mcp/client_test.rb` cover the `meta:` keyword: the trace keys are sent in `_meta` on `call_tool` and `read_resource`, a table-driven test exercises the remaining request methods (`tools/list`, `resources/list`, `resources/templates/list`, `prompts/list`, `prompts/get`, `completion/complete`, `ping`), `progress_token` overrides a `progressToken` entry in `meta` without duplicating the key, the caller's `meta` hash is not mutated, and requests without `meta:` serialize exactly as before (wire-format regressions for both the empty `meta` hash and the no-params list request). ## Breaking Changes None. `MCP::TraceContext` and the `meta:` keyword are purely additive, and requests without `meta:` serialize exactly as before.
Summary
This PR introduces SEP-414, documenting OpenTelemetry Trace Context Propagation Conventions
SEP
seps/414-request-meta.mdSponsor
@Kludex
Notes
This PR converts the earlier doc change into a standards-track SEP. Discussion links and rationale are in the SEP itself.