# 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](https://github.com/open-telemetry/semantic-conventions/blob/v1.40.0/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. 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 context using the configured [OpenTelemetry propagators](https://opentelemetry.io/docs/specs/otel/context/api-propagators/) by injecting it into the MCP request [`params._meta`](https://modelcontextprotocol.io/specification/2025-11-25/basic#_meta) property bag when creating a request or notification. The receiver extracts the context from `params._meta` and uses it as the remote parent. Although the MCP convention expects keys in `params._meta` to be DNS-prefixed, the context propagation keys SHOULD be written unprefixed. [SEP-414](https://modelcontextprotocol.io/community/seps/414-request-meta) defines this explicit handling for the W3C Trace Context and Baggage keys (`traceparent`, `tracestate`, and `baggage`). Here's an example of a tool call request with injected [W3C Trace Context](https://www.w3.org/TR/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, } ``` If the application also uses [W3C Baggage](https://www.w3.org/TR/baggage/), propagate `baggage` in the same `params._meta` property bag, as in 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](https://github.com/open-telemetry/semantic-conventions/blob/v1.41.0/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`. **Requirement level:** [Recommended](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/signal-requirement-level.md). **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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/docs/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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.prompt.variable`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The variables supplied to the prompt template in the request. [13] | `Alice`; `French` | | [`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. [14] | {
    "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). [15] | {
  "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.prompt.variable`:** Prompt templates are parameterized with variables that are filled in at runtime. This attribute records the variable values passed to the template. The attribute name defines the variable name, and the attribute value is the variable value serialized as a string. Examples: - A variable `user_name` with value `Alice` SHOULD be recorded as the `gen_ai.prompt.variable.user_name` attribute with value `"Alice"`. - A variable `language` with value `French` SHOULD be recorded as the `gen_ai.prompt.variable.language` attribute with value `"French"`. In MCP, [prompt arguments](https://modelcontextprotocol.io/specification/2025-11-25/schema#prompt) supplied in `prompts/get` requests SHOULD be recorded as `gen_ai.prompt.variable.` attributes. > [!Warning] > This attribute may contain sensitive information. **[14] `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. Instrumentations MUST follow [JSON schema](/model/gen-ai/gen-ai-tool-call-arguments.json). When the attribute is recorded on events, it MUST be recorded in structured form. 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. **[15] `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. Instrumentations MUST follow [JSON schema](/model/gen-ai/gen-ai-tool-call-result.json). When the attribute is recorded on events, it MUST be recorded in structured form. 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) | | `create_memory` | Create new memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `create_memory_store` | Create or initialize a memory store | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory` | Delete memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory_store` | Delete or deprovision a memory store | ![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) | | `invoke_workflow` | Invoke GenAI workflow | ![Development](https://img.shields.io/badge/-development-blue) | | `plan` | Agent planning or task decomposition phase | ![Development](https://img.shields.io/badge/-development-blue) | | `retrieval` | Retrieval operation such as [OpenAI Search Vector Store API](https://platform.openai.com/docs/api-reference/vector-stores/search) | ![Development](https://img.shields.io/badge/-development-blue) | | `search_memory` | Search/query memories from a memory store | ![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) | | `update_memory` | Update existing memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `upsert_memory` | Create or update memory records without the caller choosing which | ![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](https://github.com/open-telemetry/semantic-conventions/blob/v1.41.0/docs/general/recording-errors.md) document for more details. **Span kind** SHOULD be `SERVER`. **Requirement level:** [Recommended](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/signal-requirement-level.md). **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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/docs/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `Conditionally Required` If response contains an error code. | string | The error code from the JSON-RPC response. [5] | `OK`; `DEADLINE_EXCEEDED`; `-32602` | | [`client.address`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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` | | [`gen_ai.prompt.variable`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The variables supplied to the prompt template in the request. [13] | `Alice`; `French` | | [`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. [14] | {
    "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). [15] | {
  "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] `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. **[13] `gen_ai.prompt.variable`:** Prompt templates are parameterized with variables that are filled in at runtime. This attribute records the variable values passed to the template. The attribute name defines the variable name, and the attribute value is the variable value serialized as a string. Examples: - A variable `user_name` with value `Alice` SHOULD be recorded as the `gen_ai.prompt.variable.user_name` attribute with value `"Alice"`. - A variable `language` with value `French` SHOULD be recorded as the `gen_ai.prompt.variable.language` attribute with value `"French"`. In MCP, [prompt arguments](https://modelcontextprotocol.io/specification/2025-11-25/schema#prompt) supplied in `prompts/get` requests SHOULD be recorded as `gen_ai.prompt.variable.` attributes. > [!Warning] > This attribute may contain sensitive information. **[14] `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. Instrumentations MUST follow [JSON schema](/model/gen-ai/gen-ai-tool-call-arguments.json). When the attribute is recorded on events, it MUST be recorded in structured form. 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. **[15] `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. Instrumentations MUST follow [JSON schema](/model/gen-ai/gen-ai-tool-call-result.json). When the attribute is recorded on events, it MUST be recorded in structured form. 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) | | `create_memory` | Create new memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `create_memory_store` | Create or initialize a memory store | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory` | Delete memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory_store` | Delete or deprovision a memory store | ![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) | | `invoke_workflow` | Invoke GenAI workflow | ![Development](https://img.shields.io/badge/-development-blue) | | `plan` | Agent planning or task decomposition phase | ![Development](https://img.shields.io/badge/-development-blue) | | `retrieval` | Retrieval operation such as [OpenAI Search Vector Store API](https://platform.openai.com/docs/api-reference/vector-stores/search) | ![Development](https://img.shields.io/badge/-development-blue) | | `search_memory` | Search/query memories from a memory store | ![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) | | `update_memory` | Update existing memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `upsert_memory` | Create or update memory records without the caller choosing which | ![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 SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.55.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) | | **Requirement level:** [Recommended](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/signal-requirement-level.md). **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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/docs/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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` | | [`gen_ai.prompt.variable`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The variables supplied to the prompt template in the request. [9] | `Alice`; `French` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [10] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. 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] `gen_ai.prompt.variable`:** Prompt templates are parameterized with variables that are filled in at runtime. This attribute records the variable values passed to the template. The attribute name defines the variable name, and the attribute value is the variable value serialized as a string. Examples: - A variable `user_name` with value `Alice` SHOULD be recorded as the `gen_ai.prompt.variable.user_name` attribute with value `"Alice"`. - A variable `language` with value `French` SHOULD be recorded as the `gen_ai.prompt.variable.language` attribute with value `"French"`. > [!Warning] > This attribute may contain sensitive information. **[10] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | | --- | --- | --- | | `_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) | | `create_memory` | Create new memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `create_memory_store` | Create or initialize a memory store | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory` | Delete memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory_store` | Delete or deprovision a memory store | ![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) | | `invoke_workflow` | Invoke GenAI workflow | ![Development](https://img.shields.io/badge/-development-blue) | | `plan` | Agent planning or task decomposition phase | ![Development](https://img.shields.io/badge/-development-blue) | | `retrieval` | Retrieval operation such as [OpenAI Search Vector Store API](https://platform.openai.com/docs/api-reference/vector-stores/search) | ![Development](https://img.shields.io/badge/-development-blue) | | `search_memory` | Search/query memories from a memory store | ![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) | | `update_memory` | Update existing memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `upsert_memory` | Create or update memory records without the caller choosing which | ![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 SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.55.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) | | **Requirement level:** [Recommended](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/signal-requirement-level.md). **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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/docs/registry/attributes/rpc.md) | ![Release Candidate](https://img.shields.io/badge/-rc-mediumorchid) | `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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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` | | [`gen_ai.prompt.variable`](/docs/registry/attributes/gen-ai.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The variables supplied to the prompt template in the request. [7] | `Alice`; `French` | | [`mcp.resource.uri`](/docs/registry/attributes/mcp.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | The value of the resource uri. [8] | `postgres://database/customers/schema`; `file:///home/user/documents/report.pdf` | **[1] `error.type`:** This attribute SHOULD be set to the string representation of the JSON-RPC error code, if one is returned. 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] `gen_ai.prompt.variable`:** Prompt templates are parameterized with variables that are filled in at runtime. This attribute records the variable values passed to the template. The attribute name defines the variable name, and the attribute value is the variable value serialized as a string. Examples: - A variable `user_name` with value `Alice` SHOULD be recorded as the `gen_ai.prompt.variable.user_name` attribute with value `"Alice"`. - A variable `language` with value `French` SHOULD be recorded as the `gen_ai.prompt.variable.language` attribute with value `"French"`. > [!Warning] > This attribute may contain sensitive information. **[8] `mcp.resource.uri`:** This is a URI of the resource provided in the following requests or notifications: `resources/read`, `resources/subscribe`, `resources/unsubscribe`, or `notifications/resources/updated`. --- `error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. | Value | Description | Stability | | --- | --- | --- | | `_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) | | `create_memory` | Create new memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `create_memory_store` | Create or initialize a memory store | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory` | Delete memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `delete_memory_store` | Delete or deprovision a memory store | ![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) | | `invoke_workflow` | Invoke GenAI workflow | ![Development](https://img.shields.io/badge/-development-blue) | | `plan` | Agent planning or task decomposition phase | ![Development](https://img.shields.io/badge/-development-blue) | | `retrieval` | Retrieval operation such as [OpenAI Search Vector Store API](https://platform.openai.com/docs/api-reference/vector-stores/search) | ![Development](https://img.shields.io/badge/-development-blue) | | `search_memory` | Search/query memories from a memory store | ![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) | | `update_memory` | Update existing memory records | ![Development](https://img.shields.io/badge/-development-blue) | | `upsert_memory` | Create or update memory records without the caller choosing which | ![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 SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.55.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) | | **Requirement level:** [Recommended](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/signal-requirement-level.md). **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | | --- | --- | --- | --- | --- | --- | | [`error.type`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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. If the recorded error type is a wrapper that is not meaningful for failure classification, instrumentation MAY use the type of the inner error instead. For example, in Go, errors created with `fmt.Errorf` using `%w` MAY be unwrapped when the wrapper type does not help classify the failure. 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 SHOULD be specified with [`ExplicitBucketBoundaries`](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.55.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) | | **Requirement level:** [Recommended](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/signal-requirement-level.md). **Attributes:** | Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values | | --- | --- | --- | --- | --- | --- | | [`error.type`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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`](https://github.com/open-telemetry/semantic-conventions/blob/v1.43.0/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. If the recorded error type is a wrapper that is not meaningful for failure classification, instrumentation MAY use the type of the inner error instead. For example, in Go, errors created with `fmt.Errorf` using `%w` MAY be unwrapped when the wrapper type does not help classify the failure. 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 ## 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](https://github.com/open-telemetry/semantic-conventions/blob/v1.40.0/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"` |