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 70c40c5469..70a9d2e5dd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -105,6 +105,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 72dd7fbd48..760104a9c6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -68,6 +68,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 9920af2bc9..713fa0d4e2 100644 --- a/.github/ISSUE_TEMPLATE/change_proposal.yaml +++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml @@ -60,6 +60,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 007cbe2ddd..e75cc16afb 100644 --- a/.github/ISSUE_TEMPLATE/new-conventions.yaml +++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml @@ -71,6 +71,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 0b78b5f191..b23d7433b1 100644 --- a/AREAS.md +++ b/AREAS.md @@ -28,7 +28,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`, `area:container`, `area:oci` | `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-phase-2.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`, `area:dns`, `area:file`, `area:tls`, `area:network`, `area:process` | `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 de54794d0c..ffb47d536d 100644 --- a/areas.yaml +++ b/areas.yaml @@ -42,6 +42,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 9d927cfc94..19921b967e 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/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md index c4e10aaa7f..96ffadc8f6 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.md#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`. diff --git a/docs/gen-ai/mcp.md b/docs/gen-ai/mcp.md new file mode 100644 index 0000000000..0ff7b1342b --- /dev/null +++ b/docs/gen-ai/mcp.md @@ -0,0 +1,1119 @@ + + +# 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) +- [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) + + + +[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 exchanges within streaming calls. + +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 + +### 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 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. + +Instrumentations SHOULD propagate trace context inside MCP request [`params._meta`](https://modelcontextprotocol.io/specification/2025-11-25/basic#_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, +} +``` + +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. +> 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 + + + + + + +**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 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}`. + +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` 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. + +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. +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`. + +**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.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` | +| [`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` [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. [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. + +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] `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`:** When the client executes a request type that includes a resource URI parameter. + +**[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] `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. + +**[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] `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. + +**[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. + +**[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. + +**[13] `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. + +**[14] `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. + +--- + +`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) | + +--- + +`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 | +| --- | --- | --- | +| `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 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 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}`. + +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` 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. + +**Span kind** SHOULD be `SERVER`. + +**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.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` | +| [`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` [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. [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. + +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] `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`:** When the client executes a request type that includes a resource URI parameter. + +**[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] `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] `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. + +**[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] `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. + +--- + +`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) | + +--- + +`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 | +| --- | --- | --- | +| `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 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.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.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.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.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. [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` | +| [`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. + +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] `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. + +**[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.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. + +**[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.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) | + +--- + +`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 | +| --- | --- | --- | +| `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 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/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.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.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.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. [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` | +| [`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. + +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] `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. + +**[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.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. + +**[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`. + +--- + +`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) | + +--- + +`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 | +| --- | --- | --- | +| `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 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) | | + +**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` | +| [`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` | +| [`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. + +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 RPC 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.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. 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. + +**[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. + +--- + +`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) | | + +**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` | +| [`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` | + +**[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 RPC 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.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. 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 | +| --- | --- | --- | +| `_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 + +## 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. + +## 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 `jsonrpc.request.id` | `"1"` | +| Attribute `mcp.method.name` | `"initialize"` | +| 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 `jsonrpc.request.id` | `"1"` | +| Attribute `mcp.method.name` | `"initialize"` | +| 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` | (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.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` | (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.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`) and has a link to HTTP server span (`s3`) that was current when MCP server +span started. + +MCP client span (`s1`): + +| Property | Value | +| :----------------------------------- | :----------------------------------- | +| 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.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 `jsonrpc.request.id` | `"1"` | +| Attribute `mcp.method.name` | `"initialize"` | +| 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` | (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.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` | (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.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/README.md b/docs/registry/attributes/README.md index e08766db04..b3ebffa36e 100644 --- a/docs/registry/attributes/README.md +++ b/docs/registry/attributes/README.md @@ -79,6 +79,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/gen-ai.md b/docs/registry/attributes/gen-ai.md index 34a73fa908..bec186d9cc 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 new file mode 100644 index 0000000000..5f920d4193 --- /dev/null +++ b/docs/registry/attributes/mcp.md @@ -0,0 +1,51 @@ + + + +# MCP + +## MCP Attributes + +[Model Context Protocol (MCP)](https://modelcontextprotocol.io) attributes + +**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.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.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 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/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/gen-ai/spans.yaml b/model/gen-ai/spans.yaml index 542de5fdff..9cbf6775af 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.md#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 new file mode 100644 index 0000000000..16c307224a --- /dev/null +++ b/model/mcp/common.yaml @@ -0,0 +1,63 @@ +groups: + - id: mcp.common.attributes + type: attribute_group + brief: Common MCP attributes + attributes: + - ref: gen_ai.tool.name + requirement_level: + conditionally_required: When operation is related to a specific tool. + - 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: + 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. + examples: ["tcp", "quic", "pipe"] + - 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: mcp.protocol.version + - 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 + requirement_level: + recommended: When applicable. + examples: + - "http" + - "websocket" + - ref: network.protocol.version + note: "" # overriding the default note + requirement_level: + recommended: When applicable. + - 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 new file mode 100644 index 0000000000..68a482a9c3 --- /dev/null +++ b/model/mcp/metrics.yaml @@ -0,0 +1,90 @@ +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: 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: jsonrpc.protocol.version + 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. + examples: ["tcp", "quic", "pipe"] + - 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 + requirement_level: + recommended: If applicable + - 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 + requirement_level: + recommended: If applicable + - 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..fa4455a7f8 --- /dev/null +++ b/model/mcp/registry.yaml @@ -0,0 +1,155 @@ +groups: + - id: registry.mcp + type: attribute_group + brief: > + [Model Context Protocol (MCP)](https://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 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.session.id + type: string + brief: Identifies [MCP session](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management). + stability: development + examples: ["191c4850af6c49e08843a3f6c80e5046"] + - 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.protocol.version + type: string + brief: The [version](https://modelcontextprotocol.io/specification/versioning) of the Model Context Protocol used. + stability: development + examples: ["2025-06-18"] diff --git a/model/mcp/spans.yaml b/model/mcp/spans.yaml new file mode 100644 index 0000000000..bab682a14b --- /dev/null +++ b/model/mcp/spans.yaml @@ -0,0 +1,95 @@ +groups: + - id: trace.mcp.common.attributes + type: attribute_group + extends: mcp.common.attributes + 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: jsonrpc.request.id + requirement_level: + conditionally_required: When the client executes a request. + + - 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 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}`. + + 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` 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. + + 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. + 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: + - ref: server.address + requirement_level: + recommended: If applicable + - ref: server.port + requirement_level: + recommended: When `server.address` is set + - ref: gen_ai.tool.call.arguments + requirement_level: opt_in + - ref: gen_ai.tool.call.result + requirement_level: opt_in + + - 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 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}`. + + 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` 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. + stability: development + extends: trace.mcp.common.attributes + attributes: + - ref: client.address + requirement_level: + recommended: If applicable + + - 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 1471999c5a..656281f909 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