From ddb37cbc0936c2bde27075bc7d27188e2c066d3e Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 7 Apr 2025 17:25:30 -0700 Subject: [PATCH 01/22] MCP semantic conventions --- .chloggen/2083.yaml | 4 + .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/change_proposal.yaml | 1 + .github/ISSUE_TEMPLATE/new-conventions.yaml | 1 + AREAS.md | 2 +- areas.yaml | 1 + docs/gen-ai/README.md | 4 + docs/gen-ai/mcp.md | 753 ++++++++++++++++++++ docs/registry/attributes/README.md | 1 + docs/registry/attributes/mcp.md | 70 ++ model/mcp/common.yaml | 41 ++ model/mcp/metrics.yaml | 67 ++ model/mcp/registry.yaml | 193 +++++ model/mcp/spans.yaml | 70 ++ templates/registry/markdown/weaver.yaml | 1 + 16 files changed, 1210 insertions(+), 1 deletion(-) create mode 100644 .chloggen/2083.yaml create mode 100644 docs/gen-ai/mcp.md create mode 100644 docs/registry/attributes/mcp.md create mode 100644 model/mcp/common.yaml create mode 100644 model/mcp/metrics.yaml create mode 100644 model/mcp/registry.yaml create mode 100644 model/mcp/spans.yaml diff --git a/.chloggen/2083.yaml b/.chloggen/2083.yaml new file mode 100644 index 0000000000..e23949a527 --- /dev/null +++ b/.chloggen/2083.yaml @@ -0,0 +1,4 @@ +change_type: enhancement +component: mcp +note: Add MCP semantic conventions +issues: [2043, 2083] diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 636d070396..378f9d91ac 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -106,6 +106,7 @@ /docs/gen-ai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-genai-approvers /model/gen-ai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-genai-approvers /model/openai/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-genai-approvers +/model/mcp/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-genai-approvers # Security semantic conventions /docs/dns/ @open-telemetry/specs-semconv-approvers @open-telemetry/semconv-security-approvers diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index bc47e17aed..fc31c4b528 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -67,6 +67,7 @@ body: - area:k8s - area:log - area:mainframe + - area:mcp - area:messaging - area:network - area:nfs diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml index 22ae1f480c..d4566a074b 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -59,6 +59,7 @@ body: - area:k8s - area:log - area:mainframe + - area:mcp - area:messaging - area:network - area:nfs diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml index b5ba619910..9e5a3fd400 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -70,6 +70,7 @@ body: - area:k8s - area:log - area:mainframe + - area:mcp - area:messaging - area:network - area:nfs diff --git a/AREAS.md b/AREAS.md index 127c5bae73..f929bf739f 100644 --- a/AREAS.md +++ b/AREAS.md @@ -29,7 +29,7 @@ their owners, related project (and project board) as well as its current status. |------|--------|---------|-------|-------|--------|-------| | Semantic Conventions: System | [semconv-system-approvers](https://github.com/orgs/open-telemetry/teams/semconv-system-approvers) | https://github.com/open-telemetry/community/blob/main/projects/system-semconv.md | https://github.com/orgs/open-telemetry/projects/55 | `area:system`, `area:host`, `area:process`, `area:nfs`, `area:os`, `area:cpu`, `area:disk`, `area:network`, `area:linux` | `accepting_contributions`, `active` | The SIG is looking for contributions! | | Semantic Conventions: K8s | [semconv-k8s-approvers](https://github.com/orgs/open-telemetry/teams/semconv-k8s-approvers) | https://github.com/open-telemetry/community/blob/main/projects/k8s-semconv.md | https://github.com/orgs/open-telemetry/projects/114 | `area:k8s` | `accepting_contributions`, `active` | The SIG is looking for contributions! | -| Semantic Conventions: GenAI | [semconv-genai-approvers](https://github.com/orgs/open-telemetry/teams/semconv-genai-approvers) | https://github.com/open-telemetry/community/blob/main/projects/gen-ai.md | https://github.com/orgs/open-telemetry/projects/82 | `area:gen-ai`, `area:openai` | `accepting_contributions`, `active` | The SIG is looking for contributions! | +| Semantic Conventions: GenAI | [semconv-genai-approvers](https://github.com/orgs/open-telemetry/teams/semconv-genai-approvers) | https://github.com/open-telemetry/community/blob/main/projects/gen-ai.md | https://github.com/orgs/open-telemetry/projects/82 | `area:gen-ai`, `area:openai`, `area:mcp` | `accepting_contributions`, `active` | The SIG is looking for contributions! | | Semantic Conventions: CI/CD | [semconv-cicd-approvers](https://github.com/orgs/open-telemetry/teams/semconv-cicd-approvers) | https://github.com/open-telemetry/community/blob/main/projects/ci-cd.md | https://github.com/orgs/open-telemetry/projects/79 | `area:cicd`, `area:artifact`, `area:deployment`, `area:test`, `area:vcs` | `accepting_contributions`, `active` | The SIG is looking for contributions! | | Semantic Conventions: Security | [semconv-security-approvers](https://github.com/orgs/open-telemetry/teams/semconv-security-approvers) | https://github.com/open-telemetry/community/blob/main/projects/security-semconv.md | https://github.com/orgs/open-telemetry/projects/104 | `area:security`, `area:log`, `area:user` | `accepting_contributions`, `active` | The SIG is looking for contributions! | | Semantic Conventions: Browser Instrumentation | [semconv-browser-approvers](https://github.com/orgs/open-telemetry/teams/semconv-browser-approvers) | https://github.com/open-telemetry/community/blob/main/projects/browser-phase-1.md | https://github.com/orgs/open-telemetry/projects/146 | `area:browser` | `accepting_contributions`, `active` | The SIG is looking for contributions! | diff --git a/areas.yaml b/areas.yaml index d2055f5762..b665c4cc1b 100644 --- a/areas.yaml +++ b/areas.yaml @@ -40,6 +40,7 @@ areas: labels: - area:gen-ai - area:openai + - area:mcp status: - accepting_contributions - active diff --git a/docs/gen-ai/README.md b/docs/gen-ai/README.md index 0a0b588660..0f06cc7523 100644 --- a/docs/gen-ai/README.md +++ b/docs/gen-ai/README.md @@ -40,4 +40,8 @@ Technology specific semantic conventions are defined for the following GenAI sys * [OpenAI](./openai.md): Semantic Conventions for OpenAI. * [AWS Bedrock](./aws-bedrock.md): Semantic Conventions for AWS Bedrock. +See also + +* [Model Context Protocol](./mcp.md): Semantic Conventions for [MCP](https://modelcontextprotocol.io) + [DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md new file mode 100644 index 0000000000..d2520fd6f3 --- /dev/null +++ b/docs/gen-ai/mcp.md @@ -0,0 +1,753 @@ + + +# Semantic conventions for Model Context Protocol (MCP) + +**Status**: [Development][DocumentStatus] + + + +- [Spans](#spans) + - [Context propagation](#context-propagation) + - [Client](#client) + - [Server](#server) +- [Metrics](#metrics) + - [Metric: `mcp.client.operation.duration`](#metric-mcpclientoperationduration) + - [Metric: `mcp.server.operation.duration`](#metric-mcpserveroperationduration) + - [Metric: `mcp.client.session.duration`](#metric-mcpclientsessionduration) + - [Metric: `mcp.server.session.duration`](#metric-mcpserversessionduration) + + + +[Model Context Protocol](https://github.com/modelcontextprotocol/modelcontextprotocol) (MCP) is based on JSON RPC. + +When instrumenting MCP calls, it's RECOMMENDED to follow MCP conventions instead of [RPC semantic conventions](/docs/rpc/README.md) +since MCP spans and metrics provide domain-specific context and record details +that are not covered by the RPC conventions such as message exchange within streaming calls. + +HTTP conventions (when HTTP used as transport) do not adequately cover MCP requests +and notifications either, given that multiple MCP requests could be sent over single +HTTP request in the corresponding request and response streams. + +## Spans + +### Context propagation + +Model Context Protocol works on top of JSON RPC and does not define a standard +Trace Context propagation mechanism. It also works on top of different transports +including stdio and HTTP streams. + +HTTP trace context propagation only covers the HTTP request, but not the individual +messages client and server exchange within the request/response streams. + +Instrumentations SHOULD propagate trace context inside MCP request `params._meta` +property bag. + +> [!NOTE] +> The propagation format defined here is likely to change. Please check out +> context propagation discussions in MCP repository: +> [modelcontextprotocol#246](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/246) +> and +> [modelcontextprotocol#414](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/414). +> +> If the MCP or JSON-RPC specifications provide official guidance, instrumentations +> SHOULD prioritize that over the recommendation provided in this section. + +For example, when using [W3C Trace Context](https://www.w3.org/TR/trace-context/) propagation, +inject `traceparent` and `tracestate` to the MCP message `params._meta` when creating request +or notification and extract them on the receiver side to use as the remote parent. + +Here's an example of tool call request with injected trace context. + +```json +{ + "jsonrpc": "2.0", + "method": "tools/call", + "params": { + "name": "get-weather", + "_meta": { + "traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", + "tracestate": "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE" + } + }, + "id": 1, +} +``` + +Or, if user application uses [W3C Baggage](https://www.w3.org/TR/baggage/) in addition +to the Trace-Context, `baggage` should be propagated in the same `params._meta` +property bag similarly to the following example: + +```json +{ + "jsonrpc": "2.0", + "method": "tools/call", + "params": { + "name": "get-weather", + "_meta": { + "traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", + "baggage": "userId=alice,serverNode=DF%2028,isProduction=false" + } + }, + "id": 1, +} +``` + +### Client + + + + + + + + +**Status:** ![Development](https://img.shields.io/badge/-development-blue) + +This span describes the MCP call from the client side. + +It's reported by the MCP client when it initiates the request +or notification or by the MCP server when server initiates the operation. +It covers the time to receive the response or ack from the peer. + +**Span name** SHOULD follow the format `{mcp.method.name} {target}` +where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` +depending on the request or notification type. + +**Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` +attribute. The status description SHOULD match the `JSONRPCError.message` +if the message is available. + +Refer to the [Recording Errors](/docs/general/recording-errors.md) document +for more details. + +**Span kind** SHOULD be `CLIENT`. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | string | This is a unique identifier for the request. | `42` | `Conditionally Required` When the client executes a request. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Conditionally Required` [3] | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/registry/attributes/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/registry/attributes/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` When `server.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.request.argument.`](/docs/registry/attributes/mcp.md) | template[any] | Additional arguments passed to the request within `params` object. `` being the normalized argument name (lowercase), the value being the argument value. [7] | `Seattle, WA`; `42`; `{"foo": "bar"}` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | + +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +error code, if one is returned. + +When JSON RPC call is successful, but an error is returned within the +result payload, this attribute SHOULD be set to the low-cardinality +string representation of the error. When +[CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) +is returned with `isError` set to `true`, this attribute SHOULD be set to +`tool_error`. + +**[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +**[3] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. + +**[4] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. +It SHOULD be set to `pipe` if the transport is stdio. + +**[5] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[6] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[7] `mcp.request.argument.`:** Instrumentations SHOULD require an explicit configuration of which arguments +are to be captured. Including all request arguments can be a security risk - +explicit configuration helps avoid leaking sensitive information. + +Value type SHOULD match the value of the argument as passed in the request. + +Examples: + +- A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.request.argument.location` attribute with value `"Seattle, WA"`. +- A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. +- A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. + +When the attribute value SHOULD be recorded in structured form when it's possible +and MAY be recorded as a JSON string if structured format is not yet supported +by the OpenTelemetry implementation. + +--- + +`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +--- + +`mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | +| `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | +| `logging/setLevel` | Request to set the logging level. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/cancelled` | Notification cancelling a previously-issued request. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/initialized` | Notification indicating that the MCP client has been initialized. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/message` | Notification indicating that a message has been received. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/progress` | Notification indicating the progress for a long-running operation. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/prompts/list_changed` | Notification indicating that the list of prompts has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/list_changed` | Notification indicating that the list of resources has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/updated` | Notification indicating that a resource has been updated. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/roots/list_changed` | Notification indicating that the list of roots has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/tools/list_changed` | Notification indicating that the list of tools has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `ping` | Request to check that the other party is still alive. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/get` | Request to get a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/list` | Request to list prompts available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/list` | Request to list resources available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/list` | Request to list tools available on server. | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + +`network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + + + + + +### Server + + + + + + + + +**Status:** ![Development](https://img.shields.io/badge/-development-blue) + +This span describes the processing of the MCP request or notification initiated by the peer. + +It's reported by the MCP server when client initiates the request +(or notification) or by the MCP client when server initiates the operation. + +**Span name** SHOULD follow the format `{mcp.method.name} {target}` +where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` +depending on the request or notification type. + +**Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` +attribute. The status description SHOULD match the `JSONRPCError.message` +if the message is available. + +Refer to the [Recording Errors](/docs/general/recording-errors.md) document +for more details. + +**Span kind** SHOULD be `SERVER`. + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | string | This is a unique identifier for the request. | `42` | `Conditionally Required` When the client executes a request. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Conditionally Required` [3] | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`client.address`](/docs/registry/attributes/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`client.port`](/docs/registry/attributes/client.md) | int | Client port number. [5] | `65123` | `Recommended` When `client.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [6] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.request.argument.`](/docs/registry/attributes/mcp.md) | template[any] | Additional arguments passed to the request within `params` object. `` being the normalized argument name (lowercase), the value being the argument value. [7] | `Seattle, WA`; `42`; `{"foo": "bar"}` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | + +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +error code, if one is returned. + +When JSON RPC call is successful, but an error is returned within the +result payload, this attribute SHOULD be set to the low-cardinality +string representation of the error. When +[CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) +is returned with `isError` set to `true`, this attribute SHOULD be set to +`tool_error`. + +**[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +**[3] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. + +**[4] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. + +**[5] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. + +**[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. +It SHOULD be set to `pipe` if the transport is stdio. + +**[7] `mcp.request.argument.`:** Instrumentations SHOULD require an explicit configuration of which arguments +are to be captured. Including all request arguments can be a security risk - +explicit configuration helps avoid leaking sensitive information. + +Value type SHOULD match the value of the argument as passed in the request. + +Examples: + +- A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.request.argument.location` attribute with value `"Seattle, WA"`. +- A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. +- A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. + +When the attribute value SHOULD be recorded in structured form when it's possible +and MAY be recorded as a JSON string if structured format is not yet supported +by the OpenTelemetry implementation. + +--- + +`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +--- + +`mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | +| `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | +| `logging/setLevel` | Request to set the logging level. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/cancelled` | Notification cancelling a previously-issued request. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/initialized` | Notification indicating that the MCP client has been initialized. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/message` | Notification indicating that a message has been received. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/progress` | Notification indicating the progress for a long-running operation. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/prompts/list_changed` | Notification indicating that the list of prompts has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/list_changed` | Notification indicating that the list of resources has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/updated` | Notification indicating that a resource has been updated. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/roots/list_changed` | Notification indicating that the list of roots has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/tools/list_changed` | Notification indicating that the list of tools has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `ping` | Request to check that the other party is still alive. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/get` | Request to get a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/list` | Request to list prompts available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/list` | Request to list resources available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/list` | Request to list tools available on server. | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + +`network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + + + + + +## Metrics + +### Metric: `mcp.client.operation.duration` + +This metric is [recommended][MetricRecommended]. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| -------- | --------------- | ----------- | -------------- | --------- | ------ | +| `mcp.client.operation.duration` | Histogram | `s` | The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received. | ![Development](https://img.shields.io/badge/-development-blue) | | + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/registry/attributes/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/registry/attributes/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` When `server.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [5] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | + +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +error code, if one is returned. + +When JSON RPC call is successful, but an error is returned within the +result payload, this attribute SHOULD be set to the low-cardinality +string representation of the error. When +[CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) +is returned with `isError` set to `true`, this attribute SHOULD be set to +`tool_error`. + +**[2] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. +It SHOULD be set to `pipe` if the transport is stdio. + +**[3] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[5] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +--- + +`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +--- + +`mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | +| `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | +| `logging/setLevel` | Request to set the logging level. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/cancelled` | Notification cancelling a previously-issued request. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/initialized` | Notification indicating that the MCP client has been initialized. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/message` | Notification indicating that a message has been received. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/progress` | Notification indicating the progress for a long-running operation. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/prompts/list_changed` | Notification indicating that the list of prompts has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/list_changed` | Notification indicating that the list of resources has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/updated` | Notification indicating that a resource has been updated. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/roots/list_changed` | Notification indicating that the list of roots has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/tools/list_changed` | Notification indicating that the list of tools has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `ping` | Request to check that the other party is still alive. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/get` | Request to get a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/list` | Request to list prompts available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/list` | Request to list resources available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/list` | Request to list tools available on server. | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + +`network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + + + + + +### Metric: `mcp.server.operation.duration` + +This metric is [recommended][MetricRecommended]. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.43.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| -------- | --------------- | ----------- | -------------- | --------- | ------ | +| `mcp.server.operation.duration` | Histogram | `s` | MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent. | ![Development](https://img.shields.io/badge/-development-blue) | | + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | + +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +error code, if one is returned. + +When JSON RPC call is successful, but an error is returned within the +result payload, this attribute SHOULD be set to the low-cardinality +string representation of the error. When +[CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) +is returned with `isError` set to `true`, this attribute SHOULD be set to +`tool_error`. + +**[2] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. +It SHOULD be set to `pipe` if the transport is stdio. + +**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +--- + +`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +--- + +`mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | +| `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | +| `logging/setLevel` | Request to set the logging level. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/cancelled` | Notification cancelling a previously-issued request. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/initialized` | Notification indicating that the MCP client has been initialized. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/message` | Notification indicating that a message has been received. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/progress` | Notification indicating the progress for a long-running operation. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/prompts/list_changed` | Notification indicating that the list of prompts has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/list_changed` | Notification indicating that the list of resources has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/updated` | Notification indicating that a resource has been updated. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/roots/list_changed` | Notification indicating that the list of roots has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/tools/list_changed` | Notification indicating that the list of tools has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `ping` | Request to check that the other party is still alive. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/get` | Request to get a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/list` | Request to list prompts available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/list` | Request to list resources available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/list` | Request to list tools available on server. | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + +`network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + + + + + +### Metric: `mcp.client.session.duration` + +This metric is [recommended][MetricRecommended]. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| -------- | --------------- | ----------- | -------------- | --------- | ------ | +| `mcp.client.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | | + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if session ends with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/registry/attributes/network.md) | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.address`](/docs/registry/attributes/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`server.port`](/docs/registry/attributes/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` When `server.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +- Use a domain-specific attribute +- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[2] `network.transport`:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +**[3] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +--- + +`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +--- + +`network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + + + + + +### Metric: `mcp.server.session.duration` + +This metric is [recommended][MetricRecommended]. + +This metric SHOULD be specified with +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/metrics/api.md#instrument-advisory-parameters) +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. + + + + + + + + +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| -------- | --------------- | ----------- | -------------- | --------- | ------ | +| `mcp.server.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP server. | ![Development](https://img.shields.io/badge/-development-blue) | | + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if session ends with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`network.transport`](/docs/registry/attributes/network.md) | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +**[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +it's RECOMMENDED to: + +- Use a domain-specific attribute +- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. + +**[2] `network.transport`:** The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +--- + +`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + +--- + +`network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | + + + + + + +[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status +[MetricRecommended]: /docs/general/metric-requirement-level.md#recommended diff --git a/docs/registry/attributes/README.md b/docs/registry/attributes/README.md index a782d50540..54b24ffe4a 100644 --- a/docs/registry/attributes/README.md +++ b/docs/registry/attributes/README.md @@ -78,6 +78,7 @@ Currently, the following namespaces exist: - [Linux](linux.md) - [Log](log.md) - [Mainframe](mainframe.md) +- [MCP](mcp.md) - [Messaging](messaging.md) - [Network](network.md) - [NFS](nfs.md) diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md new file mode 100644 index 0000000000..31e511e5b1 --- /dev/null +++ b/docs/registry/attributes/mcp.md @@ -0,0 +1,70 @@ + + + +# MCP + +## MCP Attributes + +[Model Context Protocol (MCP)](https://spec.modelcontextprotocol.io) attributes + +| Attribute | Type | Description | Examples | Stability | +|---|---|---|---|---| +| `mcp.method.name` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.prompt.name` | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.request.argument.` | template[any] | Additional arguments passed to the request within `params` object. `` being the normalized argument name (lowercase), the value being the argument value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.request.id` | string | This is a unique identifier for the request. | `42` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.resource.uri` | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.session.id` | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.tool.name` | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | ![Development](https://img.shields.io/badge/-development-blue) | + +**[1] `mcp.request.argument.`:** Instrumentations SHOULD require an explicit configuration of which arguments +are to be captured. Including all request arguments can be a security risk - +explicit configuration helps avoid leaking sensitive information. + +Value type SHOULD match the value of the argument as passed in the request. + +Examples: + +- A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.request.argument.location` attribute with value `"Seattle, WA"`. +- A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. +- A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. + +When the attribute value SHOULD be recorded in structured form when it's possible +and MAY be recorded as a JSON string if structured format is not yet supported +by the OpenTelemetry implementation. + +**[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +--- + +`mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +|---|---|---| +| `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | +| `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | +| `logging/setLevel` | Request to set the logging level. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/cancelled` | Notification cancelling a previously-issued request. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/initialized` | Notification indicating that the MCP client has been initialized. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/message` | Notification indicating that a message has been received. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/progress` | Notification indicating the progress for a long-running operation. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/prompts/list_changed` | Notification indicating that the list of prompts has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/list_changed` | Notification indicating that the list of resources has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/resources/updated` | Notification indicating that a resource has been updated. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/roots/list_changed` | Notification indicating that the list of roots has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `notifications/tools/list_changed` | Notification indicating that the list of tools has changed. | ![Development](https://img.shields.io/badge/-development-blue) | +| `ping` | Request to check that the other party is still alive. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/get` | Request to get a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | +| `prompts/list` | Request to list prompts available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/list` | Request to list resources available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | +| `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | +| `tools/list` | Request to list tools available on server. | ![Development](https://img.shields.io/badge/-development-blue) | diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml new file mode 100644 index 0000000000..92e2140076 --- /dev/null +++ b/model/mcp/common.yaml @@ -0,0 +1,41 @@ +groups: + - id: mcp.common.attributes + type: attribute_group + brief: Common MCP attributes + attributes: + - ref: mcp.tool.name + requirement_level: + conditionally_required: When operation is related to a specific tool. + - ref: mcp.prompt.name + requirement_level: + conditionally_required: When operation is related to a specific prompt. + - ref: network.transport + brief: The transport protocol used for the MCP session. + note: | + This attribute SHOULD be set to `tcp` or `quic` if the transport protocol + is HTTP. + It SHOULD be set to `pipe` if the transport is stdio. + + - ref: error.type + requirement_level: + conditionally_required: If and only if the operation fails. + note: | + This attribute SHOULD be set to the string representation of the JSON RPC + error code, if one is returned. + + When JSON RPC call is successful, but an error is returned within the + result payload, this attribute SHOULD be set to the low-cardinality + string representation of the error. When + [CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) + is returned with `isError` set to `true`, this attribute SHOULD be set to + `tool_error`. + - ref: mcp.method.name + requirement_level: required + - ref: rpc.jsonrpc.error_code + requirement_level: + conditionally_required: If response contains an error code. + - ref: network.protocol.version + brief: The version of JSON RPC protocol used. + note: "" # overriding the default note + requirement_level: + recommended: when it's not `2.0`. diff --git a/model/mcp/metrics.yaml b/model/mcp/metrics.yaml new file mode 100644 index 0000000000..3682d12b03 --- /dev/null +++ b/model/mcp/metrics.yaml @@ -0,0 +1,67 @@ +groups: + - id: mcp.operation.metrics.attributes + type: attribute_group + brief: MCP request metrics attributes + extends: mcp.common.attributes + attributes: + - ref: mcp.resource.uri + requirement_level: opt_in + + - id: mcp.session.metrics.attributes + type: attribute_group + brief: MCP session metrics attributes + attributes: + - ref: network.transport + - ref: error.type + requirement_level: + conditionally_required: If and only if session ends with an error. + + - id: metric.mcp.client.operation.duration + type: metric + metric_name: mcp.client.operation.duration + brief: > + The duration of the MCP request or notification as observed on the sender + from the time it was sent until the response or ack is received. + unit: s + instrument: histogram + stability: development + extends: mcp.operation.metrics.attributes + attributes: + - ref: server.address + - ref: server.port + requirement_level: + recommended: When `server.address` is set + + - id: metric.mcp.server.operation.duration + type: metric + metric_name: mcp.server.operation.duration + brief: > + MCP request or notification duration as observed on the receiver + from the time it was received until the result or ack is sent. + unit: s + instrument: histogram + stability: development + extends: mcp.operation.metrics.attributes + + - id: metric.mcp.client.session.duration + type: metric + metric_name: mcp.client.session.duration + brief: The duration of the MCP session as observed on the MCP client. + unit: s + instrument: histogram + stability: development + extends: mcp.session.metrics.attributes + attributes: + - ref: server.address + - ref: server.port + requirement_level: + recommended: When `server.address` is set + + - id: metric.mcp.server.session.duration + type: metric + metric_name: mcp.server.session.duration + brief: The duration of the MCP session as observed on the MCP server. + unit: s + instrument: histogram + stability: development + extends: mcp.session.metrics.attributes diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml new file mode 100644 index 0000000000..309d2c02fa --- /dev/null +++ b/model/mcp/registry.yaml @@ -0,0 +1,193 @@ +groups: + - id: registry.mcp + type: attribute_group + brief: > + [Model Context Protocol (MCP)](https://spec.modelcontextprotocol.io) attributes + attributes: + - id: mcp.method.name + brief: The name of the request or notification method. + stability: development + type: + members: + - id: notifications_cancelled + value: notifications/cancelled + brief: > + Notification cancelling a previously-issued request. + stability: development + - id: initialize + value: initialize + brief: > + Request to initialize the MCP client. + stability: development + - id: notifications_initialized + value: notifications/initialized + brief: > + Notification indicating that the MCP client has been initialized. + stability: development + - id: notifications_progress + value: notifications/progress + brief: > + Notification indicating the progress for a long-running operation. + stability: development + - id: ping + value: ping + brief: > + Request to check that the other party is still alive. + stability: development + - id: resources_list + value: resources/list + brief: > + Request to list resources available on server. + stability: development + - id: resources_templates_list + value: resources/templates/list + brief: > + Request to list resource templates available on server. + stability: development + - id: resources_read + value: resources/read + brief: > + Request to read a resource. + stability: development + - id: notifications_resources_list_changed + value: notifications/resources/list_changed + brief: > + Notification indicating that the list of resources has changed. + stability: development + - id: resources_subscribe + value: resources/subscribe + brief: > + Request to subscribe to a resource. + stability: development + - id: resources_unsubscribe + value: resources/unsubscribe + brief: > + Request to unsubscribe from a resource updates. + stability: development + - id: notifications_resources_updated + value: notifications/resources/updated + brief: > + Notification indicating that a resource has been updated. + stability: development + - id: prompts_list + value: prompts/list + brief: > + Request to list prompts available on server. + stability: development + - id: prompts_get + value: prompts/get + brief: > + Request to get a prompt. + stability: development + - id: notifications_prompts_list_changed + value: notifications/prompts/list_changed + brief: > + Notification indicating that the list of prompts has changed. + stability: development + - id: tools_list + value: tools/list + brief: > + Request to list tools available on server. + stability: development + - id: tools_call + value: tools/call + brief: > + Request to call a tool. + stability: development + - id: notifications_tools_list_changed + value: notifications/tools/list_changed + brief: > + Notification indicating that the list of tools has changed. + stability: development + - id: logging_set_level + value: logging/setLevel + brief: > + Request to set the logging level. + stability: development + - id: notifications_message + value: notifications/message + brief: > + Notification indicating that a message has been received. + stability: development + - id: sampling_create_message + value: sampling/createMessage + brief: > + Request to create a sampling message. + stability: development + - id: completion_complete + value: completion/complete + brief: > + Request to complete a prompt. + stability: development + - id: roots_list + value: roots/list + brief: > + Request to list roots available on server. + stability: development + - id: notifications_roots_list_changed + value: notifications/roots/list_changed + brief: > + Notification indicating that the list of roots has changed. + stability: development + - id: elicitation_create + value: elicitation/create + brief: > + Request from the server to elicit additional information from the + user via the client + stability: development + - id: mcp.request.id + type: string + brief: > + This is a unique identifier for the request. + stability: development + examples: ["42"] + - id: mcp.session.id + type: string + brief: Identifies MCP session. + stability: development + examples: ["191c4850af6c49e08843a3f6c80e5046"] + - id: mcp.tool.name + # This is effectively the same as `gen_ai.tool.name`, but it's not clear + # which one of them should survive. MCP can be used outside of GenAI domain, + # and GenAI can be used without MCP. + type: string + brief: The name of the tool provided in the request. + stability: development + examples: ["get-weather", "execute_command"] + - id: mcp.prompt.name + type: string + brief: The name of the prompt or prompt template provided in the request or response. + stability: development + examples: ["analyze-code"] + - id: mcp.resource.uri + type: string + brief: The value of the resource uri. + note: > + This is a URI of the resource provided in the following requests or notifications: + `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + stability: development + examples: ["postgres://database/customers/schema", "file:///home/user/documents/report.pdf"] + - id: mcp.request.argument + type: template[any] + brief: Additional arguments passed to the request within `params` object. + `` being the normalized argument name (lowercase), the value being the argument value. + note: | + Instrumentations SHOULD require an explicit configuration of which arguments + are to be captured. Including all request arguments can be a security risk - + explicit configuration helps avoid leaking sensitive information. + + Value type SHOULD match the value of the argument as passed in the request. + + Examples: + + - A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.request.argument.location` attribute with value `"Seattle, WA"`. + - A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. + - A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. + + When the attribute value SHOULD be recorded in structured form when it's possible + and MAY be recorded as a JSON string if structured format is not yet supported + by the OpenTelemetry implementation. + stability: development + examples: ["Seattle, WA", '42', '{"foo": "bar"}'] diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml new file mode 100644 index 0000000000..6ae59c45e7 --- /dev/null +++ b/model/mcp/spans.yaml @@ -0,0 +1,70 @@ +groups: + - id: trace.mcp.common.attributes + type: attribute_group + extends: mcp.common.attributes + brief: MCP common span attributes + attributes: + - ref: mcp.session.id + - ref: mcp.resource.uri + requirement_level: + conditionally_required: When the client executes a request type that includes a resource URI parameter. + - ref: mcp.request.id + requirement_level: + conditionally_required: When the client executes a request. + - ref: mcp.request.argument + requirement_level: opt_in + + - id: span.mcp.client + type: span + span_kind: client + brief: This span describes the MCP call from the client side. + note: | + It's reported by the MCP client when it initiates the request + or notification or by the MCP server when server initiates the operation. + It covers the time to receive the response or ack from the peer. + + **Span name** SHOULD follow the format `{mcp.method.name} {target}` + where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` + depending on the request or notification type. + + **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` + attribute. The status description SHOULD match the `JSONRPCError.message` + if the message is available. + + Refer to the [Recording Errors](/docs/general/recording-errors.md) document + for more details. + stability: development + extends: trace.mcp.common.attributes + attributes: + - ref: server.address + - ref: server.port + requirement_level: + recommended: When `server.address` is set + + - id: span.mcp.server + type: span + span_kind: server + brief: This span describes the processing of the MCP request or notification + initiated by the peer. + note: | + It's reported by the MCP server when client initiates the request + (or notification) or by the MCP client when server initiates the operation. + + **Span name** SHOULD follow the format `{mcp.method.name} {target}` + where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` + depending on the request or notification type. + + **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` + attribute. The status description SHOULD match the `JSONRPCError.message` + if the message is available. + + Refer to the [Recording Errors](/docs/general/recording-errors.md) document + for more details. + stability: development + extends: trace.mcp.common.attributes + attributes: + - ref: client.address + requirement_level: recommended + - ref: client.port + requirement_level: + recommended: When `client.address` is set diff --git a/templates/registry/markdown/weaver.yaml b/templates/registry/markdown/weaver.yaml index f058d47c41..ae34bc2800 100644 --- a/templates/registry/markdown/weaver.yaml +++ b/templates/registry/markdown/weaver.yaml @@ -40,6 +40,7 @@ acronyms: - HTTP - iOS - JVM + - MCP - NFS - NodeJS - OCI From 4aaeb65d69ad2bca3fecd9c887cb8e0110b85073 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Sat, 25 Oct 2025 12:35:02 -0700 Subject: [PATCH 02/22] fix link --- docs/gen-ai/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index d2520fd6f3..08854c3ba1 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -495,7 +495,7 @@ It SHOULD be set to `pipe` if the transport is stdio. This metric is [recommended][MetricRecommended]. This metric SHOULD be specified with -[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.43.0/specification/metrics/api.md#instrument-advisory-parameters) +[`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/metrics/api.md#instrument-advisory-parameters) of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. From 5de1c3c54b8c85627429eb43e741ee8b2f5e4852 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Sat, 1 Nov 2025 19:29:20 -0700 Subject: [PATCH 03/22] Some of the review comments --- docs/gen-ai/mcp.md | 344 +++++++++++++++++++++++--------- docs/registry/attributes/mcp.md | 88 ++++++-- model/mcp/common.yaml | 18 +- model/mcp/registry.yaml | 85 ++++++-- model/mcp/spans.yaml | 30 ++- 5 files changed, 429 insertions(+), 136 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 08854c3ba1..f2284a30e5 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -112,8 +112,13 @@ or notification or by the MCP server when server initiates the operation. It covers the time to receive the response or ack from the peer. **Span name** SHOULD follow the format `{mcp.method.name} {target}` -where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` -depending on the request or notification type. +where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when +applicable. +If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. + +Instrumentation MAY provide optional configuration to include +`{mcp.resource.uri}` as `target` in the span name when applicable. But by default +it SHOULD NOT be included to avoid high cardinality span names. **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` attribute. The status description SHOULD match the `JSONRPCError.message` @@ -124,21 +129,27 @@ for more details. **Span kind** SHOULD be `CLIENT`. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +**Attributes:** + +| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | -| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | string | This is a unique identifier for the request. | `42` | `Conditionally Required` When the client executes a request. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Conditionally Required` [3] | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [4] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/registry/attributes/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/registry/attributes/server.md) | int | Server port number. [6] | `80`; `8080`; `443` | `Recommended` When `server.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.request.argument.`](/docs/registry/attributes/mcp.md) | template[any] | Additional arguments passed to the request within `params` object. `` being the normalized argument name (lowercase), the value being the argument value. [7] | `Seattle, WA`; `42`; `{"foo": "bar"}` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `amqp`; `http`; `mqtt` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `udp` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | +| [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | +| [`mcp.response.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC error code, if one is returned. @@ -150,33 +161,87 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. + +**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +**[4] `mcp.session.id`:** When the MCP request or notification is part of a session. -**[3] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[5] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. +If MCP is used over WebSocket, it SHOULD be set to `websocket`. +Other protocols MAY be used as well. -**[4] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[5] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[7] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + +**[8] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. + +**[9] `mcp.input.param.`:** Instrumentations SHOULD require an explicit configuration of which keys +are to be captured. Including all request or notifications parameters +can be a security risk - explicit configuration helps avoid leaking sensitive information. + +Value type SHOULD match the value of the parameter as passed in the request +or notification. + +Examples: + +In a params object with the following structure: + +```json +{ + "jsonrpc": "2.0", + "id": 12345, + "method": "some/method", + "params": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } +} + +- A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the + `mcp.input.param.location` attribute with string value `"Seattle, WA"`. +- A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` + attribute with integer (signed 64 bit) value `42`. +- A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. -**[6] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +The attribute value SHOULD be recorded in structured form when it's possible +and MAY be recorded as a JSON string if structured format is not yet supported +by the OpenTelemetry implementation. -**[7] `mcp.request.argument.`:** Instrumentations SHOULD require an explicit configuration of which arguments -are to be captured. Including all request arguments can be a security risk - -explicit configuration helps avoid leaking sensitive information. +**[10] `mcp.response.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, +as response result can contain sensitive information. -Value type SHOULD match the value of the argument as passed in the request. +Value type SHOULD match the value of the `result` object property as returned in the response. Examples: -- A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.request.argument.location` attribute with value `"Seattle, WA"`. -- A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. -- A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. +In a response with the following structure: -When the attribute value SHOULD be recorded in structured form when it's possible +```json +{ + "jsonrpc": "2.0", + "id": 12345, + "result": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } +} +``` + +- A `location` key with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.response.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + attribute with integer (signed 64 bit) value `42`. +- A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + +The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. @@ -254,8 +319,13 @@ It's reported by the MCP server when client initiates the request (or notification) or by the MCP client when server initiates the operation. **Span name** SHOULD follow the format `{mcp.method.name} {target}` -where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` -depending on the request or notification type. +where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when +applicable. +If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. + +Instrumentation MAY provide optional configuration to include +`{mcp.resource.uri}` as `target` in the span name when applicable. But by default +it SHOULD NOT be included to avoid high cardinality span names. **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` attribute. The status description SHOULD match the `JSONRPCError.message` @@ -266,21 +336,27 @@ for more details. **Span kind** SHOULD be `SERVER`. -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +**Attributes:** + +| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | -| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | string | This is a unique identifier for the request. | `42` | `Conditionally Required` When the client executes a request. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Conditionally Required` [3] | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`client.address`](/docs/registry/attributes/client.md) | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`client.port`](/docs/registry/attributes/client.md) | int | Client port number. [5] | `65123` | `Recommended` When `client.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | `Recommended` | ![Development](https://img.shields.io/badge/-development-blue) | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [6] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.request.argument.`](/docs/registry/attributes/mcp.md) | template[any] | Additional arguments passed to the request within `params` object. `` being the normalized argument name (lowercase), the value being the argument value. [7] | `Seattle, WA`; `42`; `{"foo": "bar"}` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `amqp`; `http`; `mqtt` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `udp` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | +| [`mcp.response.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC error code, if one is returned. @@ -292,33 +368,87 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. -**[3] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. **[4] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. **[5] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[6] `mcp.session.id`:** When the MCP request or notification is part of a session. + +**[7] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. +If MCP is used over WebSocket, it SHOULD be set to `websocket`. +Other protocols MAY be used as well. + +**[8] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[7] `mcp.request.argument.`:** Instrumentations SHOULD require an explicit configuration of which arguments -are to be captured. Including all request arguments can be a security risk - -explicit configuration helps avoid leaking sensitive information. +**[9] `mcp.input.param.`:** Instrumentations SHOULD require an explicit configuration of which keys +are to be captured. Including all request or notifications parameters +can be a security risk - explicit configuration helps avoid leaking sensitive information. -Value type SHOULD match the value of the argument as passed in the request. +Value type SHOULD match the value of the parameter as passed in the request +or notification. Examples: -- A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.request.argument.location` attribute with value `"Seattle, WA"`. -- A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. -- A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. +In a params object with the following structure: -When the attribute value SHOULD be recorded in structured form when it's possible +```json +{ + "jsonrpc": "2.0", + "id": 12345, + "method": "some/method", + "params": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } +} + +- A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the + `mcp.input.param.location` attribute with string value `"Seattle, WA"`. +- A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` + attribute with integer (signed 64 bit) value `42`. +- A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. + +The attribute value SHOULD be recorded in structured form when it's possible +and MAY be recorded as a JSON string if structured format is not yet supported +by the OpenTelemetry implementation. + +**[10] `mcp.response.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, +as response result can contain sensitive information. + +Value type SHOULD match the value of the `result` object property as returned in the response. + +Examples: + +In a response with the following structure: + +```json +{ + "jsonrpc": "2.0", + "id": 12345, + "result": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } +} +``` + +- A `location` key with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.response.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + attribute with integer (signed 64 bit) value `42`. +- A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + +The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. @@ -387,7 +517,7 @@ This metric is [recommended][MetricRecommended]. This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/metrics/api.md#instrument-advisory-parameters) -of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. @@ -400,18 +530,23 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `mcp.client.operation.duration` | Histogram | `s` | The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received. | ![Development](https://img.shields.io/badge/-development-blue) | | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +**Attributes:** + +| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | -| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/registry/attributes/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/registry/attributes/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` When `server.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [5] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `amqp`; `http`; `mqtt` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [6] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC error code, if one is returned. @@ -423,15 +558,19 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[2] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. +If MCP is used over WebSocket, it SHOULD be set to `websocket`. +Other protocols MAY be used as well. + +**[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[3] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[4] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[5] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[6] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- @@ -496,7 +635,7 @@ This metric is [recommended][MetricRecommended]. This metric SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.50.0/specification/metrics/api.md#instrument-advisory-parameters) -of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 ]`. +of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. @@ -509,16 +648,21 @@ of `[ 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 7.5, 10 | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `mcp.server.operation.duration` | Histogram | `s` | MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent. | ![Development](https://img.shields.io/badge/-development-blue) | | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +**Attributes:** + +| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | `Required` | ![Development](https://img.shields.io/badge/-development-blue) | -| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if the operation fails. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | `Conditionally Required` When operation is related to a specific prompt. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | `Conditionally Required` When operation is related to a specific tool. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | int | `error.code` property of response if it is an error response. | `-32700`; `100` | `Conditionally Required` If response contains an error code. | ![Development](https://img.shields.io/badge/-development-blue) | -| [`network.protocol.version`](/docs/registry/attributes/network.md) | string | The version of JSON RPC protocol used. | `1.1`; `2` | `Recommended` when it's not `2.0`. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/registry/attributes/network.md) | string | The transport protocol used for the MCP session. [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | `Opt-In` | ![Development](https://img.shields.io/badge/-development-blue) | +| [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `amqp`; `http`; `mqtt` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [4] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC error code, if one is returned. @@ -530,11 +674,15 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[2] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. +If MCP is used over WebSocket, it SHOULD be set to `websocket`. +Other protocols MAY be used as well. + +**[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[4] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- @@ -612,12 +760,14 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `mcp.client.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +**Attributes:** + +| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if session ends with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/registry/attributes/network.md) | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.address`](/docs/registry/attributes/server.md) | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`server.port`](/docs/registry/attributes/server.md) | int | Server port number. [4] | `80`; `8080`; `443` | `Recommended` When `server.address` is set | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [4] | `80`; `8080`; `443` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -693,10 +843,12 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | -------- | --------------- | ----------- | -------------- | --------- | ------ | | `mcp.server.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP server. | ![Development](https://img.shields.io/badge/-development-blue) | | -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +**Attributes:** + +| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| -| [`error.type`](/docs/registry/attributes/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` If and only if session ends with an error. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | -| [`network.transport`](/docs/registry/attributes/network.md) | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | +| [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 31e511e5b1..9086044b74 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -7,36 +7,88 @@ [Model Context Protocol (MCP)](https://spec.modelcontextprotocol.io) attributes -| Attribute | Type | Description | Examples | Stability | +**Attributes:** + +| Key | Stability | Value Type | Description | Example Values | |---|---|---|---|---| -| `mcp.method.name` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | ![Development](https://img.shields.io/badge/-development-blue) | -| `mcp.prompt.name` | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | ![Development](https://img.shields.io/badge/-development-blue) | -| `mcp.request.argument.` | template[any] | Additional arguments passed to the request within `params` object. `` being the normalized argument name (lowercase), the value being the argument value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | ![Development](https://img.shields.io/badge/-development-blue) | -| `mcp.request.id` | string | This is a unique identifier for the request. | `42` | ![Development](https://img.shields.io/badge/-development-blue) | -| `mcp.resource.uri` | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | ![Development](https://img.shields.io/badge/-development-blue) | -| `mcp.session.id` | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | ![Development](https://img.shields.io/badge/-development-blue) | -| `mcp.tool.name` | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | ![Development](https://img.shields.io/badge/-development-blue) | +| `mcp.input.param.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | +| `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | +| `mcp.prompt.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | +| `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| `mcp.response.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [3] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | +| `mcp.tool.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | -**[1] `mcp.request.argument.`:** Instrumentations SHOULD require an explicit configuration of which arguments -are to be captured. Including all request arguments can be a security risk - -explicit configuration helps avoid leaking sensitive information. +**[1] `mcp.input.param.`:** Instrumentations SHOULD require an explicit configuration of which keys +are to be captured. Including all request or notifications parameters +can be a security risk - explicit configuration helps avoid leaking sensitive information. -Value type SHOULD match the value of the argument as passed in the request. +Value type SHOULD match the value of the parameter as passed in the request +or notification. Examples: -- A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.request.argument.location` attribute with value `"Seattle, WA"`. -- A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. -- A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. +In a params object with the following structure: + +```json +{ + "jsonrpc": "2.0", + "id": 12345, + "method": "some/method", + "params": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } +} -When the attribute value SHOULD be recorded in structured form when it's possible +- A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the + `mcp.input.param.location` attribute with string value `"Seattle, WA"`. +- A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` + attribute with integer (signed 64 bit) value `42`. +- A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. + +The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. **[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[3] `mcp.response.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, +as response result can contain sensitive information. + +Value type SHOULD match the value of the `result` object property as returned in the response. + +Examples: + +In a response with the following structure: + +```json +{ + "jsonrpc": "2.0", + "id": 12345, + "result": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } +} +``` + +- A `location` key with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.response.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + attribute with integer (signed 64 bit) value `42`. +- A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + +The attribute value SHOULD be recorded in structured form when it's possible +and MAY be recorded as a JSON string if structured format is not yet supported +by the OpenTelemetry implementation. + --- `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index 92e2140076..5e2bdcc8de 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -15,7 +15,6 @@ groups: This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. - - ref: error.type requirement_level: conditionally_required: If and only if the operation fails. @@ -31,11 +30,24 @@ groups: `tool_error`. - ref: mcp.method.name requirement_level: required - - ref: rpc.jsonrpc.error_code + - ref: mcp.protocol.version + requirement_level: recommended + - ref: rpc.jsonrpc.error_code # todo: this is being unified in https://github.com/open-telemetry/semantic-conventions/pull/2920 requirement_level: conditionally_required: If response contains an error code. + - ref: network.protocol.name + note: | + When MCP is used over HTTP, this attribute SHOULD be set to `http`. + If MCP is used over WebSocket, it SHOULD be set to `websocket`. + Other protocols MAY be used as well. + requirement_level: + recommended: When applicable. - ref: network.protocol.version + note: "" # overriding the default note + requirement_level: + recommended: When applicable. + - ref: rpc.jsonrpc.version brief: The version of JSON RPC protocol used. note: "" # overriding the default note requirement_level: - recommended: when it's not `2.0`. + recommended: when it's not `2.0`. \ No newline at end of file diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 309d2c02fa..91f6796666 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -167,27 +167,86 @@ groups: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. stability: development examples: ["postgres://database/customers/schema", "file:///home/user/documents/report.pdf"] - - id: mcp.request.argument + - id: mcp.input.param type: template[any] - brief: Additional arguments passed to the request within `params` object. - `` being the normalized argument name (lowercase), the value being the argument value. + brief: Parameters passed to the request within `params` object. + `` being the normalized parameter key (lowercase), the value being the parameter value. note: | - Instrumentations SHOULD require an explicit configuration of which arguments - are to be captured. Including all request arguments can be a security risk - - explicit configuration helps avoid leaking sensitive information. + Instrumentations SHOULD require an explicit configuration of which keys + are to be captured. Including all request or notifications parameters + can be a security risk - explicit configuration helps avoid leaking sensitive information. - Value type SHOULD match the value of the argument as passed in the request. + Value type SHOULD match the value of the parameter as passed in the request + or notification. Examples: - - A `param.location` argument with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.request.argument.location` attribute with value `"Seattle, WA"`. - - A `param.a` argument with value `42` SHOULD be recorded as the `mcp.request.argument.a` attribute with value `42`. - - A `param.complex` argument with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.request.argument.complex` attribute with complex value type `{"foo": "bar"}`. + In a params object with the following structure: - When the attribute value SHOULD be recorded in structured form when it's possible + ```json + { + "jsonrpc": "2.0", + "id": 12345, + "method": "some/method", + "params": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } + } + + - A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the + `mcp.input.param.location` attribute with string value `"Seattle, WA"`. + - A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` + attribute with integer (signed 64 bit) value `42`. + - A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. + + The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. stability: development examples: ["Seattle, WA", '42', '{"foo": "bar"}'] + - id: mcp.response.result + type: template[any] + brief: Result property returned in the response. + `` being the normalized result key (lowercase), the value being the result value. + note: | + Instrumentations SHOULD require an explicit configuration to capture this attribute, + as response result can contain sensitive information. + + Value type SHOULD match the value of the `result` object property as returned in the response. + + Examples: + + In a response with the following structure: + + ```json + { + "jsonrpc": "2.0", + "id": 12345, + "result": { + "location": "Seattle, WA", + "a": 42, + "complex": {"foo": "bar"} + } + } + ``` + + - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the + `mcp.response.result.location` attribute with string value `"Seattle, WA"`. + - A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + attribute with integer (signed 64 bit) value `42`. + - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the + `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + + The attribute value SHOULD be recorded in structured form when it's possible + and MAY be recorded as a JSON string if structured format is not yet supported + by the OpenTelemetry implementation. + stability: development + examples: ['{"output": "The weather is sunny."}', '42', '{"data": {"id": 1, "name": "Alice"}}'] + - id: mcp.protocol.version + type: string + brief: The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. + stability: development + examples: ["2025-06-18"] \ No newline at end of file diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index 6ae59c45e7..3c7084d933 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -5,13 +5,17 @@ groups: brief: MCP common span attributes attributes: - ref: mcp.session.id + requirement_level: + recommended: When the MCP request or notification is part of a session. - ref: mcp.resource.uri requirement_level: conditionally_required: When the client executes a request type that includes a resource URI parameter. - ref: mcp.request.id requirement_level: conditionally_required: When the client executes a request. - - ref: mcp.request.argument + - ref: mcp.input.param + requirement_level: opt_in + - ref: mcp.response.result requirement_level: opt_in - id: span.mcp.client @@ -24,8 +28,13 @@ groups: It covers the time to receive the response or ack from the peer. **Span name** SHOULD follow the format `{mcp.method.name} {target}` - where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` - depending on the request or notification type. + where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when + applicable. + If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. + + Instrumentation MAY provide optional configuration to include + `{mcp.resource.uri}` as `target` in the span name when applicable. But by default + it SHOULD NOT be included to avoid high cardinality span names. **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` attribute. The status description SHOULD match the `JSONRPCError.message` @@ -37,6 +46,8 @@ groups: extends: trace.mcp.common.attributes attributes: - ref: server.address + requirement_level: + recommended: If applicable - ref: server.port requirement_level: recommended: When `server.address` is set @@ -51,8 +62,13 @@ groups: (or notification) or by the MCP client when server initiates the operation. **Span name** SHOULD follow the format `{mcp.method.name} {target}` - where target is the `{mcp.tool.name}`, `{mcp.prompt.name}` or `{mcp.resource.uri}` - depending on the request or notification type. + where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when + applicable. + If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. + + Instrumentation MAY provide optional configuration to include + `{mcp.resource.uri}` as `target` in the span name when applicable. But by default + it SHOULD NOT be included to avoid high cardinality span names. **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` attribute. The status description SHOULD match the `JSONRPCError.message` @@ -64,7 +80,9 @@ groups: extends: trace.mcp.common.attributes attributes: - ref: client.address - requirement_level: recommended + requirement_level: + recommended: If applicable + - ref: client.port requirement_level: recommended: When `client.address` is set From cfcf1c108075009788dbde710f474a9c546b4e54 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Sun, 2 Nov 2025 10:11:30 -0800 Subject: [PATCH 04/22] address some of the comments --- docs/gen-ai/mcp.md | 121 ++++++++++++++++---------------- docs/registry/attributes/mcp.md | 3 +- model/mcp/common.yaml | 14 ++-- model/mcp/metrics.yaml | 24 +++++++ model/mcp/registry.yaml | 3 +- model/mcp/spans.yaml | 22 +++--- 6 files changed, 103 insertions(+), 84 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index f2284a30e5..7f209ba76a 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -34,9 +34,8 @@ HTTP request in the corresponding request and response streams. ### Context propagation -Model Context Protocol works on top of JSON RPC and does not define a standard -Trace Context propagation mechanism. It also works on top of different transports -including stdio and HTTP streams. +Model Context Protocol works on top of JSON-RPC and does not define a standard +Trace Context propagation mechanism. MCP is transport independent and works across different transports. The specification expects clients to implement at least stdio or HTTP streams. HTTP trace context propagation only covers the HTTP request, but not the individual messages client and server exchange within the request/response streams. @@ -116,13 +115,12 @@ where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. -Instrumentation MAY provide optional configuration to include -`{mcp.resource.uri}` as `target` in the span name when applicable. But by default -it SHOULD NOT be included to avoid high cardinality span names. +Instrumentation MAY allow users to opt into including `{mcp.resource.uri}` +as `target` in the span name when it is available but SHOULD NOT include it by default +to avoid high cardinality span names. -**Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` -attribute. The status description SHOULD match the `JSONRPCError.message` -if the message is available. +**Span status** SHOULD be set to `ERROR` when `error.type` attribute is present. +The status description SHOULD match the `JSONRPCError.message` if the message is available. Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. @@ -140,21 +138,21 @@ for more details. | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `amqp`; `http`; `mqtt` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `udp` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | | [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | | [`mcp.response.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | -**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. -When JSON RPC call is successful, but an error is returned within the +When JSON-RPC call is successful, but an error is returned within the result payload, this attribute SHOULD be set to the low-cardinality string representation of the error. When [CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) @@ -167,9 +165,7 @@ is returned with `isError` set to `true`, this attribute SHOULD be set to **[4] `mcp.session.id`:** When the MCP request or notification is part of a session. -**[5] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. -If MCP is used over WebSocket, it SHOULD be set to `websocket`. -Other protocols MAY be used as well. +**[5] `network.protocol.name`:** The value SHOULD be normalized to lowercase. **[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. @@ -201,6 +197,7 @@ In a params object with the following structure: "complex": {"foo": "bar"} } } +``` - A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the `mcp.input.param.location` attribute with string value `"Seattle, WA"`. @@ -323,13 +320,12 @@ where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. -Instrumentation MAY provide optional configuration to include -`{mcp.resource.uri}` as `target` in the span name when applicable. But by default -it SHOULD NOT be included to avoid high cardinality span names. +Instrumentation MAY allow users to opt into including `{mcp.resource.uri}` +as `target` in the span name when it is available but SHOULD NOT include it by default +to avoid high cardinality span names. -**Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` -attribute. The status description SHOULD match the `JSONRPCError.message` -if the message is available. +**Span status** SHOULD be set to `ERROR` when `error.type` attribute is present. +The status description SHOULD match the `JSONRPCError.message` if the message is available. Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. @@ -349,19 +345,19 @@ for more details. | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | | [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | -| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `amqp`; `http`; `mqtt` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `udp` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | | [`mcp.response.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | -**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. -When JSON RPC call is successful, but an error is returned within the +When JSON-RPC call is successful, but an error is returned within the result payload, this attribute SHOULD be set to the low-cardinality string representation of the error. When [CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) @@ -378,9 +374,7 @@ is returned with `isError` set to `true`, this attribute SHOULD be set to **[6] `mcp.session.id`:** When the MCP request or notification is part of a session. -**[7] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. -If MCP is used over WebSocket, it SHOULD be set to `websocket`. -Other protocols MAY be used as well. +**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. **[8] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. @@ -408,6 +402,7 @@ In a params object with the following structure: "complex": {"foo": "bar"} } } +``` - A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the `mcp.input.param.location` attribute with string value `"Seattle, WA"`. @@ -539,28 +534,26 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `amqp`; `http`; `mqtt` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [6] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. -When JSON RPC call is successful, but an error is returned within the +When JSON-RPC call is successful, but an error is returned within the result payload, this attribute SHOULD be set to the low-cardinality string representation of the error. When [CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. -If MCP is used over WebSocket, it SHOULD be set to `websocket`. -Other protocols MAY be used as well. +**[2] `network.protocol.name`:** The value SHOULD be normalized to lowercase. **[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. @@ -657,26 +650,24 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `amqp`; `http`; `mqtt` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [4] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON RPC +**[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. -When JSON RPC call is successful, but an error is returned within the +When JSON-RPC call is successful, but an error is returned within the result payload, this attribute SHOULD be set to the low-cardinality string representation of the error. When [CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `network.protocol.name`:** When MCP is used over HTTP, this attribute SHOULD be set to `http`. -If MCP is used over WebSocket, it SHOULD be set to `websocket`. -Other protocols MAY be used as well. +**[2] `network.protocol.name`:** The value SHOULD be normalized to lowercase. **[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. @@ -765,9 +756,13 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [3] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [4] | `80`; `8080`; `443` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -789,15 +784,14 @@ it's RECOMMENDED to: - Use a domain-specific attribute - Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -**[2] `network.transport`:** The value SHOULD be normalized to lowercase. +**[2] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport. For example -different processes could be listening on TCP port 12345 and UDP port 12345. +**[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[3] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[4] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[4] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. --- @@ -848,7 +842,11 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | |---|---|---|---|---|---| | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | [OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). [2] | `tcp`; `udp` | +| [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | +| [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -870,11 +868,10 @@ it's RECOMMENDED to: - Use a domain-specific attribute - Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -**[2] `network.transport`:** The value SHOULD be normalized to lowercase. +**[2] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport. For example -different processes could be listening on TCP port 12345 and UDP port 12345. +**[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. It SHOULD be set to `pipe` if the transport is stdio. --- diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 9086044b74..2cff9dbb97 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -14,7 +14,7 @@ | `mcp.input.param.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | | `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | `mcp.prompt.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. | `2025-06-18` | +| `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | | `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | `mcp.response.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [3] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | @@ -43,6 +43,7 @@ In a params object with the following structure: "complex": {"foo": "bar"} } } +``` - A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the `mcp.input.param.location` attribute with string value `"Seattle, WA"`. diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index 5e2bdcc8de..96ff2277b2 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -19,10 +19,10 @@ groups: requirement_level: conditionally_required: If and only if the operation fails. note: | - This attribute SHOULD be set to the string representation of the JSON RPC + This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. - When JSON RPC call is successful, but an error is returned within the + When JSON-RPC call is successful, but an error is returned within the result payload, this attribute SHOULD be set to the low-cardinality string representation of the error. When [CallToolResult](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/9c8a44e47e16b789a1f9d47c89ea23ed13a37cf9/schema/2025-06-18/schema.ts#L715) @@ -31,23 +31,21 @@ groups: - ref: mcp.method.name requirement_level: required - ref: mcp.protocol.version - requirement_level: recommended - ref: rpc.jsonrpc.error_code # todo: this is being unified in https://github.com/open-telemetry/semantic-conventions/pull/2920 requirement_level: conditionally_required: If response contains an error code. - ref: network.protocol.name - note: | - When MCP is used over HTTP, this attribute SHOULD be set to `http`. - If MCP is used over WebSocket, it SHOULD be set to `websocket`. - Other protocols MAY be used as well. requirement_level: recommended: When applicable. + examples: + - "http" + - "websocket" - ref: network.protocol.version note: "" # overriding the default note requirement_level: recommended: When applicable. - ref: rpc.jsonrpc.version - brief: The version of JSON RPC protocol used. + brief: The version of JSON-RPC protocol used. note: "" # overriding the default note requirement_level: recommended: when it's not `2.0`. \ No newline at end of file diff --git a/model/mcp/metrics.yaml b/model/mcp/metrics.yaml index 3682d12b03..35eb0fb732 100644 --- a/model/mcp/metrics.yaml +++ b/model/mcp/metrics.yaml @@ -11,7 +11,27 @@ groups: type: attribute_group brief: MCP session metrics attributes attributes: + - ref: mcp.protocol.version + - ref: network.protocol.name + requirement_level: + recommended: When applicable. + examples: + - "http" + - "websocket" + - ref: network.protocol.version + note: "" # overriding the default note + requirement_level: + recommended: When applicable. + - ref: rpc.jsonrpc.version + brief: The version of JSON-RPC protocol used. + note: "" # overriding the default note + requirement_level: + recommended: when it's not `2.0`. - ref: network.transport + brief: The transport protocol used for the MCP session. + note: | + This attribute SHOULD be set to `tcp` or `quic` if the transport protocol + is HTTP. It SHOULD be set to `pipe` if the transport is stdio. - ref: error.type requirement_level: conditionally_required: If and only if session ends with an error. @@ -28,6 +48,8 @@ groups: extends: mcp.operation.metrics.attributes attributes: - ref: server.address + requirement_level: + recommended: If applicable - ref: server.port requirement_level: recommended: When `server.address` is set @@ -53,6 +75,8 @@ groups: extends: mcp.session.metrics.attributes attributes: - ref: server.address + requirement_level: + recommended: If applicable - ref: server.port requirement_level: recommended: When `server.address` is set diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 91f6796666..ee11fba0af 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -194,6 +194,7 @@ groups: "complex": {"foo": "bar"} } } + ``` - A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the `mcp.input.param.location` attribute with string value `"Seattle, WA"`. @@ -247,6 +248,6 @@ groups: examples: ['{"output": "The weather is sunny."}', '42', '{"data": {"id": 1, "name": "Alice"}}'] - id: mcp.protocol.version type: string - brief: The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol (MCP) used. + brief: The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. stability: development examples: ["2025-06-18"] \ No newline at end of file diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index 3c7084d933..40917e95dd 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -32,13 +32,12 @@ groups: applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. - Instrumentation MAY provide optional configuration to include - `{mcp.resource.uri}` as `target` in the span name when applicable. But by default - it SHOULD NOT be included to avoid high cardinality span names. + Instrumentation MAY allow users to opt into including `{mcp.resource.uri}` + as `target` in the span name when it is available but SHOULD NOT include it by default + to avoid high cardinality span names. - **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` - attribute. The status description SHOULD match the `JSONRPCError.message` - if the message is available. + **Span status** SHOULD be set to `ERROR` when `error.type` attribute is present. + The status description SHOULD match the `JSONRPCError.message` if the message is available. Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. @@ -66,13 +65,12 @@ groups: applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. - Instrumentation MAY provide optional configuration to include - `{mcp.resource.uri}` as `target` in the span name when applicable. But by default - it SHOULD NOT be included to avoid high cardinality span names. + Instrumentation MAY allow users to opt into including `{mcp.resource.uri}` + as `target` in the span name when it is available but SHOULD NOT include it by default + to avoid high cardinality span names. - **Span status** SHOULD be set to `ERROR` using the same condition as the `error.type` - attribute. The status description SHOULD match the `JSONRPCError.message` - if the message is available. + **Span status** SHOULD be set to `ERROR` when `error.type` attribute is present. + The status description SHOULD match the `JSONRPCError.message` if the message is available. Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. From 9e8d1b021156de45637e905fdd73000181096216 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Mon, 3 Nov 2025 15:02:45 -0800 Subject: [PATCH 05/22] mcp.response.result -> mcp.result, better examples for network.transport --- docs/gen-ai/mcp.md | 32 ++++++++++++++++---------------- docs/registry/attributes/mcp.md | 10 +++++----- model/mcp/common.yaml | 1 + model/mcp/metrics.yaml | 1 + model/mcp/registry.yaml | 8 ++++---- model/mcp/spans.yaml | 2 +- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 7f209ba76a..77a13fdc2b 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -142,12 +142,12 @@ for more details. | [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `udp` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | | [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | -| [`mcp.response.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| [`mcp.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -210,7 +210,7 @@ The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. -**[10] `mcp.response.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, +**[10] `mcp.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. @@ -232,11 +232,11 @@ In a response with the following structure: ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.response.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + `mcp.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported @@ -349,10 +349,10 @@ for more details. | [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `udp` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | -| [`mcp.response.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| [`mcp.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -415,7 +415,7 @@ The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. -**[10] `mcp.response.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, +**[10] `mcp.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. @@ -437,11 +437,11 @@ In a response with the following structure: ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.response.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + `mcp.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported @@ -537,7 +537,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | @@ -653,7 +653,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [4] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | @@ -759,7 +759,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | @@ -845,7 +845,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `udp` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 2cff9dbb97..a6fc913aab 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -17,7 +17,7 @@ | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | | `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| `mcp.response.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [3] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| `mcp.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [3] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | | `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | | `mcp.tool.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | @@ -58,7 +58,7 @@ by the OpenTelemetry implementation. **[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. -**[3] `mcp.response.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, +**[3] `mcp.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. @@ -80,11 +80,11 @@ In a response with the following structure: ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.response.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + `mcp.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index 96ff2277b2..db121a8a4a 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -15,6 +15,7 @@ groups: This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. + examples: ["tcp", "quic", "pipe"] - ref: error.type requirement_level: conditionally_required: If and only if the operation fails. diff --git a/model/mcp/metrics.yaml b/model/mcp/metrics.yaml index 35eb0fb732..e1e1f82f50 100644 --- a/model/mcp/metrics.yaml +++ b/model/mcp/metrics.yaml @@ -32,6 +32,7 @@ groups: note: | This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. + examples: ["tcp", "quic", "pipe"] - ref: error.type requirement_level: conditionally_required: If and only if session ends with an error. diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index ee11fba0af..20f87191c9 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -208,7 +208,7 @@ groups: by the OpenTelemetry implementation. stability: development examples: ["Seattle, WA", '42', '{"foo": "bar"}'] - - id: mcp.response.result + - id: mcp.result type: template[any] brief: Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. @@ -235,11 +235,11 @@ groups: ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.response.result.location` attribute with string value `"Seattle, WA"`. - - A `a` key with value `42` SHOULD be recorded as the `mcp.response.result.a` + `mcp.result.location` attribute with string value `"Seattle, WA"`. + - A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.response.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index 40917e95dd..a0434b173f 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -15,7 +15,7 @@ groups: conditionally_required: When the client executes a request. - ref: mcp.input.param requirement_level: opt_in - - ref: mcp.response.result + - ref: mcp.result requirement_level: opt_in - id: span.mcp.client From 0ffe9c29cbed268e93149f6b16a461f58c02b734 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Fri, 7 Nov 2025 17:59:17 -0800 Subject: [PATCH 06/22] review: output params and _meta params --- docs/gen-ai/mcp.md | 88 +++++++++++++++++++++++++++------ docs/registry/attributes/mcp.md | 48 ++++++++++++++---- model/mcp/registry.yaml | 44 ++++++++++++++--- model/mcp/spans.yaml | 2 +- 4 files changed, 147 insertions(+), 35 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 77a13fdc2b..f5ad52c365 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -147,7 +147,7 @@ for more details. | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | | [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | -| [`mcp.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| [`mcp.output.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -175,13 +175,19 @@ It SHOULD be set to `pipe` if the transport is stdio. **[8] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[9] `mcp.input.param.`:** Instrumentations SHOULD require an explicit configuration of which keys +**[9] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed +to the request or notification within `params` object. + +Instrumentations that support it SHOULD require an explicit configuration of which keys are to be captured. Including all request or notifications parameters can be a security risk - explicit configuration helps avoid leaking sensitive information. Value type SHOULD match the value of the parameter as passed in the request or notification. +Instrumentation SHOULD allow capturing parameters passed with MCP's +reserved `_meta` key. + Examples: In a params object with the following structure: @@ -195,6 +201,9 @@ In a params object with the following structure: "location": "Seattle, WA", "a": 42, "complex": {"foo": "bar"} + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` @@ -205,16 +214,27 @@ In a params object with the following structure: attribute with integer (signed 64 bit) value `42`. - A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. +- A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. -**[10] `mcp.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, -as response result can contain sensitive information. +Keys SHOULD be captured as they appear in the request or notification +without any additional normalization. + +**[10] `mcp.output.result.`:** Instrumentations MAY support capturing properties returned +to the response within `result` object. + +Instrumentations that support it SHOULD require an explicit configuration +to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. +Instrumentation SHOULD allow capturing result properties passed with MCP's +reserved `_meta` key. + Examples: In a response with the following structure: @@ -226,22 +246,30 @@ In a response with the following structure: "result": { "location": "Seattle, WA", "a": 42, - "complex": {"foo": "bar"} + "complex": {"foo": "bar"}, + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` + `mcp.output.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. +- A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. +Keys SHOULD be captured as they appear in the result without any +additional normalization. + --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. @@ -352,7 +380,7 @@ for more details. | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | -| [`mcp.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| [`mcp.output.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -380,13 +408,19 @@ is returned with `isError` set to `true`, this attribute SHOULD be set to is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[9] `mcp.input.param.`:** Instrumentations SHOULD require an explicit configuration of which keys +**[9] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed +to the request or notification within `params` object. + +Instrumentations that support it SHOULD require an explicit configuration of which keys are to be captured. Including all request or notifications parameters can be a security risk - explicit configuration helps avoid leaking sensitive information. Value type SHOULD match the value of the parameter as passed in the request or notification. +Instrumentation SHOULD allow capturing parameters passed with MCP's +reserved `_meta` key. + Examples: In a params object with the following structure: @@ -400,6 +434,9 @@ In a params object with the following structure: "location": "Seattle, WA", "a": 42, "complex": {"foo": "bar"} + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` @@ -410,16 +447,27 @@ In a params object with the following structure: attribute with integer (signed 64 bit) value `42`. - A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. +- A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. -**[10] `mcp.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, -as response result can contain sensitive information. +Keys SHOULD be captured as they appear in the request or notification +without any additional normalization. + +**[10] `mcp.output.result.`:** Instrumentations MAY support capturing properties returned +to the response within `result` object. + +Instrumentations that support it SHOULD require an explicit configuration +to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. +Instrumentation SHOULD allow capturing result properties passed with MCP's +reserved `_meta` key. + Examples: In a response with the following structure: @@ -431,22 +479,30 @@ In a response with the following structure: "result": { "location": "Seattle, WA", "a": 42, - "complex": {"foo": "bar"} + "complex": {"foo": "bar"}, + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` + `mcp.output.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. +- A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. +Keys SHOULD be captured as they appear in the result without any +additional normalization. + --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index a6fc913aab..22641e438e 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -13,21 +13,27 @@ |---|---|---|---|---| | `mcp.input.param.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | | `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | +| `mcp.output.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [2] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | | `mcp.prompt.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | -| `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [2] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| `mcp.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [3] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | +| `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | | `mcp.tool.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | -**[1] `mcp.input.param.`:** Instrumentations SHOULD require an explicit configuration of which keys +**[1] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed +to the request or notification within `params` object. + +Instrumentations that support it SHOULD require an explicit configuration of which keys are to be captured. Including all request or notifications parameters can be a security risk - explicit configuration helps avoid leaking sensitive information. Value type SHOULD match the value of the parameter as passed in the request or notification. +Instrumentation SHOULD allow capturing parameters passed with MCP's +reserved `_meta` key. + Examples: In a params object with the following structure: @@ -41,6 +47,9 @@ In a params object with the following structure: "location": "Seattle, WA", "a": 42, "complex": {"foo": "bar"} + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` @@ -51,18 +60,27 @@ In a params object with the following structure: attribute with integer (signed 64 bit) value `42`. - A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. +- A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. -**[2] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +Keys SHOULD be captured as they appear in the request or notification +without any additional normalization. -**[3] `mcp.result.`:** Instrumentations SHOULD require an explicit configuration to capture this attribute, -as response result can contain sensitive information. +**[2] `mcp.output.result.`:** Instrumentations MAY support capturing properties returned +to the response within `result` object. + +Instrumentations that support it SHOULD require an explicit configuration +to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. +Instrumentation SHOULD allow capturing result properties passed with MCP's +reserved `_meta` key. + Examples: In a response with the following structure: @@ -74,22 +92,32 @@ In a response with the following structure: "result": { "location": "Seattle, WA", "a": 42, - "complex": {"foo": "bar"} + "complex": {"foo": "bar"}, + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` + `mcp.output.result.location` attribute with string value `"Seattle, WA"`. +- A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. +- A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. +Keys SHOULD be captured as they appear in the result without any +additional normalization. + +**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + --- `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 20f87191c9..72e201956f 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -172,13 +172,19 @@ groups: brief: Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. note: | - Instrumentations SHOULD require an explicit configuration of which keys + Instrumentations MAY support capturing input parameters passed + to the request or notification within `params` object. + + Instrumentations that support it SHOULD require an explicit configuration of which keys are to be captured. Including all request or notifications parameters can be a security risk - explicit configuration helps avoid leaking sensitive information. Value type SHOULD match the value of the parameter as passed in the request or notification. + Instrumentation SHOULD allow capturing parameters passed with MCP's + reserved `_meta` key. + Examples: In a params object with the following structure: @@ -192,6 +198,9 @@ groups: "location": "Seattle, WA", "a": 42, "complex": {"foo": "bar"} + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` @@ -202,22 +211,33 @@ groups: attribute with integer (signed 64 bit) value `42`. - A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. + - A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. + + Keys SHOULD be captured as they appear in the request or notification + without any additional normalization. stability: development examples: ["Seattle, WA", '42', '{"foo": "bar"}'] - - id: mcp.result + - id: mcp.output.result type: template[any] brief: Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. note: | - Instrumentations SHOULD require an explicit configuration to capture this attribute, - as response result can contain sensitive information. + Instrumentations MAY support capturing properties returned + to the response within `result` object. + + Instrumentations that support it SHOULD require an explicit configuration + to capture this attribute, as response result can contain sensitive information. Value type SHOULD match the value of the `result` object property as returned in the response. + Instrumentation SHOULD allow capturing result properties passed with MCP's + reserved `_meta` key. + Examples: In a response with the following structure: @@ -229,21 +249,29 @@ groups: "result": { "location": "Seattle, WA", "a": 42, - "complex": {"foo": "bar"} + "complex": {"foo": "bar"}, + "_meta" : { + "mcp.dev/baz": "qux" + } } } ``` - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.result.location` attribute with string value `"Seattle, WA"`. - - A `a` key with value `42` SHOULD be recorded as the `mcp.result.a` + `mcp.output.result.location` attribute with string value `"Seattle, WA"`. + - A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` attribute with integer (signed 64 bit) value `42`. - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.result.complex` attribute with complex value type `{"foo": "bar"}`. + `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. + - A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the + `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. The attribute value SHOULD be recorded in structured form when it's possible and MAY be recorded as a JSON string if structured format is not yet supported by the OpenTelemetry implementation. + + Keys SHOULD be captured as they appear in the result without any + additional normalization. stability: development examples: ['{"output": "The weather is sunny."}', '42', '{"data": {"id": 1, "name": "Alice"}}'] - id: mcp.protocol.version diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index a0434b173f..9af1d29d7c 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -15,7 +15,7 @@ groups: conditionally_required: When the client executes a request. - ref: mcp.input.param requirement_level: opt_in - - ref: mcp.result + - ref: mcp.output.result requirement_level: opt_in - id: span.mcp.client From aeb8a7540fb8c2509e783bddcabc0a1b3d67791d Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Fri, 7 Nov 2025 18:00:56 -0800 Subject: [PATCH 07/22] lint --- model/mcp/common.yaml | 2 +- model/mcp/registry.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index db121a8a4a..68abb36f3f 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -49,4 +49,4 @@ groups: brief: The version of JSON-RPC protocol used. note: "" # overriding the default note requirement_level: - recommended: when it's not `2.0`. \ No newline at end of file + recommended: when it's not `2.0`. diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 72e201956f..5a85a1c4ac 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -278,4 +278,4 @@ groups: type: string brief: The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. stability: development - examples: ["2025-06-18"] \ No newline at end of file + examples: ["2025-06-18"] From 455b9163293bd6eda53297d719ee0859f80e2d50 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Tue, 18 Nov 2025 08:03:39 -0800 Subject: [PATCH 08/22] gen_ai.tool.name and gen_ai.prompt.name --- docs/gen-ai/mcp.md | 20 ++++++++++---------- docs/registry/attributes/gen-ai.md | 1 + docs/registry/attributes/mcp.md | 2 -- model/gen-ai/registry.yaml | 5 +++++ model/mcp/common.yaml | 5 +++-- model/mcp/registry.yaml | 13 ------------- model/mcp/spans.yaml | 4 ++-- 7 files changed, 21 insertions(+), 29 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index f5ad52c365..ab87de265b 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -111,7 +111,7 @@ or notification or by the MCP server when server initiates the operation. It covers the time to receive the response or ack from the peer. **Span name** SHOULD follow the format `{mcp.method.name} {target}` -where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when +where target SHOULD match `{gen_ai.tool.name}` or `{gen_ai.prompt.name}` when applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. @@ -133,10 +133,10 @@ for more details. |---|---|---|---|---|---| | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | @@ -344,7 +344,7 @@ It's reported by the MCP server when client initiates the request (or notification) or by the MCP client when server initiates the operation. **Span name** SHOULD follow the format `{mcp.method.name} {target}` -where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when +where target SHOULD match `{gen_ai.tool.name}` or `{gen_ai.prompt.name}` when applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. @@ -366,10 +366,10 @@ for more details. |---|---|---|---|---|---| | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | | [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | @@ -587,8 +587,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. |---|---|---|---|---|---| | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | +| [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | @@ -703,8 +703,8 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. |---|---|---|---|---|---| | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | -| [`mcp.prompt.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| [`mcp.tool.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | +| [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | diff --git a/docs/registry/attributes/gen-ai.md b/docs/registry/attributes/gen-ai.md index af894ef526..772cbb68a9 100644 --- a/docs/registry/attributes/gen-ai.md +++ b/docs/registry/attributes/gen-ai.md @@ -29,6 +29,7 @@ This document defines the attributes used to describe telemetry in the context o | `gen_ai.operation.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the operation being performed. [4] | `chat`; `generate_content`; `text_completion` | | `gen_ai.output.messages` | ![Development](https://img.shields.io/badge/-development-blue) | any | Messages returned by the model where each message represents a specific model response (choice, candidate). [5] | [
  {
    "role": "assistant",
    "parts": [
      {
        "type": "text",
        "content": "The weather in Paris is currently rainy with a temperature of 57°F."
      }
    ],
    "finish_reason": "stop"
  }
] | | `gen_ai.output.type` | ![Development](https://img.shields.io/badge/-development-blue) | string | Represents the content type requested by the client. [6] | `text`; `json`; `image` | +| `gen_ai.prompt.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the prompt that uniquely identifies it. | `analyze-code` | | `gen_ai.provider.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The Generative AI provider as identified by the client or server instrumentation. [7] | `openai`; `gcp.gen_ai`; `gcp.vertex_ai` | | `gen_ai.request.choice.count` | ![Development](https://img.shields.io/badge/-development-blue) | int | The target number of candidate completions to return. | `3` | | `gen_ai.request.encoding_formats` | ![Development](https://img.shields.io/badge/-development-blue) | string[] | The encoding formats requested in an embeddings operation, if specified. [8] | `["base64"]`; `["float", "binary"]` | diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 22641e438e..589ae28a3b 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -14,12 +14,10 @@ | `mcp.input.param.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | | `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | `mcp.output.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [2] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | -| `mcp.prompt.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | | `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | -| `mcp.tool.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the tool provided in the request. | `get-weather`; `execute_command` | **[1] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed to the request or notification within `params` object. diff --git a/model/gen-ai/registry.yaml b/model/gen-ai/registry.yaml index 8b3fa51dd4..5105358897 100644 --- a/model/gen-ai/registry.yaml +++ b/model/gen-ai/registry.yaml @@ -591,3 +591,8 @@ groups: type: string brief: A free-form explanation for the assigned score provided by the evaluator. examples: ["The response is factually accurate but lacks sufficient detail to fully address the question."] + - id: gen_ai.prompt.name + type: string + brief: The name of the prompt that uniquely identifies it. + stability: development + examples: ["analyze-code"] diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index 68abb36f3f..cdf20ca2b4 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -3,10 +3,11 @@ groups: type: attribute_group brief: Common MCP attributes attributes: - - ref: mcp.tool.name + - ref: gen_ai.tool.name requirement_level: conditionally_required: When operation is related to a specific tool. - - ref: mcp.prompt.name + - ref: gen_ai.prompt.name + brief: The name of the prompt or prompt template provided in the request or response. requirement_level: conditionally_required: When operation is related to a specific prompt. - ref: network.transport diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 5a85a1c4ac..901f57f72a 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -146,19 +146,6 @@ groups: brief: Identifies MCP session. stability: development examples: ["191c4850af6c49e08843a3f6c80e5046"] - - id: mcp.tool.name - # This is effectively the same as `gen_ai.tool.name`, but it's not clear - # which one of them should survive. MCP can be used outside of GenAI domain, - # and GenAI can be used without MCP. - type: string - brief: The name of the tool provided in the request. - stability: development - examples: ["get-weather", "execute_command"] - - id: mcp.prompt.name - type: string - brief: The name of the prompt or prompt template provided in the request or response. - stability: development - examples: ["analyze-code"] - id: mcp.resource.uri type: string brief: The value of the resource uri. diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index 9af1d29d7c..b09dece587 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -28,7 +28,7 @@ groups: It covers the time to receive the response or ack from the peer. **Span name** SHOULD follow the format `{mcp.method.name} {target}` - where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when + where target SHOULD match `{gen_ai.tool.name}` or `{gen_ai.prompt.name}` when applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. @@ -61,7 +61,7 @@ groups: (or notification) or by the MCP client when server initiates the operation. **Span name** SHOULD follow the format `{mcp.method.name} {target}` - where target SHOULD match `{mcp.tool.name}` or `{mcp.prompt.name}` when + where target SHOULD match `{gen_ai.tool.name}` or `{gen_ai.prompt.name}` when applicable. If there is no low-cardinality `target` available, the Span name SHOULD be `{mcp.method.name}`. From b8f15ab416ad4489e6f47043d828c8bc107bf954 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Tue, 18 Nov 2025 08:08:12 -0800 Subject: [PATCH 09/22] add link to mcp session management --- docs/gen-ai/mcp.md | 4 ++-- docs/registry/attributes/mcp.md | 2 +- model/mcp/registry.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index ab87de265b..bbacc87313 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -139,7 +139,7 @@ for more details. | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `quic`; `pipe` | @@ -374,7 +374,7 @@ for more details. | [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 589ae28a3b..21ccdbaac7 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -17,7 +17,7 @@ | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | | `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies MCP session. | `191c4850af6c49e08843a3f6c80e5046` | +| `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | **[1] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed to the request or notification within `params` object. diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 901f57f72a..5a78379be4 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -143,7 +143,7 @@ groups: examples: ["42"] - id: mcp.session.id type: string - brief: Identifies MCP session. + brief: Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). stability: development examples: ["191c4850af6c49e08843a3f6c80e5046"] - id: mcp.resource.uri From 33f0e0b45e8aea86626c8302b27afe4073d397ea Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Tue, 18 Nov 2025 18:41:08 -0800 Subject: [PATCH 10/22] remove input/result params for now, add transport table --- docs/gen-ai/README.md | 2 +- docs/gen-ai/mcp.md | 213 +++----------------------------- docs/registry/attributes/mcp.md | 101 +-------------- model/mcp/registry.yaml | 107 ---------------- model/mcp/spans.yaml | 4 - 5 files changed, 22 insertions(+), 405 deletions(-) diff --git a/docs/gen-ai/README.md b/docs/gen-ai/README.md index 0f06cc7523..ddcfcc6e7e 100644 --- a/docs/gen-ai/README.md +++ b/docs/gen-ai/README.md @@ -40,7 +40,7 @@ Technology specific semantic conventions are defined for the following GenAI sys * [OpenAI](./openai.md): Semantic Conventions for OpenAI. * [AWS Bedrock](./aws-bedrock.md): Semantic Conventions for AWS Bedrock. -See also +See also: * [Model Context Protocol](./mcp.md): Semantic Conventions for [MCP](https://modelcontextprotocol.io) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index bbacc87313..e6931c883d 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -17,6 +17,7 @@ linkTitle: Model Context Protocol - [Metric: `mcp.server.operation.duration`](#metric-mcpserveroperationduration) - [Metric: `mcp.client.session.duration`](#metric-mcpclientsessionduration) - [Metric: `mcp.server.session.duration`](#metric-mcpserversessionduration) +- [Recording MCP transport](#recording-mcp-transport) @@ -146,8 +147,6 @@ for more details. | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | -| [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | -| [`mcp.output.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -175,101 +174,6 @@ It SHOULD be set to `pipe` if the transport is stdio. **[8] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[9] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed -to the request or notification within `params` object. - -Instrumentations that support it SHOULD require an explicit configuration of which keys -are to be captured. Including all request or notifications parameters -can be a security risk - explicit configuration helps avoid leaking sensitive information. - -Value type SHOULD match the value of the parameter as passed in the request -or notification. - -Instrumentation SHOULD allow capturing parameters passed with MCP's -reserved `_meta` key. - -Examples: - -In a params object with the following structure: - -```json -{ - "jsonrpc": "2.0", - "id": 12345, - "method": "some/method", - "params": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"} - "_meta" : { - "mcp.dev/baz": "qux" - } - } -} -``` - -- A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the - `mcp.input.param.location` attribute with string value `"Seattle, WA"`. -- A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` - attribute with integer (signed 64 bit) value `42`. -- A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. -- A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. - -The attribute value SHOULD be recorded in structured form when it's possible -and MAY be recorded as a JSON string if structured format is not yet supported -by the OpenTelemetry implementation. - -Keys SHOULD be captured as they appear in the request or notification -without any additional normalization. - -**[10] `mcp.output.result.`:** Instrumentations MAY support capturing properties returned -to the response within `result` object. - -Instrumentations that support it SHOULD require an explicit configuration -to capture this attribute, as response result can contain sensitive information. - -Value type SHOULD match the value of the `result` object property as returned in the response. - -Instrumentation SHOULD allow capturing result properties passed with MCP's -reserved `_meta` key. - -Examples: - -In a response with the following structure: - -```json -{ - "jsonrpc": "2.0", - "id": 12345, - "result": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"}, - "_meta" : { - "mcp.dev/baz": "qux" - } - } -} -``` - -- A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.output.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` - attribute with integer (signed 64 bit) value `42`. -- A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. -- A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. - -The attribute value SHOULD be recorded in structured form when it's possible -and MAY be recorded as a JSON string if structured format is not yet supported -by the OpenTelemetry implementation. - -Keys SHOULD be captured as they appear in the result without any -additional normalization. - --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. @@ -379,8 +283,6 @@ for more details. | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`mcp.input.param.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [9] | `Seattle, WA`; `42`; `{"foo": "bar"}` | -| [`mcp.output.result.`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [10] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -408,101 +310,6 @@ is returned with `isError` set to `true`, this attribute SHOULD be set to is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[9] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed -to the request or notification within `params` object. - -Instrumentations that support it SHOULD require an explicit configuration of which keys -are to be captured. Including all request or notifications parameters -can be a security risk - explicit configuration helps avoid leaking sensitive information. - -Value type SHOULD match the value of the parameter as passed in the request -or notification. - -Instrumentation SHOULD allow capturing parameters passed with MCP's -reserved `_meta` key. - -Examples: - -In a params object with the following structure: - -```json -{ - "jsonrpc": "2.0", - "id": 12345, - "method": "some/method", - "params": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"} - "_meta" : { - "mcp.dev/baz": "qux" - } - } -} -``` - -- A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the - `mcp.input.param.location` attribute with string value `"Seattle, WA"`. -- A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` - attribute with integer (signed 64 bit) value `42`. -- A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. -- A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. - -The attribute value SHOULD be recorded in structured form when it's possible -and MAY be recorded as a JSON string if structured format is not yet supported -by the OpenTelemetry implementation. - -Keys SHOULD be captured as they appear in the request or notification -without any additional normalization. - -**[10] `mcp.output.result.`:** Instrumentations MAY support capturing properties returned -to the response within `result` object. - -Instrumentations that support it SHOULD require an explicit configuration -to capture this attribute, as response result can contain sensitive information. - -Value type SHOULD match the value of the `result` object property as returned in the response. - -Instrumentation SHOULD allow capturing result properties passed with MCP's -reserved `_meta` key. - -Examples: - -In a response with the following structure: - -```json -{ - "jsonrpc": "2.0", - "id": 12345, - "result": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"}, - "_meta" : { - "mcp.dev/baz": "qux" - } - } -} -``` - -- A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.output.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` - attribute with integer (signed 64 bit) value `42`. -- A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. -- A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. - -The attribute value SHOULD be recorded in structured form when it's possible -and MAY be recorded as a JSON string if structured format is not yet supported -by the OpenTelemetry implementation. - -Keys SHOULD be captured as they appear in the result without any -additional normalization. - --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. @@ -956,3 +763,21 @@ is HTTP. It SHOULD be set to `pipe` if the transport is stdio. [DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status [MetricRecommended]: /docs/general/metric-requirement-level.md#recommended + +## Recording MCP transport + +The following table shows how to capture MCP transport and can be used be telemetry +consumers to deduce transport type. + +| MCP transport | `network.transport` attribute | `network.protocol.*` attributes | `mcp.protocol.version` attribute | comments | +| ------------- | ----------------------------- | ------------------------------- | -------------------------------- | -------- | +| stdio | `pipe` | | any | | +| Streamable HTTP | `tcp` (or `quic`) | `network.protocol.name = http`
`network.protocol.version = 2` | `2025-06-18` or newer | `mcp.protocol.version` distinguishes streamable HTTP from SSE | +| HTTP with SSE | `tcp` (or `quic`) | `network.protocol.name = http`
`network.protocol.version = 1.1` (or 2) | `2024-11-05` or older | `mcp.protocol.version` distinguishes streamable HTTP from SSE | +| Custom: websockets | `tcp` (or another applicable protocol) | `network.protocol.name = websocket` | any | | +| Custom: gRPC | `tcp` (or another applicable protocol) | `network.protocol.name = http`
`network.protocol.version = 2` | any | See [gRPC conventions](/docs/rpc/grpc.md) for additional details | + +Note: Applications may enable instrumentation for the underlying application protocol +like HTTP (when applicable) alongside MCP instrumentation to capture additional +transport-level details, such as transport-specific error codes. + diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 21ccdbaac7..f792c0fb1b 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -11,110 +11,13 @@ | Key | Stability | Value Type | Description | Example Values | |---|---|---|---|---| -| `mcp.input.param.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Parameters passed to the request within `params` object. `` being the normalized parameter key (lowercase), the value being the parameter value. [1] | `Seattle, WA`; `42`; `{"foo": "bar"}` | | `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | -| `mcp.output.result.` | ![Development](https://img.shields.io/badge/-development-blue) | template[any] | Result property returned in the response. `` being the normalized result key (lowercase), the value being the result value. [2] | `{"output": "The weather is sunny."}`; `42`; `{"data": {"id": 1, "name": "Alice"}}` | | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | -| `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [1] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -**[1] `mcp.input.param.`:** Instrumentations MAY support capturing input parameters passed -to the request or notification within `params` object. - -Instrumentations that support it SHOULD require an explicit configuration of which keys -are to be captured. Including all request or notifications parameters -can be a security risk - explicit configuration helps avoid leaking sensitive information. - -Value type SHOULD match the value of the parameter as passed in the request -or notification. - -Instrumentation SHOULD allow capturing parameters passed with MCP's -reserved `_meta` key. - -Examples: - -In a params object with the following structure: - -```json -{ - "jsonrpc": "2.0", - "id": 12345, - "method": "some/method", - "params": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"} - "_meta" : { - "mcp.dev/baz": "qux" - } - } -} -``` - -- A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the - `mcp.input.param.location` attribute with string value `"Seattle, WA"`. -- A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` - attribute with integer (signed 64 bit) value `42`. -- A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. -- A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. - -The attribute value SHOULD be recorded in structured form when it's possible -and MAY be recorded as a JSON string if structured format is not yet supported -by the OpenTelemetry implementation. - -Keys SHOULD be captured as they appear in the request or notification -without any additional normalization. - -**[2] `mcp.output.result.`:** Instrumentations MAY support capturing properties returned -to the response within `result` object. - -Instrumentations that support it SHOULD require an explicit configuration -to capture this attribute, as response result can contain sensitive information. - -Value type SHOULD match the value of the `result` object property as returned in the response. - -Instrumentation SHOULD allow capturing result properties passed with MCP's -reserved `_meta` key. - -Examples: - -In a response with the following structure: - -```json -{ - "jsonrpc": "2.0", - "id": 12345, - "result": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"}, - "_meta" : { - "mcp.dev/baz": "qux" - } - } -} -``` - -- A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.output.result.location` attribute with string value `"Seattle, WA"`. -- A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` - attribute with integer (signed 64 bit) value `42`. -- A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. -- A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. - -The attribute value SHOULD be recorded in structured form when it's possible -and MAY be recorded as a JSON string if structured format is not yet supported -by the OpenTelemetry implementation. - -Keys SHOULD be captured as they appear in the result without any -additional normalization. - -**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[1] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 5a78379be4..6df2bd1cbe 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -154,113 +154,6 @@ groups: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. stability: development examples: ["postgres://database/customers/schema", "file:///home/user/documents/report.pdf"] - - id: mcp.input.param - type: template[any] - brief: Parameters passed to the request within `params` object. - `` being the normalized parameter key (lowercase), the value being the parameter value. - note: | - Instrumentations MAY support capturing input parameters passed - to the request or notification within `params` object. - - Instrumentations that support it SHOULD require an explicit configuration of which keys - are to be captured. Including all request or notifications parameters - can be a security risk - explicit configuration helps avoid leaking sensitive information. - - Value type SHOULD match the value of the parameter as passed in the request - or notification. - - Instrumentation SHOULD allow capturing parameters passed with MCP's - reserved `_meta` key. - - Examples: - - In a params object with the following structure: - - ```json - { - "jsonrpc": "2.0", - "id": 12345, - "method": "some/method", - "params": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"} - "_meta" : { - "mcp.dev/baz": "qux" - } - } - } - ``` - - - A `param.location` key with string value `"Seattle, WA"` SHOULD be recorded as the - `mcp.input.param.location` attribute with string value `"Seattle, WA"`. - - A `param.a` key with integer value `42` SHOULD be recorded as the `mcp.input.param.a` - attribute with integer (signed 64 bit) value `42`. - - A `param.complex` key with complex value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.input.param.complex` attribute with complex value type `{"foo": "bar"}`. - - A `param._meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.input.param._meta.mcp.dev/baz` attribute with string value `"qux"`. - - The attribute value SHOULD be recorded in structured form when it's possible - and MAY be recorded as a JSON string if structured format is not yet supported - by the OpenTelemetry implementation. - - Keys SHOULD be captured as they appear in the request or notification - without any additional normalization. - stability: development - examples: ["Seattle, WA", '42', '{"foo": "bar"}'] - - id: mcp.output.result - type: template[any] - brief: Result property returned in the response. - `` being the normalized result key (lowercase), the value being the result value. - note: | - Instrumentations MAY support capturing properties returned - to the response within `result` object. - - Instrumentations that support it SHOULD require an explicit configuration - to capture this attribute, as response result can contain sensitive information. - - Value type SHOULD match the value of the `result` object property as returned in the response. - - Instrumentation SHOULD allow capturing result properties passed with MCP's - reserved `_meta` key. - - Examples: - - In a response with the following structure: - - ```json - { - "jsonrpc": "2.0", - "id": 12345, - "result": { - "location": "Seattle, WA", - "a": 42, - "complex": {"foo": "bar"}, - "_meta" : { - "mcp.dev/baz": "qux" - } - } - } - ``` - - - A `location` key with value `"Seattle, WA"` SHOULD be recorded as the - `mcp.output.result.location` attribute with string value `"Seattle, WA"`. - - A `a` key with value `42` SHOULD be recorded as the `mcp.output.result.a` - attribute with integer (signed 64 bit) value `42`. - - A `complex` key with value `{"foo": "bar"}` SHOULD be recorded as the - `mcp.output.result.complex` attribute with complex value type `{"foo": "bar"}`. - - A `_meta.mcp.dev/baz` key with string value `"qux"` SHOULD be recorded as the - `mcp.output.result._meta.mcp.dev/baz` attribute with string value `"qux"`. - - The attribute value SHOULD be recorded in structured form when it's possible - and MAY be recorded as a JSON string if structured format is not yet supported - by the OpenTelemetry implementation. - - Keys SHOULD be captured as they appear in the result without any - additional normalization. - stability: development - examples: ['{"output": "The weather is sunny."}', '42', '{"data": {"id": 1, "name": "Alice"}}'] - id: mcp.protocol.version type: string brief: The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index b09dece587..882a03f6de 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -13,10 +13,6 @@ groups: - ref: mcp.request.id requirement_level: conditionally_required: When the client executes a request. - - ref: mcp.input.param - requirement_level: opt_in - - ref: mcp.output.result - requirement_level: opt_in - id: span.mcp.client type: span From 6ebd29daed7c6dd9486d8b0fbcb3f4c22ec5bcec Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Mon, 24 Nov 2025 13:02:47 -0800 Subject: [PATCH 11/22] lint --- docs/gen-ai/mcp.md | 19 ------------------- docs/registry/attributes/mcp.md | 2 +- model/mcp/registry.yaml | 2 +- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index e6931c883d..ab8a6f415f 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -100,8 +100,6 @@ property bag similarly to the following example: - - **Status:** ![Development](https://img.shields.io/badge/-development-blue) @@ -226,7 +224,6 @@ It SHOULD be set to `pipe` if the transport is stdio. | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - @@ -237,8 +234,6 @@ It SHOULD be set to `pipe` if the transport is stdio. - - **Status:** ![Development](https://img.shields.io/badge/-development-blue) @@ -362,7 +357,6 @@ It SHOULD be set to `pipe` if the transport is stdio. | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - @@ -381,8 +375,6 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. - - | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | @@ -480,7 +472,6 @@ It SHOULD be set to `pipe` if the transport is stdio. | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - @@ -497,8 +488,6 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. - - | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | @@ -590,7 +579,6 @@ It SHOULD be set to `pipe` if the transport is stdio. | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - @@ -607,8 +595,6 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. - - | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | @@ -676,7 +662,6 @@ is HTTP. It SHOULD be set to `pipe` if the transport is stdio. | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - @@ -693,8 +678,6 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. - - | Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | @@ -756,7 +739,6 @@ is HTTP. It SHOULD be set to `pipe` if the transport is stdio. | `udp` | UDP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `unix` | Unix domain socket | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | - @@ -780,4 +762,3 @@ consumers to deduce transport type. Note: Applications may enable instrumentation for the underlying application protocol like HTTP (when applicable) alongside MCP instrumentation to capture additional transport-level details, such as transport-specific error codes. - diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index f792c0fb1b..99851ffaba 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -5,7 +5,7 @@ ## MCP Attributes -[Model Context Protocol (MCP)](https://spec.modelcontextprotocol.io) attributes +[Model Context Protocol (MCP)](https://modelcontextprotocol.io) attributes **Attributes:** diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 6df2bd1cbe..e12e02bae9 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -2,7 +2,7 @@ groups: - id: registry.mcp type: attribute_group brief: > - [Model Context Protocol (MCP)](https://spec.modelcontextprotocol.io) attributes + [Model Context Protocol (MCP)](https://modelcontextprotocol.io) attributes attributes: - id: mcp.method.name brief: The name of the request or notification method. From b58b8fa2c80cf6612fd6c083ad355b78f6415bc1 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 1 Dec 2025 17:05:48 -0800 Subject: [PATCH 12/22] make mcp tool call and genai tool execution spans compatible, add notes that allow suppression --- docs/gen-ai/gen-ai-spans.md | 15 +- docs/gen-ai/mcp.md | 321 +++++++++++++++++++++-------- docs/registry/attributes/gen-ai.md | 2 +- docs/registry/attributes/mcp.md | 6 +- model/gen-ai/registry.yaml | 2 +- model/gen-ai/spans.yaml | 13 +- model/mcp/common.yaml | 17 ++ model/mcp/spans.yaml | 5 + 8 files changed, 279 insertions(+), 102 deletions(-) diff --git a/docs/gen-ai/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md index 4e1b321bfb..bcb56eccc8 100644 --- a/docs/gen-ai/gen-ai-spans.md +++ b/docs/gen-ai/gen-ai-spans.md @@ -364,10 +364,15 @@ Describes tool execution span. **Span name** SHOULD be `execute_tool {gen_ai.tool.name}`. -GenAI instrumentations that are able to instrument tool execution call SHOULD do so. -However, it's common for tools to be executed by the application code. It's recommended -for the application developers to follow this semantic convention for tools invoked -by the application code. +GenAI instrumentations that can instrument tool execution calls SHOULD do so, +unless another instrumentation can reliably cover all supported tool types. +MCP tool executions may also be traced by the +[corresponding MCP instrumentation](/docs/gen-ai/mcp#client). + +Tools are often executed directly by application code. Application developers +are encouraged to follow this semantic convention for tools invoked by their +own code and to manually instrument any tool calls that automatic +instrumentations do not cover. **Span kind** SHOULD be `INTERNAL`. @@ -382,7 +387,7 @@ by the application code. | [`gen_ai.tool.call.id`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | The tool call identifier. | `call_mszuSIzqtI65i1wAUOE8w5H4` | | [`gen_ai.tool.description`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | The tool description. | `Multiply two numbers` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | Name of the tool utilized by the agent. | `Flights` | -| [`gen_ai.tool.type`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | Type of the tool utilized by the agent [3] | `function`; `extension`; `datastore` | +| [`gen_ai.tool.type`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | Type of the tool utilized by the agent [3] | `function`; `extension`; `datastore`; `mcp` | | [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | Parameters passed to the tool call. [4] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | | [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | The result returned by the tool call (if any and if execution was successful). [5] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index ab8a6f415f..f51b4172aa 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -124,27 +124,35 @@ The status description SHOULD match the `JSONRPCError.message` if the message is Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. +MCP tool call execution spans are compatible with Gen AI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). +MCP instrumentations MAY suppress their spans when they can detect that +the Gen AI instrumentation is already tracing the tool execution and MAY +provide configuration options to disable tool execution spans. + **Span kind** SHOULD be `CLIENT`. **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [4] | string | The value of the resource uri. [5] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | The name of the GenAI operation being performed. [7] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http`; `websocket` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [10] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [12] | `80`; `8080`; `443` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -156,36 +164,68 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[3] `gen_ai.tool.call.result`:** > [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[4] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. + +**[5] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. + +**[6] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[7] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[4] `mcp.session.id`:** When the MCP request or notification is part of a session. +**[8] `mcp.session.id`:** When the MCP request or notification is part of a session. -**[5] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[9] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[10] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[7] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[11] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[8] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[12] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- +`gen_ai.operation.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +| --- | --- | --- | +| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Development](https://img.shields.io/badge/-development-blue) | +| `create_agent` | Create GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `embeddings` | Embeddings operation such as [OpenAI Create embeddings API](https://platform.openai.com/docs/api-reference/embeddings/create) | ![Development](https://img.shields.io/badge/-development-blue) | +| `execute_tool` | Execute a tool | ![Development](https://img.shields.io/badge/-development-blue) | +| `generate_content` | Multimodal content generation operation such as [Gemini Generate Content](https://ai.google.dev/api/generate-content) | ![Development](https://img.shields.io/badge/-development-blue) | +| `invoke_agent` | Invoke GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | | `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | | `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -216,8 +256,8 @@ It SHOULD be set to `pipe` if the transport is stdio. `network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -262,21 +302,24 @@ for more details. **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [4] | string | The value of the resource uri. [5] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [7] | `65123` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | The name of the GenAI operation being performed. [9] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http`; `websocket` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [10] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [11] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [12] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC @@ -289,19 +332,37 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[3] `gen_ai.tool.call.result`:** > [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. -**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[4] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. -**[4] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[5] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. -**[5] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[6] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[6] `mcp.session.id`:** When the MCP request or notification is part of a session. +**[7] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[8] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[8] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[9] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. + +**[10] `mcp.session.id`:** When the MCP request or notification is part of a session. + +**[11] `network.protocol.name`:** The value SHOULD be normalized to lowercase. + +**[12] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. @@ -309,16 +370,30 @@ It SHOULD be set to `pipe` if the transport is stdio. `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- +`gen_ai.operation.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +| --- | --- | --- | +| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Development](https://img.shields.io/badge/-development-blue) | +| `create_agent` | Create GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `embeddings` | Embeddings operation such as [OpenAI Create embeddings API](https://platform.openai.com/docs/api-reference/embeddings/create) | ![Development](https://img.shields.io/badge/-development-blue) | +| `execute_tool` | Execute a tool | ![Development](https://img.shields.io/badge/-development-blue) | +| `generate_content` | Multimodal content generation operation such as [Gemini Generate Content](https://ai.google.dev/api/generate-content) | ![Development](https://img.shields.io/badge/-development-blue) | +| `invoke_agent` | Invoke GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | | `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | | `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -349,8 +424,8 @@ It SHOULD be set to `pipe` if the transport is stdio. `network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -376,27 +451,30 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | -| `mcp.client.operation.duration` | Histogram | `s` | The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received. | ![Development](https://img.shields.io/badge/-development-blue) | | +| `mcp.client.operation.duration` | Histogram | `s` | The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received. | ![Development](https://img.shields.io/badge/-development-blue) | | **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | The name of the GenAI operation being performed. [5] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [6] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [7] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [6] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [9] | `80`; `8080`; `443` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [10] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -408,32 +486,64 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] +> This attribute may contain sensitive information. -**[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[3] `gen_ai.tool.call.result`:** > [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[4] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. + +**[5] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. + +**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase. + +**[7] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[4] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[8] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[9] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[6] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[10] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- +`gen_ai.operation.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +| --- | --- | --- | +| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Development](https://img.shields.io/badge/-development-blue) | +| `create_agent` | Create GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `embeddings` | Embeddings operation such as [OpenAI Create embeddings API](https://platform.openai.com/docs/api-reference/embeddings/create) | ![Development](https://img.shields.io/badge/-development-blue) | +| `execute_tool` | Execute a tool | ![Development](https://img.shields.io/badge/-development-blue) | +| `generate_content` | Multimodal content generation operation such as [Gemini Generate Content](https://ai.google.dev/api/generate-content) | ![Development](https://img.shields.io/badge/-development-blue) | +| `invoke_agent` | Invoke GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | | `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | | `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -464,8 +574,8 @@ It SHOULD be set to `pipe` if the transport is stdio. `network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -489,25 +599,28 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | -| `mcp.server.operation.duration` | Histogram | `s` | MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent. | ![Development](https://img.shields.io/badge/-development-blue) | | +| `mcp.server.operation.duration` | Histogram | `s` | MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent. | ![Development](https://img.shields.io/badge/-development-blue) | | **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | +| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | The name of the GenAI operation being performed. [5] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [6] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [7] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [4] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [8] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -519,28 +632,60 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] +> This attribute may contain sensitive information. -**[3] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[3] `gen_ai.tool.call.result`:** > [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. + +**[4] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. + +**[5] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. + +**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase. + +**[7] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[4] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[8] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- +`gen_ai.operation.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. + +| Value | Description | Stability | +| --- | --- | --- | +| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Development](https://img.shields.io/badge/-development-blue) | +| `create_agent` | Create GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `embeddings` | Embeddings operation such as [OpenAI Create embeddings API](https://platform.openai.com/docs/api-reference/embeddings/create) | ![Development](https://img.shields.io/badge/-development-blue) | +| `execute_tool` | Execute a tool | ![Development](https://img.shields.io/badge/-development-blue) | +| `generate_content` | Multimodal content generation operation such as [Gemini Generate Content](https://ai.google.dev/api/generate-content) | ![Development](https://img.shields.io/badge/-development-blue) | +| `invoke_agent` | Invoke GenAI agent | ![Development](https://img.shields.io/badge/-development-blue) | +| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Development](https://img.shields.io/badge/-development-blue) | + +--- + `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | | `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | | `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -571,8 +716,8 @@ It SHOULD be set to `pipe` if the transport is stdio. `network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -596,14 +741,14 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | -| `mcp.client.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | | +| `mcp.client.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | | **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | @@ -646,16 +791,16 @@ is HTTP. It SHOULD be set to `pipe` if the transport is stdio. `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- `network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | @@ -679,14 +824,14 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. -| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | +| Name | Instrument Type | Unit (UCUM) | Description | Stability | Entity Associations | | -------- | --------------- | ----------- | -------------- | --------- | ------ | -| `mcp.server.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP server. | ![Development](https://img.shields.io/badge/-development-blue) | | +| `mcp.server.session.duration` | Histogram | `s` | The duration of the MCP session as observed on the MCP server. | ![Development](https://img.shields.io/badge/-development-blue) | | **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | -|---|---|---|---|---|---| +| --- | --- | --- | --- | --- | --- | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | @@ -723,16 +868,16 @@ is HTTP. It SHOULD be set to `pipe` if the transport is stdio. `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | --- `network.transport` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `pipe` | Named or anonymous pipe. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `quic` | QUIC | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | | `tcp` | TCP | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | diff --git a/docs/registry/attributes/gen-ai.md b/docs/registry/attributes/gen-ai.md index 2d0066bde5..ec55412ae4 100644 --- a/docs/registry/attributes/gen-ai.md +++ b/docs/registry/attributes/gen-ai.md @@ -53,7 +53,7 @@ This document defines the attributes used to describe telemetry in the context o | `gen_ai.tool.definitions` | ![Development](https://img.shields.io/badge/-development-blue) | any | The list of source system tool definitions available to the GenAI agent or model. [12] | [
  {
    "type": "function",
    "name": "get_current_weather",
    "description": "Get the current weather in a given location",
    "parameters": {
      "type": "object",
      "properties": {
        "location": {
          "type": "string",
          "description": "The city and state, e.g. San Francisco, CA"
        },
        "unit": {
          "type": "string",
          "enum": [
            "celsius",
            "fahrenheit"
          ]
        }
      },
      "required": [
        "location",
        "unit"
      ]
    }
  }
] | | `gen_ai.tool.description` | ![Development](https://img.shields.io/badge/-development-blue) | string | The tool description. | `Multiply two numbers` | | `gen_ai.tool.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | Name of the tool utilized by the agent. | `Flights` | -| `gen_ai.tool.type` | ![Development](https://img.shields.io/badge/-development-blue) | string | Type of the tool utilized by the agent [13] | `function`; `extension`; `datastore` | +| `gen_ai.tool.type` | ![Development](https://img.shields.io/badge/-development-blue) | string | Type of the tool utilized by the agent [13] | `function`; `extension`; `datastore`; `mcp` | | `gen_ai.usage.input_tokens` | ![Development](https://img.shields.io/badge/-development-blue) | int | The number of tokens used in the GenAI input (prompt). | `100` | | `gen_ai.usage.output_tokens` | ![Development](https://img.shields.io/badge/-development-blue) | int | The number of tokens used in the GenAI response (completion). | `180` | diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index 99851ffaba..aae0ac9a0c 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -10,7 +10,7 @@ **Attributes:** | Key | Stability | Value Type | Description | Example Values | -|---|---|---|---|---| +| --- | --- | --- | --- | --- | | `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | @@ -23,8 +23,8 @@ `mcp.method.name` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. -| Value | Description | Stability | -|---|---|---| +| Value | Description | Stability | +| --- | --- | --- | | `completion/complete` | Request to complete a prompt. | ![Development](https://img.shields.io/badge/-development-blue) | | `elicitation/create` | Request from the server to elicit additional information from the user via the client | ![Development](https://img.shields.io/badge/-development-blue) | | `initialize` | Request to initialize the MCP client. | ![Development](https://img.shields.io/badge/-development-blue) | diff --git a/model/gen-ai/registry.yaml b/model/gen-ai/registry.yaml index 5105358897..b8a4909239 100644 --- a/model/gen-ai/registry.yaml +++ b/model/gen-ai/registry.yaml @@ -254,7 +254,7 @@ groups: Function: A tool executed on the client-side, where the agent generates parameters for a predefined function, and the client executes the logic. Client-side operations are actions taken on the user's end or within the client application. Datastore: A tool used by the agent to access and query structured or unstructured external data for retrieval-augmented tasks or knowledge updates. - examples: ['function', 'extension', 'datastore'] + examples: ['function', 'extension', 'datastore', 'mcp'] - id: gen_ai.tool.call.arguments stability: development diff --git a/model/gen-ai/spans.yaml b/model/gen-ai/spans.yaml index 542de5fdff..3d59a07a0e 100644 --- a/model/gen-ai/spans.yaml +++ b/model/gen-ai/spans.yaml @@ -307,10 +307,15 @@ groups: **Span name** SHOULD be `execute_tool {gen_ai.tool.name}`. - GenAI instrumentations that are able to instrument tool execution call SHOULD do so. - However, it's common for tools to be executed by the application code. It's recommended - for the application developers to follow this semantic convention for tools invoked - by the application code. + GenAI instrumentations that can instrument tool execution calls SHOULD do so, + unless another instrumentation can reliably cover all supported tool types. + MCP tool executions may also be traced by the + [corresponding MCP instrumentation](/docs/gen-ai/mcp#client). + + Tools are often executed directly by application code. Application developers + are encouraged to follow this semantic convention for tools invoked by their + own code and to manually instrument any tool calls that automatic + instrumentations do not cover. attributes: - ref: gen_ai.operation.name requirement_level: required diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index cdf20ca2b4..c2eb21653d 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -6,6 +6,23 @@ groups: - ref: gen_ai.tool.name requirement_level: conditionally_required: When operation is related to a specific tool. + - ref: gen_ai.tool.call.arguments + requirement_level: + conditionally_required: When operation describes a tool call. + - ref: gen_ai.tool.call.result + requirement_level: + conditionally_required: When operation describes a tool call. + - ref: gen_ai.operation.name + brief: The name of the GenAI operation being performed. + examples: ["execute_tool"] + requirement_level: + recommended: > + SHOULD be set to `execute_tool` when the operation describes a tool + call and SHOULD NOT be set otherwise. + note: > + Populating this attribute for tool calling along with `mcp.method.name` + allows consumers to treat MCP tool calls spans similarly with other tool + call types. - ref: gen_ai.prompt.name brief: The name of the prompt or prompt template provided in the request or response. requirement_level: diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index 882a03f6de..e7a9d4e391 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -37,6 +37,11 @@ groups: Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. + + MCP tool call execution spans are compatible with Gen AI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). + MCP instrumentations MAY suppress their spans when they can detect that + the Gen AI instrumentation is already tracing the tool execution and MAY + provide configuration options to disable tool execution spans. stability: development extends: trace.mcp.common.attributes attributes: From 300fdfc69bb182fd22161d6a0d58d994526886d3 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Wed, 3 Dec 2025 12:59:56 -0800 Subject: [PATCH 13/22] clarigy suppression + enrichment --- docs/gen-ai/gen-ai-spans.md | 2 +- docs/gen-ai/mcp.md | 12 ++++++++---- docs/registry/attributes/gen-ai.md | 2 +- model/gen-ai/registry.yaml | 2 +- model/mcp/spans.yaml | 12 ++++++++---- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docs/gen-ai/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md index bcb56eccc8..68e0734112 100644 --- a/docs/gen-ai/gen-ai-spans.md +++ b/docs/gen-ai/gen-ai-spans.md @@ -387,7 +387,7 @@ instrumentations do not cover. | [`gen_ai.tool.call.id`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | The tool call identifier. | `call_mszuSIzqtI65i1wAUOE8w5H4` | | [`gen_ai.tool.description`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | The tool description. | `Multiply two numbers` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | Name of the tool utilized by the agent. | `Flights` | -| [`gen_ai.tool.type`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | Type of the tool utilized by the agent [3] | `function`; `extension`; `datastore`; `mcp` | +| [`gen_ai.tool.type`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` if available | string | Type of the tool utilized by the agent [3] | `function`; `extension`; `datastore` | | [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | Parameters passed to the tool call. [4] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | | [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | The result returned by the tool call (if any and if execution was successful). [5] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index f51b4172aa..942c9107e7 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -124,10 +124,14 @@ The status description SHOULD match the `JSONRPCError.message` if the message is Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. -MCP tool call execution spans are compatible with Gen AI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). -MCP instrumentations MAY suppress their spans when they can detect that -the Gen AI instrumentation is already tracing the tool execution and MAY -provide configuration options to disable tool execution spans. +MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). + +If the MCP instrumentation can reliably detect that outer GenAI instrumentation +is already tracing the tool execution, it SHOULD NOT create a separate span. +Instead, it SHOULD add MCP-specific attributes to the existing tool execution span. + +Instrumentations that support this behavior MAY provide a configuration +option to enable it. **Span kind** SHOULD be `CLIENT`. diff --git a/docs/registry/attributes/gen-ai.md b/docs/registry/attributes/gen-ai.md index ec55412ae4..2d0066bde5 100644 --- a/docs/registry/attributes/gen-ai.md +++ b/docs/registry/attributes/gen-ai.md @@ -53,7 +53,7 @@ This document defines the attributes used to describe telemetry in the context o | `gen_ai.tool.definitions` | ![Development](https://img.shields.io/badge/-development-blue) | any | The list of source system tool definitions available to the GenAI agent or model. [12] | [
  {
    "type": "function",
    "name": "get_current_weather",
    "description": "Get the current weather in a given location",
    "parameters": {
      "type": "object",
      "properties": {
        "location": {
          "type": "string",
          "description": "The city and state, e.g. San Francisco, CA"
        },
        "unit": {
          "type": "string",
          "enum": [
            "celsius",
            "fahrenheit"
          ]
        }
      },
      "required": [
        "location",
        "unit"
      ]
    }
  }
] | | `gen_ai.tool.description` | ![Development](https://img.shields.io/badge/-development-blue) | string | The tool description. | `Multiply two numbers` | | `gen_ai.tool.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | Name of the tool utilized by the agent. | `Flights` | -| `gen_ai.tool.type` | ![Development](https://img.shields.io/badge/-development-blue) | string | Type of the tool utilized by the agent [13] | `function`; `extension`; `datastore`; `mcp` | +| `gen_ai.tool.type` | ![Development](https://img.shields.io/badge/-development-blue) | string | Type of the tool utilized by the agent [13] | `function`; `extension`; `datastore` | | `gen_ai.usage.input_tokens` | ![Development](https://img.shields.io/badge/-development-blue) | int | The number of tokens used in the GenAI input (prompt). | `100` | | `gen_ai.usage.output_tokens` | ![Development](https://img.shields.io/badge/-development-blue) | int | The number of tokens used in the GenAI response (completion). | `180` | diff --git a/model/gen-ai/registry.yaml b/model/gen-ai/registry.yaml index b8a4909239..5105358897 100644 --- a/model/gen-ai/registry.yaml +++ b/model/gen-ai/registry.yaml @@ -254,7 +254,7 @@ groups: Function: A tool executed on the client-side, where the agent generates parameters for a predefined function, and the client executes the logic. Client-side operations are actions taken on the user's end or within the client application. Datastore: A tool used by the agent to access and query structured or unstructured external data for retrieval-augmented tasks or knowledge updates. - examples: ['function', 'extension', 'datastore', 'mcp'] + examples: ['function', 'extension', 'datastore'] - id: gen_ai.tool.call.arguments stability: development diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index e7a9d4e391..0352bee453 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -38,10 +38,14 @@ groups: Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. - MCP tool call execution spans are compatible with Gen AI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). - MCP instrumentations MAY suppress their spans when they can detect that - the Gen AI instrumentation is already tracing the tool execution and MAY - provide configuration options to disable tool execution spans. + MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). + + If the MCP instrumentation can reliably detect that outer GenAI instrumentation + is already tracing the tool execution, it SHOULD NOT create a separate span. + Instead, it SHOULD add MCP-specific attributes to the existing tool execution span. + + Instrumentations that support this behavior MAY provide a configuration + option to enable it. stability: development extends: trace.mcp.common.attributes attributes: From cb57baa99189810a3c4ece8dd3c87c06dafe21fc Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Wed, 3 Dec 2025 13:04:18 -0800 Subject: [PATCH 14/22] fix common attributes and links --- docs/gen-ai/mcp.md | 126 +++++++++++++--------------------------- model/gen-ai/spans.yaml | 2 +- model/mcp/common.yaml | 6 -- model/mcp/spans.yaml | 8 ++- 4 files changed, 47 insertions(+), 95 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 942c9107e7..61049aeb97 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -124,7 +124,7 @@ The status description SHOULD match the `JSONRPCError.message` if the message is Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. -MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). +MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans#execute-tool-span). If the MCP instrumentation can reliably detect that outer GenAI instrumentation is already tracing the tool execution, it SHOULD NOT create a separate span. @@ -310,20 +310,18 @@ for more details. | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | -| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [4] | string | The value of the resource uri. [5] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [7] | `65123` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | The name of the GenAI operation being performed. [9] | `execute_tool` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | The name of the GenAI operation being performed. [7] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [10] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [11] | `http`; `websocket` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [12] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [10] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC @@ -336,37 +334,23 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] -> This attribute may contain sensitive information. - -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. - -**[3] `gen_ai.tool.call.result`:** > [!WARNING] -> This attribute may contain sensitive information. - -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. - -**[4] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. -**[5] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. -**[6] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[4] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[7] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[5] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[8] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[6] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[9] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[7] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[10] `mcp.session.id`:** When the MCP request or notification is part of a session. +**[8] `mcp.session.id`:** When the MCP request or notification is part of a session. -**[11] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[9] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[12] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[10] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. @@ -466,19 +450,17 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | -| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | The name of the GenAI operation being performed. [5] | `execute_tool` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [2] | string | The name of the GenAI operation being performed. [3] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [6] | `http`; `websocket` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [7] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [5] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [9] | `80`; `8080`; `443` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [10] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [7] | `80`; `8080`; `443` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [8] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -490,35 +472,21 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] -> This attribute may contain sensitive information. - -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. - -**[3] `gen_ai.tool.call.result`:** > [!WARNING] -> This attribute may contain sensitive information. - -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. - -**[4] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[2] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[5] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[3] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[4] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[7] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[5] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[8] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[6] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[9] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[7] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[10] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[8] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- @@ -614,17 +582,15 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | -| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | The name of the GenAI operation being performed. [5] | `execute_tool` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [2] | string | The name of the GenAI operation being performed. [3] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [6] | `http`; `websocket` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [7] | `tcp`; `quic`; `pipe` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [5] | `tcp`; `quic`; `pipe` | | [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [8] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [6] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -636,31 +602,17 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] -> This attribute may contain sensitive information. - -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. - -**[3] `gen_ai.tool.call.result`:** > [!WARNING] -> This attribute may contain sensitive information. - -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. +**[2] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[4] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[3] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[5] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[4] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[6] `network.protocol.name`:** The value SHOULD be normalized to lowercase. - -**[7] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[5] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[8] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[6] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- diff --git a/model/gen-ai/spans.yaml b/model/gen-ai/spans.yaml index 3d59a07a0e..9cbf6775af 100644 --- a/model/gen-ai/spans.yaml +++ b/model/gen-ai/spans.yaml @@ -310,7 +310,7 @@ groups: GenAI instrumentations that can instrument tool execution calls SHOULD do so, unless another instrumentation can reliably cover all supported tool types. MCP tool executions may also be traced by the - [corresponding MCP instrumentation](/docs/gen-ai/mcp#client). + [corresponding MCP instrumentation](/docs/gen-ai/mcp.md#client). Tools are often executed directly by application code. Application developers are encouraged to follow this semantic convention for tools invoked by their diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index c2eb21653d..081e301e82 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -6,12 +6,6 @@ groups: - ref: gen_ai.tool.name requirement_level: conditionally_required: When operation is related to a specific tool. - - ref: gen_ai.tool.call.arguments - requirement_level: - conditionally_required: When operation describes a tool call. - - ref: gen_ai.tool.call.result - requirement_level: - conditionally_required: When operation describes a tool call. - ref: gen_ai.operation.name brief: The name of the GenAI operation being performed. examples: ["execute_tool"] diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index 0352bee453..eec329d780 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -38,7 +38,7 @@ groups: Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. - MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans##execute-tool-span). + MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans#execute-tool-span). If the MCP instrumentation can reliably detect that outer GenAI instrumentation is already tracing the tool execution, it SHOULD NOT create a separate span. @@ -55,6 +55,12 @@ groups: - ref: server.port requirement_level: recommended: When `server.address` is set + - ref: gen_ai.tool.call.arguments + requirement_level: + conditionally_required: When operation describes a tool call. + - ref: gen_ai.tool.call.result + requirement_level: + conditionally_required: When operation describes a tool call. - id: span.mcp.server type: span From 6b417743858f95224afd6f6012c0fa91875fea1a Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Wed, 3 Dec 2025 13:21:59 -0800 Subject: [PATCH 15/22] lint --- docs/gen-ai/gen-ai-spans.md | 2 +- docs/gen-ai/mcp.md | 16 ++++++++-------- model/mcp/spans.yaml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/gen-ai/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md index 68e0734112..9b0fc97b26 100644 --- a/docs/gen-ai/gen-ai-spans.md +++ b/docs/gen-ai/gen-ai-spans.md @@ -367,7 +367,7 @@ Describes tool execution span. GenAI instrumentations that can instrument tool execution calls SHOULD do so, unless another instrumentation can reliably cover all supported tool types. MCP tool executions may also be traced by the -[corresponding MCP instrumentation](/docs/gen-ai/mcp#client). +[corresponding MCP instrumentation](/docs/gen-ai/mcp.md#client). Tools are often executed directly by application code. Application developers are encouraged to follow this semantic convention for tools invoked by their diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 61049aeb97..591a58371c 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -124,7 +124,7 @@ The status description SHOULD match the `JSONRPCError.message` if the message is Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. -MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans#execute-tool-span). +MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans.md#execute-tool-span). If the MCP instrumentation can reliably detect that outer GenAI instrumentation is already tracing the tool execution, it SHOULD NOT create a separate span. @@ -852,13 +852,13 @@ is HTTP. It SHOULD be set to `pipe` if the transport is stdio. The following table shows how to capture MCP transport and can be used be telemetry consumers to deduce transport type. -| MCP transport | `network.transport` attribute | `network.protocol.*` attributes | `mcp.protocol.version` attribute | comments | -| ------------- | ----------------------------- | ------------------------------- | -------------------------------- | -------- | -| stdio | `pipe` | | any | | -| Streamable HTTP | `tcp` (or `quic`) | `network.protocol.name = http`
`network.protocol.version = 2` | `2025-06-18` or newer | `mcp.protocol.version` distinguishes streamable HTTP from SSE | -| HTTP with SSE | `tcp` (or `quic`) | `network.protocol.name = http`
`network.protocol.version = 1.1` (or 2) | `2024-11-05` or older | `mcp.protocol.version` distinguishes streamable HTTP from SSE | -| Custom: websockets | `tcp` (or another applicable protocol) | `network.protocol.name = websocket` | any | | -| Custom: gRPC | `tcp` (or another applicable protocol) | `network.protocol.name = http`
`network.protocol.version = 2` | any | See [gRPC conventions](/docs/rpc/grpc.md) for additional details | +| MCP transport | `network.transport` attribute | `network.protocol.*` attributes | `mcp.protocol.version` attribute | Comments | +| :----------------- | :------------------------------------- | :-------------------------------------------------------------------------- | :------------------------------- | :--------------------------------------------------------------- | +| stdio | `pipe` | | any | | +| Streamable HTTP | `tcp` (or `quic`) | `network.protocol.name = http`
`network.protocol.version = 2` | `2025-06-18` or newer | `mcp.protocol.version` distinguishes streamable HTTP from SSE | +| HTTP with SSE | `tcp` (or `quic`) | `network.protocol.name = http`
`network.protocol.version = 1.1` (or 2) | `2024-11-05` or older | `mcp.protocol.version` distinguishes streamable HTTP from SSE | +| Custom: websockets | `tcp` (or another applicable protocol) | `network.protocol.name = websocket` | any | | +| Custom: gRPC | `tcp` (or another applicable protocol) | `network.protocol.name = http`
`network.protocol.version = 2` | any | See [gRPC conventions](/docs/rpc/grpc.md) for additional details | Note: Applications may enable instrumentation for the underlying application protocol like HTTP (when applicable) alongside MCP instrumentation to capture additional diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index eec329d780..e4942aaaef 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -38,7 +38,7 @@ groups: Refer to the [Recording Errors](/docs/general/recording-errors.md) document for more details. - MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans#execute-tool-span). + MCP tool call execution spans are compatible with GenAI [execute_tool spans](/docs/gen-ai/gen-ai-spans.md#execute-tool-span). If the MCP instrumentation can reliably detect that outer GenAI instrumentation is already tracing the tool execution, it SHOULD NOT create a separate span. From 0b18d29ebccb5f5af3420715d7c280ef060a3175 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Mon, 15 Dec 2025 16:41:48 -0800 Subject: [PATCH 16/22] add MCP examples and minor fixes --- docs/gen-ai/mcp.md | 325 +++++++++++++++++++++++++++----- docs/registry/attributes/mcp.md | 2 +- model/mcp/registry.yaml | 2 +- model/mcp/spans.yaml | 6 +- 4 files changed, 280 insertions(+), 55 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 591a58371c..dbc08930da 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -25,10 +25,10 @@ linkTitle: Model Context Protocol When instrumenting MCP calls, it's RECOMMENDED to follow MCP conventions instead of [RPC semantic conventions](/docs/rpc/README.md) since MCP spans and metrics provide domain-specific context and record details -that are not covered by the RPC conventions such as message exchange within streaming calls. +that are not covered by the RPC conventions such as message exchanges within streaming calls. -HTTP conventions (when HTTP used as transport) do not adequately cover MCP requests -and notifications either, given that multiple MCP requests could be sent over single +HTTP conventions (when HTTP is used as transport) do not adequately cover MCP requests +and notifications either, given that multiple MCP requests could be sent over a single HTTP request in the corresponding request and response streams. ## Spans @@ -94,6 +94,17 @@ property bag similarly to the following example: } ``` +MCP server instrumentation SHOULD, by default, use context extracted from MCP +`params._meta` as a parent for MCP server span and SHOULD link current ambient +context, if it's present. + +> [!NOTE] +> MCP and underlying transport (such as HTTP) contexts are independent. One MCP +> request can be served by multiple HTTP requests (for example, because of retries) +> and one streamable HTTP request can serve more than one MCP request/notification. +> MCP client becomes a parent of the MCP server span regardless of transport used; +> span links allow recording the transport context (if present). + ### Client @@ -142,21 +153,21 @@ option to enable it. | [`mcp.method.name`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | -| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | Parameters passed to the tool call. [2] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | -| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation describes a tool call. | any | The result returned by the tool call (if any and if execution was successful). [3] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [4] | string | The value of the resource uri. [5] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | The name of the GenAI operation being performed. [7] | `execute_tool` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | The name of the GenAI operation being performed. [5] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http`; `websocket` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [10] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [12] | `80`; `8080`; `443` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [10] | `80`; `8080`; `443` | +| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | Parameters passed to the tool call. [11] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | The result returned by the tool call (if any and if execution was successful). [12] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -168,39 +179,43 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `gen_ai.tool.call.arguments`:** > [!WARNING] -> This attribute may contain sensitive information. +**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. +**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. -**[3] `gen_ai.tool.call.result`:** > [!WARNING] -> This attribute may contain sensitive information. +**[4] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -It's expected to be an object - in case a serialized string is available -to the instrumentation, the instrumentation SHOULD do the best effort to -deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. +**[5] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[4] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[6] `mcp.session.id`:** When the MCP request or notification is part of a session. -**[5] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[6] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[8] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +is HTTP. +It SHOULD be set to `pipe` if the transport is stdio. -**[7] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[9] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[8] `mcp.session.id`:** When the MCP request or notification is part of a session. +**[10] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[9] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[11] `gen_ai.tool.call.arguments`:** -**[10] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol -is HTTP. -It SHOULD be set to `pipe` if the transport is stdio. +> [!WARNING] +> This attribute may contain sensitive information. -**[11] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. -**[12] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[12] `gen_ai.tool.call.result`:** + +> [!WARNING] +> This attribute may contain sensitive information. + +It's expected to be an object - in case a serialized string is available +to the instrumentation, the instrumentation SHOULD do the best effort to +deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. --- @@ -250,7 +265,7 @@ It SHOULD be set to `pipe` if the transport is stdio. | `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | -| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | | `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | | `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | | `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -313,7 +328,7 @@ for more details. | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | | [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | | [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | | [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | The name of the GenAI operation being performed. [7] | `execute_tool` | @@ -322,7 +337,7 @@ for more details. | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [10] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -402,7 +417,7 @@ It SHOULD be set to `pipe` if the transport is stdio. | `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | -| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | | `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | | `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | | `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -451,13 +466,13 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | | [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [2] | string | The name of the GenAI operation being performed. [3] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [5] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [7] | `80`; `8080`; `443` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [8] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | @@ -536,7 +551,7 @@ It SHOULD be set to `pipe` if the transport is stdio. | `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | -| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | | `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | | `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | | `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -583,13 +598,13 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | int | `error.code` property of response if it is an error response. | `-32700`; `100` | +| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | | [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [2] | string | The name of the GenAI operation being performed. [3] | `execute_tool` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [5] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [6] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC @@ -662,7 +677,7 @@ It SHOULD be set to `pipe` if the transport is stdio. | `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | -| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | | `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | | `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | | `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | @@ -710,7 +725,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | @@ -728,7 +743,7 @@ additional filters are applied. If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -793,7 +808,7 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -809,7 +824,7 @@ additional filters are applied. If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. -If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it's RECOMMENDED to: - Use a domain-specific attribute @@ -863,3 +878,215 @@ consumers to deduce transport type. Note: Applications may enable instrumentation for the underlying application protocol like HTTP (when applicable) alongside MCP instrumentation to capture additional transport-level details, such as transport-specific error codes. + +## Examples + +In these examples, we assume that GenAI framework is configured to use MCP tools, +and that tool calls are handled manually, so that GenAI framework does not +instrument corresponding tool calls. + +### Stdio transport + +#### Initialize + +``` +initialize (CLIENT, trace=t1, span=s1) # MCP client +| +-- initialize - (SERVER, trace=t1, span=s2, parent=s1) # MCP server +``` + +MCP client span (`s1`): + +| Property | Value | +| :------------------------------- | :----------------------------------- | +| Span name | `"initialize"` | +| Span kind | `CLIENT` | +| Span status | `UNSET` | +| Attribute `mcp.method.name` | `"initialize"` | +| Attribute `mcp.request.id` | `"1"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.transport` | `"pipe"` | + +MCP server span (`s2`): + +| Property | Value | +| :------------------------------- | :----------------------------------- | +| Span name | `"initialize"` | +| Span kind | `SERVER` | +| Span parent | `s1` (MCP client span) | +| Span status | `UNSET` | +| Attribute `mcp.method.name` | `"initialize"` | +| Attribute `mcp.request.id` | `"1"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.transport` | `"pipe"` | + +#### Tool call + +``` +invoke_agent weather-forecast-agent (INTERNAL, trace=t1, span=s1) # GenAI agent + | + -- chat {model} - (CLIENT, trace=t1, span=s2, parent=s1) # GenAI model client + | + -- tools/call get-weather - (CLIENT, trace=t1, span=s3, parent=s1) # MCP client + | | + | --- tools/call get-weather (SERVER, trace=t1, span=s4, parent=s3) # MCP server + | + -- chat {model} - (CLIENT, trace=t1, span=s5, parent=s1) # GenAI model client +``` + +MCP client span (`s3`): + +| Property | Value | +| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `CLIENT` | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | +| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.transport` | `"pipe"` | + +MCP server span (`s4`): + +| Property | Value | +| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `SERVER` | +| Span parent | `s3` (MCP client span) | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | +| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.transport` | `"pipe"` | + +### Streamable HTTP + +In the HTTP examples, we assume that HTTP instrumentation is enabled on both client +and server side along with the MCP instrumentation. + +#### Initialize + +``` +initialize (CLIENT, trace=t1, span=s1) # MCP client + | + -- POST - (CLIENT, trace=t1, span=s2, parent=s1) # HTTP client + | | + | --- POST - (SERVER, trace=t1, span=s3, parent=s2) # HTTP server + | + -- initialize - (SERVER, trace=t1, span=s4, parent=s1) # MCP server + | + -- HTTP - (CLIENT, trace=t1, span=s5, parent=s1) # HTTP client - notifications channel +``` + +Here, in addition to MCP client and server spans, we see HTTP client (`s3`) +and server (`s4`) spans. MCP server span remains a child of the MCP client span +(`s1`). + +MCP client span (`s1`): + +| Property | Value | +| :----------------------------------- | :----------------------------------- | +| Span name | `"initialize"` | +| Span kind | `CLIENT` | +| Span status | `UNSET` | +| Attribute `mcp.method.name` | `"initialize"` | +| Attribute `mcp.request.id` | `"1"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.protocol.name ` | `"http"` | +| Attribute `network.protocol.version` |`"2"` | +| Attribute `network.transport` | `"tcp"` | + +MCP server span (`s4`): + +| Property | Value | +| :----------------------------------- | :----------------------------------- | +| Span name | `"initialize"` | +| Span kind | `SERVER` | +| Span parent | `s1` (MCP client span) | +| Span links | [`s3`] (HTTP server span) | +| Span status | `UNSET` | +| Attribute `mcp.method.name` | `"initialize"` | +| Attribute `mcp.request.id` | `"1"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.protocol.name ` | `"http"` | +| Attribute `network.protocol.version` | `"2"` | +| Attribute `network.transport` | `"tcp"` | + +#### Tool call + +``` +invoke_agent weather-forecast-agent (INTERNAL, trace=t1, span=s1) # GenAI agent + | + -- chat {model} - (CLIENT, trace=t1, span=s2, parent=s1) # GenAI model + | | + | --- POST (CLIENT, trace=t1, span=s3, parent=s2) # HTTP client + | + -- tools/call get-weather - (CLIENT, trace=t1, span=s4, parent=s1) # MCP client + | | + | --- POST - (CLIENT, trace=t1, span=s5, parent=s4) # HTTP client + | | | + | | ---- POST - (SERVER, trace=t1, span=s6, parent=s5) # HTTP server + | | + | --- tools/call get-weather (SERVER, trace=t1, span=s7, parent=s4) # MCP server + | + -- chat {model} - (CLIENT, trace=t1, span=s8, parent=s1) # GenAI model + | | + | --- POST (CLIENT, trace=t1, span=s9, parent=s8) # HTTP server +``` + +Similarly to HTTP `initialize` example, MCP server (`s7`) span becomes a child of +MCP client span (`s4`). + +MCP client span (`s4`): + +| Property | Value | +| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `CLIENT` | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | +| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.protocol.name ` | `"http"` | +| Attribute `network.protocol.version` | `"2"` | +| Attribute `network.transport` | `"tcp"` | + +MCP server span (`s7`): + +| Property | Value | +| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `SERVER` | +| Span parent | `s4` (MCP client span) | +| Span links | [`s6`] (HTTP server span) | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | +| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.protocol.name ` | `"http"` | +| Attribute `network.protocol.version` | `"2"` | +| Attribute `network.transport` | `"tcp"` | diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index aae0ac9a0c..c8e4cdc188 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -45,7 +45,7 @@ | `resources/read` | Request to read a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/subscribe` | Request to subscribe to a resource. | ![Development](https://img.shields.io/badge/-development-blue) | | `resources/templates/list` | Request to list resource templates available on server. | ![Development](https://img.shields.io/badge/-development-blue) | -| `resources/unsubscribe` | Request to unsubscribe from a resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | +| `resources/unsubscribe` | Request to unsubscribe from resource updates. | ![Development](https://img.shields.io/badge/-development-blue) | | `roots/list` | Request to list roots available on server. | ![Development](https://img.shields.io/badge/-development-blue) | | `sampling/createMessage` | Request to create a sampling message. | ![Development](https://img.shields.io/badge/-development-blue) | | `tools/call` | Request to call a tool. | ![Development](https://img.shields.io/badge/-development-blue) | diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index e12e02bae9..6d537c694a 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -62,7 +62,7 @@ groups: - id: resources_unsubscribe value: resources/unsubscribe brief: > - Request to unsubscribe from a resource updates. + Request to unsubscribe from resource updates. stability: development - id: notifications_resources_updated value: notifications/resources/updated diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index e4942aaaef..c99307749e 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -56,11 +56,9 @@ groups: requirement_level: recommended: When `server.address` is set - ref: gen_ai.tool.call.arguments - requirement_level: - conditionally_required: When operation describes a tool call. + requirement_level: opt_in - ref: gen_ai.tool.call.result - requirement_level: - conditionally_required: When operation describes a tool call. + requirement_level: opt_in - id: span.mcp.server type: span From eb40af1257528e7cfb06608a4f33405ef2ffd928 Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Mon, 15 Dec 2025 16:48:54 -0800 Subject: [PATCH 17/22] update examples and toc --- docs/gen-ai/mcp.md | 133 ++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index dbc08930da..60fd2f5b9e 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -18,6 +18,13 @@ linkTitle: Model Context Protocol - [Metric: `mcp.client.session.duration`](#metric-mcpclientsessionduration) - [Metric: `mcp.server.session.duration`](#metric-mcpserversessionduration) - [Recording MCP transport](#recording-mcp-transport) +- [Examples](#examples) + - [Stdio transport](#stdio-transport) + - [Initialize](#initialize) + - [Tool call](#tool-call) + - [Streamable HTTP](#streamable-http) + - [Initialize](#initialize-1) + - [Tool call](#tool-call-1) @@ -938,38 +945,38 @@ invoke_agent weather-forecast-agent (INTERNAL, trace=t1, span=s1) # GenAI MCP client span (`s3`): -| Property | Value | -| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | -| Span name | `"tools/call get-weather"` | -| Span kind | `CLIENT` | -| Span status | `UNSET` | -| Attribute `gen_ai.operation.name` | `"execute_tool"` | -| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | -| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | -| Attribute `gen_ai.tool.name` | `"get-weather"` | -| Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | -| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | -| Attribute `mcp.protocol.version` | `"2025-06-18"` | -| Attribute `network.transport` | `"pipe"` | +| Property | Value | +| :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `CLIENT` | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.transport` | `"pipe"` | MCP server span (`s4`): -| Property | Value | -| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | -| Span name | `"tools/call get-weather"` | -| Span kind | `SERVER` | -| Span parent | `s3` (MCP client span) | -| Span status | `UNSET` | -| Attribute `gen_ai.operation.name` | `"execute_tool"` | -| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | -| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | -| Attribute `gen_ai.tool.name` | `"get-weather"` | -| Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | -| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | -| Attribute `mcp.protocol.version` | `"2025-06-18"` | -| Attribute `network.transport` | `"pipe"` | +| Property | Value | +| :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `SERVER` | +| Span parent | `s3` (MCP client span) | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.transport` | `"pipe"` | ### Streamable HTTP @@ -1053,40 +1060,40 @@ MCP client span (`s4`). MCP client span (`s4`): -| Property | Value | -| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | -| Span name | `"tools/call get-weather"` | -| Span kind | `CLIENT` | -| Span status | `UNSET` | -| Attribute `gen_ai.operation.name` | `"execute_tool"` | -| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | -| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | -| Attribute `gen_ai.tool.name` | `"get-weather"` | -| Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | -| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | -| Attribute `mcp.protocol.version` | `"2025-06-18"` | -| Attribute `network.protocol.name ` | `"http"` | -| Attribute `network.protocol.version` | `"2"` | -| Attribute `network.transport` | `"tcp"` | +| Property | Value | +| :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `CLIENT` | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.protocol.name ` | `"http"` | +| Attribute `network.protocol.version` | `"2"` | +| Attribute `network.transport` | `"tcp"` | MCP server span (`s7`): -| Property | Value | -| :------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | -| Span name | `"tools/call get-weather"` | -| Span kind | `SERVER` | -| Span parent | `s4` (MCP client span) | -| Span links | [`s6`] (HTTP server span) | -| Span status | `UNSET` | -| Attribute `gen_ai.operation.name` | `"execute_tool"` | -| Attribute `gen_ai.tool.call.arguments` | `{
    "location": "San Francisco?",
    "date": "2025-10-01"
}` (if enabled) | -| Attribute `gen_ai.tool.call.result` | `{
  "temperature_range": {
    "high": 75,
    "low": 60
  }}` (if enabled) | -| Attribute `gen_ai.tool.name` | `"get-weather"` | -| Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | -| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | -| Attribute `mcp.protocol.version` | `"2025-06-18"` | -| Attribute `network.protocol.name ` | `"http"` | -| Attribute `network.protocol.version` | `"2"` | -| Attribute `network.transport` | `"tcp"` | +| Property | Value | +| :------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Span name | `"tools/call get-weather"` | +| Span kind | `SERVER` | +| Span parent | `s4` (MCP client span) | +| Span links | [`s6`] (HTTP server span) | +| Span status | `UNSET` | +| Attribute `gen_ai.operation.name` | `"execute_tool"` | +| Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | +| Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `mcp.method.name` | `"tools/call"` | +| Attribute `mcp.request.id` | `"3"` | +| Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | +| Attribute `mcp.protocol.version` | `"2025-06-18"` | +| Attribute `network.protocol.name ` | `"http"` | +| Attribute `network.protocol.version` | `"2"` | +| Attribute `network.transport` | `"tcp"` | From 56eb31005433166ff5290a7ab9c6d618b434635d Mon Sep 17 00:00:00 2001 From: liudmila molkova Date: Mon, 15 Dec 2025 16:58:29 -0800 Subject: [PATCH 18/22] align with RPC changes, remove mcp.request.id - use jsonrpc one --- docs/gen-ai/mcp.md | 173 ++++++++++++++++++-------------- docs/registry/attributes/mcp.md | 1 - model/mcp/common.yaml | 7 +- model/mcp/metrics.yaml | 4 +- model/mcp/registry.yaml | 6 -- model/mcp/spans.yaml | 2 +- 6 files changed, 101 insertions(+), 92 deletions(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 60fd2f5b9e..e9d593dcb9 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -161,20 +161,20 @@ option to enable it. | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | -| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [4] | string | The name of the GenAI operation being performed. [5] | `execute_tool` | +| [`jsonrpc.request.id`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | A string representation of the `id` property of the request and its corresponding response. [2] | `10`; `request-7` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [3] | string | The value of the resource uri. [4] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | string | The error code from the JSON-RPC response. [5] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | The name of the GenAI operation being performed. [7] | `execute_tool` | +| [`jsonrpc.protocol.version`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [7] | `http`; `websocket` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [8] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [10] | `80`; `8080`; `443` | -| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | Parameters passed to the tool call. [11] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | -| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | The result returned by the tool call (if any and if execution was successful). [12] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [10] | `tcp`; `quic`; `pipe` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [12] | `80`; `8080`; `443` | +| [`gen_ai.tool.call.arguments`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | Parameters passed to the tool call. [13] | {
    "location": "San Francisco?",
    "date": "2025-10-01"
} | +| [`gen_ai.tool.call.result`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | any | The result returned by the tool call (if any and if execution was successful). [14] | {
  "temperature_range": {
    "high": 75,
    "low": 60
  },
  "conditions": "sunny"
} | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -186,27 +186,33 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[2] `jsonrpc.request.id`:** Under the [JSON-RPC specification](https://www.jsonrpc.org/specification), the `id` property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using `null` is not equivalent to omitting the `id`, but it is discouraged. +Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or omitted. -**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[3] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. -**[4] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[4] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. -**[5] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[5] `rpc.response.status_code`:** Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. -**[6] `mcp.session.id`:** When the MCP request or notification is part of a session. +**[6] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[7] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[7] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[8] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[8] `mcp.session.id`:** When the MCP request or notification is part of a session. + +**[9] `network.protocol.name`:** The value SHOULD be normalized to lowercase. + +**[10] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[9] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[11] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[10] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[12] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[11] `gen_ai.tool.call.arguments`:** +**[13] `gen_ai.tool.call.arguments`:** > [!WARNING] > This attribute may contain sensitive information. @@ -215,7 +221,7 @@ It's expected to be an object - in case a serialized string is available to the instrumentation, the instrumentation SHOULD do the best effort to deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise. -**[12] `gen_ai.tool.call.result`:** +**[14] `gen_ai.tool.call.result`:** > [!WARNING] > This attribute may contain sensitive information. @@ -333,18 +339,18 @@ for more details. | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | -| [`mcp.request.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | This is a unique identifier for the request. | `42` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [2] | string | The value of the resource uri. [3] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | -| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [5] | `65123` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [6] | string | The name of the GenAI operation being performed. [7] | `execute_tool` | +| [`jsonrpc.request.id`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When the client executes a request. | string | A string representation of the `id` property of the request and its corresponding response. [2] | `10`; `request-7` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [3] | string | The value of the resource uri. [4] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | string | The error code from the JSON-RPC response. [5] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`client.address`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `client.example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`client.port`](/docs/registry/attributes/client.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `client.address` is set | int | Client port number. [7] | `65123` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | The name of the GenAI operation being performed. [9] | `execute_tool` | +| [`jsonrpc.protocol.version`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [8] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [9] | `http`; `websocket` | +| [`mcp.session.id`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [10] | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [11] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [10] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [12] | `tcp`; `quic`; `pipe` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -356,23 +362,29 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. +**[2] `jsonrpc.request.id`:** Under the [JSON-RPC specification](https://www.jsonrpc.org/specification), the `id` property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using `null` is not equivalent to omitting the `id`, but it is discouraged. +Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or omitted. -**[3] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[3] `mcp.resource.uri`:** When the client executes a request type that includes a resource URI parameter. -**[4] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +**[4] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. -**[5] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +**[5] `rpc.response.status_code`:** Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. -**[6] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[6] `client.address`:** When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -**[7] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[7] `client.port`:** When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -**[8] `mcp.session.id`:** When the MCP request or notification is part of a session. +**[8] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[9] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[9] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[10] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[10] `mcp.session.id`:** When the MCP request or notification is part of a session. + +**[11] `network.protocol.name`:** The value SHOULD be normalized to lowercase. + +**[12] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. @@ -473,16 +485,16 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [2] | string | The name of the GenAI operation being performed. [3] | `execute_tool` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | string | The error code from the JSON-RPC response. [2] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [3] | string | The name of the GenAI operation being performed. [4] | `execute_tool` | +| [`jsonrpc.protocol.version`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http`; `websocket` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [5] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | -| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [7] | `80`; `8080`; `443` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [8] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `quic`; `pipe` | +| [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | +| [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [8] | `80`; `8080`; `443` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [9] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -494,21 +506,24 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[2] `rpc.response.status_code`:** Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. -**[3] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[3] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[4] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[4] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[5] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[5] `network.protocol.name`:** The value SHOULD be normalized to lowercase. + +**[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[6] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +**[7] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -**[7] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +**[8] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -**[8] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[9] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- @@ -605,14 +620,14 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if the operation fails. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | | [`gen_ai.prompt.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific prompt. | string | The name of the prompt or prompt template provided in the request or response. | `analyze-code` | | [`gen_ai.tool.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | `Flights` | -| [`rpc.jsonrpc.error_code`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Use string representation of the error code on the `rpc.response.status_code` attribute. | `Conditionally Required` If response contains an error code. | int | Deprecated, use string representation on the `rpc.response.status_code` attribute instead. | `-32700`; `100` | -| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [2] | string | The name of the GenAI operation being performed. [3] | `execute_tool` | +| [`rpc.response.status_code`](/docs/registry/attributes/rpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If response contains an error code. | string | The error code from the JSON-RPC response. [2] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | +| [`gen_ai.operation.name`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` [3] | string | The name of the GenAI operation being performed. [4] | `execute_tool` | +| [`jsonrpc.protocol.version`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [4] | `http`; `websocket` | +| [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [5] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | -| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [5] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | -| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [6] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | +| [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [6] | `tcp`; `quic`; `pipe` | +| [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [7] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. @@ -624,17 +639,20 @@ string representation of the error. When is returned with `isError` set to `true`, this attribute SHOULD be set to `tool_error`. -**[2] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. +**[2] `rpc.response.status_code`:** Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. + +**[3] `gen_ai.operation.name`:** SHOULD be set to `execute_tool` when the operation describes a tool call and SHOULD NOT be set otherwise. -**[3] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. +**[4] `gen_ai.operation.name`:** Populating this attribute for tool calling along with `mcp.method.name` allows consumers to treat MCP tool calls spans similarly with other tool call types. -**[4] `network.protocol.name`:** The value SHOULD be normalized to lowercase. +**[5] `network.protocol.name`:** The value SHOULD be normalized to lowercase. -**[5] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol +**[6] `network.transport`:** This attribute SHOULD be set to `tcp` or `quic` if the transport protocol is HTTP. It SHOULD be set to `pipe` if the transport is stdio. -**[6] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. +**[7] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- @@ -728,11 +746,11 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | | --- | --- | --- | --- | --- | --- | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`jsonrpc.protocol.version`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | | [`server.address`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` If applicable | string | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | | [`server.port`](/docs/registry/attributes/server.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When `server.address` is set | int | Server port number. [5] | `80`; `8080`; `443` | @@ -811,11 +829,11 @@ of `[ 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300 ]`. | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | | --- | --- | --- | --- | --- | --- | | [`error.type`](/docs/registry/attributes/error.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If and only if session ends with an error. | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | +| [`jsonrpc.protocol.version`](/docs/registry/attributes/jsonrpc.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` when it's not `2.0`. | string | Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. | `2.0`; `1.0` | | [`mcp.protocol.version`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | | [`network.protocol.name`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | [OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. [2] | `http`; `websocket` | | [`network.protocol.version`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` When applicable. | string | The actual version of the protocol used for network communication. | `1.1`; `2` | | [`network.transport`](/docs/registry/attributes/network.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Recommended` | string | The transport protocol used for the MCP session. [3] | `tcp`; `quic`; `pipe` | -| [`rpc.jsonrpc.version`](/docs/registry/attributes/rpc.md) | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `jsonrpc.protocol.version`. | `Recommended` when it's not `2.0`. | string | The version of JSON-RPC protocol used. | `2.0`; `1.0` | **[1] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality. @@ -909,8 +927,8 @@ MCP client span (`s1`): | Span name | `"initialize"` | | Span kind | `CLIENT` | | Span status | `UNSET` | +| Attribute `jsonrpc.request.id` | `"1"` | | Attribute `mcp.method.name` | `"initialize"` | -| Attribute `mcp.request.id` | `"1"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.transport` | `"pipe"` | @@ -923,8 +941,8 @@ MCP server span (`s2`): | Span kind | `SERVER` | | Span parent | `s1` (MCP client span) | | Span status | `UNSET` | +| Attribute `jsonrpc.request.id` | `"1"` | | Attribute `mcp.method.name` | `"initialize"` | -| Attribute `mcp.request.id` | `"1"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.transport` | `"pipe"` | @@ -954,8 +972,8 @@ MCP client span (`s3`): | Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | | Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | | Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `jsonrpc.request.id` | `"3"` | | Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.transport` | `"pipe"` | @@ -972,8 +990,8 @@ MCP server span (`s4`): | Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | | Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | | Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `jsonrpc.request.id` | `"3"` | | Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.transport` | `"pipe"` | @@ -1008,6 +1026,7 @@ MCP client span (`s1`): | Span name | `"initialize"` | | Span kind | `CLIENT` | | Span status | `UNSET` | +| Attribute `jsonrpc.request.id` | `"1"` | | Attribute `mcp.method.name` | `"initialize"` | | Attribute `mcp.request.id` | `"1"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | @@ -1025,8 +1044,8 @@ MCP server span (`s4`): | Span parent | `s1` (MCP client span) | | Span links | [`s3`] (HTTP server span) | | Span status | `UNSET` | +| Attribute `jsonrpc.request.id` | `"1"` | | Attribute `mcp.method.name` | `"initialize"` | -| Attribute `mcp.request.id` | `"1"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.protocol.name ` | `"http"` | @@ -1069,8 +1088,8 @@ MCP client span (`s4`): | Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | | Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | | Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `jsonrpc.request.id` | `"3"` | | Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.protocol.name ` | `"http"` | @@ -1090,8 +1109,8 @@ MCP server span (`s7`): | Attribute `gen_ai.tool.call.arguments` | (if enabled)
{
    "location": "San Francisco?",
    "date": "2025-10-01"
} | | Attribute `gen_ai.tool.call.result` | (if enabled)
{
  "temperature_range": {
    "high": 75,
    "low": 60
  }
} | | Attribute `gen_ai.tool.name` | `"get-weather"` | +| Attribute `jsonrpc.request.id` | `"3"` | | Attribute `mcp.method.name` | `"tools/call"` | -| Attribute `mcp.request.id` | `"3"` | | Attribute `mcp.session.id` | `"8267461134f24305af708e66b8eda71a"` | | Attribute `mcp.protocol.version` | `"2025-06-18"` | | Attribute `network.protocol.name ` | `"http"` | diff --git a/docs/registry/attributes/mcp.md b/docs/registry/attributes/mcp.md index c8e4cdc188..5f920d4193 100644 --- a/docs/registry/attributes/mcp.md +++ b/docs/registry/attributes/mcp.md @@ -13,7 +13,6 @@ | --- | --- | --- | --- | --- | | `mcp.method.name` | ![Development](https://img.shields.io/badge/-development-blue) | string | The name of the request or notification method. | `notifications/cancelled`; `initialize`; `notifications/initialized` | | `mcp.protocol.version` | ![Development](https://img.shields.io/badge/-development-blue) | string | The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. | `2025-06-18` | -| `mcp.request.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | This is a unique identifier for the request. | `42` | | `mcp.resource.uri` | ![Development](https://img.shields.io/badge/-development-blue) | string | The value of the resource uri. [1] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | | `mcp.session.id` | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). | `191c4850af6c49e08843a3f6c80e5046` | diff --git a/model/mcp/common.yaml b/model/mcp/common.yaml index 081e301e82..16c307224a 100644 --- a/model/mcp/common.yaml +++ b/model/mcp/common.yaml @@ -44,7 +44,8 @@ groups: - ref: mcp.method.name requirement_level: required - ref: mcp.protocol.version - - ref: rpc.jsonrpc.error_code # todo: this is being unified in https://github.com/open-telemetry/semantic-conventions/pull/2920 + - ref: rpc.response.status_code + brief: The error code from the JSON-RPC response. requirement_level: conditionally_required: If response contains an error code. - ref: network.protocol.name @@ -57,8 +58,6 @@ groups: note: "" # overriding the default note requirement_level: recommended: When applicable. - - ref: rpc.jsonrpc.version - brief: The version of JSON-RPC protocol used. - note: "" # overriding the default note + - ref: jsonrpc.protocol.version requirement_level: recommended: when it's not `2.0`. diff --git a/model/mcp/metrics.yaml b/model/mcp/metrics.yaml index e1e1f82f50..68a482a9c3 100644 --- a/model/mcp/metrics.yaml +++ b/model/mcp/metrics.yaml @@ -22,9 +22,7 @@ groups: note: "" # overriding the default note requirement_level: recommended: When applicable. - - ref: rpc.jsonrpc.version - brief: The version of JSON-RPC protocol used. - note: "" # overriding the default note + - ref: jsonrpc.protocol.version requirement_level: recommended: when it's not `2.0`. - ref: network.transport diff --git a/model/mcp/registry.yaml b/model/mcp/registry.yaml index 6d537c694a..fa4455a7f8 100644 --- a/model/mcp/registry.yaml +++ b/model/mcp/registry.yaml @@ -135,12 +135,6 @@ groups: Request from the server to elicit additional information from the user via the client stability: development - - id: mcp.request.id - type: string - brief: > - This is a unique identifier for the request. - stability: development - examples: ["42"] - id: mcp.session.id type: string brief: Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml index c99307749e..bab682a14b 100644 --- a/model/mcp/spans.yaml +++ b/model/mcp/spans.yaml @@ -10,7 +10,7 @@ groups: - ref: mcp.resource.uri requirement_level: conditionally_required: When the client executes a request type that includes a resource URI parameter. - - ref: mcp.request.id + - ref: jsonrpc.request.id requirement_level: conditionally_required: When the client executes a request. From c0bb7782cc1070a5b6c42df4f6af4503c15214df Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 29 Dec 2025 11:42:20 -0800 Subject: [PATCH 19/22] Update docs/gen-ai/mcp.md Co-authored-by: Aaron Abbott --- docs/gen-ai/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index e9d593dcb9..6478ccc953 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -43,7 +43,7 @@ HTTP request in the corresponding request and response streams. ### Context propagation Model Context Protocol works on top of JSON-RPC and does not define a standard -Trace Context propagation mechanism. MCP is transport independent and works across different transports. The specification expects clients to implement at least stdio or HTTP streams. +Trace Context propagation mechanism. MCP is transport independent and works across different transports. The specification expects clients to implement at least stdio or Streamable HTTP. HTTP trace context propagation only covers the HTTP request, but not the individual messages client and server exchange within the request/response streams. From 8c2ea8445ef9a257946c102c014ea7a41eadb388 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 29 Dec 2025 11:42:49 -0800 Subject: [PATCH 20/22] Update docs/gen-ai/mcp.md Co-authored-by: Aaron Abbott --- docs/gen-ai/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 6478ccc953..57cfd64504 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -48,7 +48,7 @@ Trace Context propagation mechanism. MCP is transport independent and works acro HTTP trace context propagation only covers the HTTP request, but not the individual messages client and server exchange within the request/response streams. -Instrumentations SHOULD propagate trace context inside MCP request `params._meta` +Instrumentations SHOULD propagate trace context inside MCP request [`params._meta`](https://modelcontextprotocol.io/specification/2025-11-25/basic#_meta) property bag. > [!NOTE] From a364cc78f17370d9470300255c7a3831e14aed73 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 29 Dec 2025 11:43:08 -0800 Subject: [PATCH 21/22] Update docs/gen-ai/mcp.md Co-authored-by: Aaron Abbott --- docs/gen-ai/mcp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index 57cfd64504..4518e4e5bc 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -109,7 +109,7 @@ context, if it's present. > MCP and underlying transport (such as HTTP) contexts are independent. One MCP > request can be served by multiple HTTP requests (for example, because of retries) > and one streamable HTTP request can serve more than one MCP request/notification. -> MCP client becomes a parent of the MCP server span regardless of transport used; +> The MCP client span becomes a parent of the MCP server span regardless of transport used; > span links allow recording the transport context (if present). ### Client From da7ba27c3df2d401ad91b9a3856232bc15f9b370 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Mon, 29 Dec 2025 11:45:36 -0800 Subject: [PATCH 22/22] review --- docs/gen-ai/mcp.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md index e9d593dcb9..312e47522f 100644 --- a/docs/gen-ai/mcp.md +++ b/docs/gen-ai/mcp.md @@ -1017,7 +1017,8 @@ initialize (CLIENT, trace=t1, span=s1) # MCP client Here, in addition to MCP client and server spans, we see HTTP client (`s3`) and server (`s4`) spans. MCP server span remains a child of the MCP client span -(`s1`). +(`s1`) and has a link to HTTP server span (`s3`) that was current when MCP server +span started. MCP client span (`s1`):