semantic-conventions
semantic-conventions copied to clipboard
MCP semantic conventions
Fixes https://github.com/open-telemetry/semantic-conventions/issues/2043
Adds the first version of MCP conventions including spans and basic metrics.
Implementations/prototypes:
- .NET https://github.com/modelcontextprotocol/csharp-sdk/pull/262
- Python: https://github.com/mayankagarwals/openllmetry/tree/main/packages/opentelemetry-instrumentation-mcp
This PR was marked stale due to lack of activity. It will be closed in 7 days.
Closed as inactive. Feel free to reopen if this PR is still being worked on.
I realize this is dangling, but one thing I wanted to mention here: you should keep mcp.transport. Abstracting this purely to the network transport removes the value conventions add. For example, how would I identify the difference between http streaming and sse?
We (Sentry) are already implemented a variation of this spec, so I'm going to suggest to the team to capture that too. We'll probably just do "http" and "sse" and stick w/ the conventions used in the SDKs.
The committers listed above are authorized under a signed CLA.
- :white_check_mark: login: lmolkova / name: Liudmila Molkova (0ffe9c29cbed268e93149f6b16a461f58c02b734, 4aaeb65d69ad2bca3fecd9c887cb8e0110b85073, 5de1c3c54b8c85627429eb43e741ee8b2f5e4852, 9e8d1b021156de45637e905fdd73000181096216, aeb8a7540fb8c2509e783bddcabc0a1b3d67791d, cfcf1c108075009788dbde710f474a9c546b4e54, ddb37cbc0936c2bde27075bc7d27188e2c066d3e)
This PR contains changes to area(s) that do not have an active SIG/project and will be auto-closed:
- mcp
Such changes may be rejected or put on hold until a new SIG/project is established.
Please refer to the Semantic Convention Areas document to see the current active SIGs and also to learn how to kick start a new one.
This PR contains changes to area(s) that do not have an active SIG/project and will be auto-closed:
- mcp
Such changes may be rejected or put on hold until a new SIG/project is established.
Please refer to the Semantic Convention Areas document to see the current active SIGs and also to learn how to kick start a new one.
This PR contains changes to area(s) that do not have an active SIG/project and will be auto-closed:
- mcp
Such changes may be rejected or put on hold until a new SIG/project is established.
Please refer to the Semantic Convention Areas document to see the current active SIGs and also to learn how to kick start a new one.
This PR contains changes to area(s) that do not have an active SIG/project and will be auto-closed:
- mcp
Such changes may be rejected or put on hold until a new SIG/project is established.
Please refer to the Semantic Convention Areas document to see the current active SIGs and also to learn how to kick start a new one.
This PR contains changes to area(s) that do not have an active SIG/project and will be auto-closed:
- mcp
Such changes may be rejected or put on hold until a new SIG/project is established.
Please refer to the Semantic Convention Areas document to see the current active SIGs and also to learn how to kick start a new one.
I realize this is dangling, but one thing I wanted to mention here: you should keep mcp.transport. Abstracting this purely to the network transport removes the value conventions add. For example, how would I identify the difference between http streaming and sse?
We (Sentry) are already implemented a variation of this spec, so I'm going to suggest to the team to capture that too. We'll probably just do "http" and "sse" and stick w/ the conventions used in the SDKs.
I don't disagree with this comment, but want to point out that MCP replaces SSE with streamable HTTP starting with version 2025-03-26, so distinction between SSE and streamable HTTP is a temporary problem. If SSE is still used as a custom transport, we can always add extra attributes to capture custom transport details as a follow up.
Also, I think this problem is not unique to MCP - https://github.com/open-telemetry/semantic-conventions/issues/2512. I hope we can solve this problem incrementally without blocking the first version of MCP semconv on it.
@dsp-ant @domdomegg thanks a lot for your feedback! I incorporated some on it, in particular, I added mcp.protocol.version and clarified how network.* attributes could be used.
On the transport topic:
There are a lot of technologies that use pluggable transport (e.g. GCP clients can run over HTTP or gRPC, JSON-RPC and pretty much any RPC have some flexibility there) - I don't think we should define MCP specific attribute since it's a pretty generic problem.
What we have today here in this PR (after changes I just pushed):
| MCP transport | OTel attributes |
|---|---|
| stdio | network.transport = pipe mcp.protocol.version = 2025-06-18 no network.protocol.* attributes |
| streamable http | network.transport = tcp (or quic) mcp.protocol.version = 2025-06-18 network.protocol.name = http network.protocol.version = 1.1 (or 2) |
| http + sse | network.transport = tcp (or quic) mcp.protocol.version = 2024-11-05 network.protocol.name = http network.protocol.version = 1.1 |
| websockets | network.transport = tcp (or quic) mcp.protocol.version = ... network.protocol.name = websocket |
| grpc | network.transport = tcp (or quic) mcp.protocol.version = ... network.protocol.name = http network.protocol.version = 2 Note: the fact that it's gRPC is not recorded |
This should provide most, but not exhaustive information allowing to deduce MCP transport from attributes.
When someone's using MCP over HTTP (or gRPC), in addition to MCP spans applications will frequently see underlying HTTP or gRPC spans (and metrics) allowing users to understand their stack.
Having said this - this conventions is a first version, they can and will be evolved based on the feedback and could include capabilities and/or more details on the transport. We usually try to start with essentials and add details as we go. I'll make sure to create issue to follow up on capabilities.
I hope this make sense and thanks again for the feedback!
I think the table of transport related attributes should be in the spec, particularly to prevent people from doing something like network.protocol.name = http+sse.