Semantic conventions for Model Context Protocol (MCP)
Status: Development
Model Context Protocol (MCP) is based on JSON RPC.
When instrumenting MCP calls, it’s RECOMMENDED to follow MCP conventions instead of RPC semantic conventions since MCP spans and metrics provide domain-specific context and record details that are not covered by the RPC conventions such as message exchanges within streaming calls.
HTTP conventions (when HTTP is used as transport) do not adequately cover MCP requests and notifications either, given that multiple MCP requests could be sent over a single HTTP request in the corresponding request and response streams.
Spans
Context propagation
Model Context Protocol works on top of JSON-RPC and does not define a standard Trace Context propagation mechanism. MCP is transport independent and works across different transports. The specification expects clients to implement at least stdio or Streamable HTTP.
HTTP trace context propagation only covers the HTTP request, but not the individual messages client and server exchange within the request/response streams.
Instrumentations SHOULD propagate trace context inside MCP request params._meta
property bag.
The propagation format defined here is likely to change. Please check out context propagation discussions in MCP repository: modelcontextprotocol#246 and modelcontextprotocol#414.
If the MCP or JSON-RPC specifications provide official guidance, instrumentations SHOULD prioritize that over the recommendation provided in this section.
For example, when using W3C Trace Context propagation,
inject traceparent and tracestate to the MCP message params._meta when creating request
or notification and extract them on the receiver side to use as the remote parent.
Here’s an example of tool call request with injected trace context.
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get-weather",
"_meta": {
"traceparent": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
"tracestate": "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"
}
},
"id": 1,
}
Or, if user application uses W3C Baggage in addition
to the Trace-Context, baggage should be propagated in the same params._meta
property bag similarly to the following example:
{
"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.
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:
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 document for more details.
MCP tool call execution spans are compatible with GenAI execute_tool spans.
If the MCP instrumentation can reliably detect that outer GenAI instrumentation is already tracing the tool execution, it SHOULD NOT create a separate span. Instead, it SHOULD add MCP-specific attributes to the existing tool execution span.
Instrumentations that support this behavior MAY provide a configuration option to enable it.
Span kind SHOULD be CLIENT.
Attributes:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
mcp.method.name | Required | string | The name of the request or notification method. | notifications/cancelled; initialize; notifications/initialized | |
error.type | 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 | 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 | Conditionally Required When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | Flights | |
jsonrpc.request.id | 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 | 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 | 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 | Recommended [6] | string | The name of the GenAI operation being performed. [7] | execute_tool | |
jsonrpc.protocol.version | 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 | Recommended | string | The version of the Model Context Protocol used. | 2025-06-18 | |
mcp.session.id | Recommended [8] | string | Identifies MCP session. | 191c4850af6c49e08843a3f6c80e5046 | |
network.protocol.name | Recommended When applicable. | string | OSI application layer or non-OSI equivalent. [9] | http; websocket | |
network.protocol.version | Recommended When applicable. | string | The actual version of the protocol used for network communication. | 1.1; 2 | |
network.transport | Recommended | string | The transport protocol used for the MCP session. [10] | tcp; quic; pipe | |
server.address | 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 | Recommended When server.address is set | int | Server port number. [12] | 80; 8080; 443 | |
gen_ai.tool.call.arguments | Opt-In | any | Parameters passed to the tool call. [13] | { “location”: “San Francisco?”, “date”: “2025-10-01” } | |
gen_ai.tool.call.result | Opt-In | any | The result returned by the tool call (if any and if execution was successful). [14] | { “temperature_range”: { “high”: 75, “low”: 60 }, “conditions”: “sunny” } |
[1] error.type: This attribute SHOULD be set to the string representation of the JSON-RPC
error code, if one is returned.
When JSON-RPC call is successful, but an error is returned within the
result payload, this attribute SHOULD be set to the low-cardinality
string representation of the error. When
CallToolResult
is returned with isError set to true, this attribute SHOULD be set to
tool_error.
[2] jsonrpc.request.id: Under the JSON-RPC specification, the id property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using null is not equivalent to omitting the id, but it is discouraged.
Instrumentations SHOULD NOT capture this attribute when the id is null or omitted.
[3] mcp.resource.uri: When the client executes a request type that includes a resource URI parameter.
[4] mcp.resource.uri: This is a URI of the resource provided in the following requests or notifications: resources/read, resources/subscribe, resources/unsubscribe, or notifications/resources/updated.
[5] rpc.response.status_code: Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes.
Semantic conventions for individual RPC frameworks SHOULD document what rpc.response.status_code means in the context of that system and which values are considered to represent errors.
[6] gen_ai.operation.name: SHOULD be set to execute_tool when the operation describes a tool call and SHOULD NOT be set otherwise.
[7] gen_ai.operation.name: Populating this attribute for tool calling along with mcp.method.name allows consumers to treat MCP tool calls spans similarly with other tool call types.
[8] mcp.session.id: When the MCP request or notification is part of a session.
[9] network.protocol.name: The value SHOULD be normalized to lowercase.
[10] network.transport: This attribute SHOULD be set to tcp or quic if the transport protocol
is HTTP.
It SHOULD be set to pipe if the transport is stdio.
[11] server.address: When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it’s available.
[12] server.port: When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it’s available.
[13] gen_ai.tool.call.arguments:
This attribute may contain sensitive information.
It’s expected to be an object - in case a serialized string is available to the instrumentation, the instrumentation SHOULD do the best effort to deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise.
[14] gen_ai.tool.call.result:
This attribute may contain sensitive information.
It’s expected to be an object - in case a serialized string is available to the instrumentation, the instrumentation SHOULD do the best effort to deserialize it to an object. When recorded on spans, it MAY be recorded as a JSON string if structured format is not supported and SHOULD be recorded in structured form otherwise.
error.type has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
| Value | Description | Stability |
|---|---|---|
_OTHER | A fallback error value to be used when the instrumentation doesn’t define a custom value. |
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 | |
create_agent | Create GenAI agent | |
embeddings | Embeddings operation such as OpenAI Create embeddings API | |
execute_tool | Execute a tool | |
generate_content | Multimodal content generation operation such as Gemini Generate Content | |
invoke_agent | Invoke GenAI agent | |
text_completion | Text completions operation such as OpenAI Completions API (Legacy) |
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. | |
elicitation/create | Request from the server to elicit additional information from the user via the client | |
initialize | Request to initialize the MCP client. | |
logging/setLevel | Request to set the logging level. | |
notifications/cancelled | Notification cancelling a previously-issued request. | |
notifications/initialized | Notification indicating that the MCP client has been initialized. | |
notifications/message | Notification indicating that a message has been received. | |
notifications/progress | Notification indicating the progress for a long-running operation. | |
notifications/prompts/list_changed | Notification indicating that the list of prompts has changed. | |
notifications/resources/list_changed | Notification indicating that the list of resources has changed. | |
notifications/resources/updated | Notification indicating that a resource has been updated. | |
notifications/roots/list_changed | Notification indicating that the list of roots has changed. | |
notifications/tools/list_changed | Notification indicating that the list of tools has changed. | |
ping | Request to check that the other party is still alive. | |
prompts/get | Request to get a prompt. | |
prompts/list | Request to list prompts available on server. | |
resources/list | Request to list resources available on server. | |
resources/read | Request to read a resource. | |
resources/subscribe | Request to subscribe to a resource. | |
resources/templates/list | Request to list resource templates available on server. | |
resources/unsubscribe | Request to unsubscribe from resource updates. | |
roots/list | Request to list roots available on server. | |
sampling/createMessage | Request to create a sampling message. | |
tools/call | Request to call a tool. | |
tools/list | Request to list tools available on server. |
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. | |
quic | QUIC | |
tcp | TCP | |
udp | UDP | |
unix | Unix domain socket |
Server
Status:
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 document for more details.
Span kind SHOULD be SERVER.
Attributes:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
mcp.method.name | Required | string | The name of the request or notification method. | notifications/cancelled; initialize; notifications/initialized | |
error.type | 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 | 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 | Conditionally Required When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | Flights | |
jsonrpc.request.id | 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 | 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 | Conditionally Required If response contains an error code. | string | The error code from the JSON-RPC response. [5] | OK; DEADLINE_EXCEEDED; -32602 | |
client.address | 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 | Recommended When client.address is set | int | Client port number. [7] | 65123 | |
gen_ai.operation.name | Recommended [8] | string | The name of the GenAI operation being performed. [9] | execute_tool | |
jsonrpc.protocol.version | 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 | Recommended | string | The version of the Model Context Protocol used. | 2025-06-18 | |
mcp.session.id | Recommended [10] | string | Identifies MCP session. | 191c4850af6c49e08843a3f6c80e5046 | |
network.protocol.name | Recommended When applicable. | string | OSI application layer or non-OSI equivalent. [11] | http; websocket | |
network.protocol.version | Recommended When applicable. | string | The actual version of the protocol used for network communication. | 1.1; 2 | |
network.transport | Recommended | string | The transport protocol used for the MCP session. [12] | tcp; quic; pipe |
[1] error.type: This attribute SHOULD be set to the string representation of the JSON-RPC
error code, if one is returned.
When JSON-RPC call is successful, but an error is returned within the
result payload, this attribute SHOULD be set to the low-cardinality
string representation of the error. When
CallToolResult
is returned with isError set to true, this attribute SHOULD be set to
tool_error.
[2] jsonrpc.request.id: Under the JSON-RPC specification, the id property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using null is not equivalent to omitting the id, but it is discouraged.
Instrumentations SHOULD NOT capture this attribute when the id is null or omitted.
[3] mcp.resource.uri: When the client executes a request type that includes a resource URI parameter.
[4] mcp.resource.uri: This is a URI of the resource provided in the following requests or notifications: resources/read, resources/subscribe, resources/unsubscribe, or notifications/resources/updated.
[5] rpc.response.status_code: Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes.
Semantic conventions for individual RPC frameworks SHOULD document what rpc.response.status_code means in the context of that system and which values are considered to represent errors.
[6] client.address: When observed from the server side, and when communicating through an intermediary, client.address SHOULD represent the client address behind any intermediaries, for example proxies, if it’s available.
[7] client.port: When observed from the server side, and when communicating through an intermediary, client.port SHOULD represent the client port behind any intermediaries, for example proxies, if it’s available.
[8] gen_ai.operation.name: SHOULD be set to execute_tool when the operation describes a tool call and SHOULD NOT be set otherwise.
[9] gen_ai.operation.name: Populating this attribute for tool calling along with mcp.method.name allows consumers to treat MCP tool calls spans similarly with other tool call types.
[10] mcp.session.id: When the MCP request or notification is part of a session.
[11] network.protocol.name: The value SHOULD be normalized to lowercase.
[12] network.transport: This attribute SHOULD be set to tcp or quic if the transport protocol
is HTTP.
It SHOULD be set to pipe if the transport is stdio.
error.type has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
| Value | Description | Stability |
|---|---|---|
_OTHER | A fallback error value to be used when the instrumentation doesn’t define a custom value. |
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 | |
create_agent | Create GenAI agent | |
embeddings | Embeddings operation such as OpenAI Create embeddings API | |
execute_tool | Execute a tool | |
generate_content | Multimodal content generation operation such as Gemini Generate Content | |
invoke_agent | Invoke GenAI agent | |
text_completion | Text completions operation such as OpenAI Completions API (Legacy) |
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. | |
elicitation/create | Request from the server to elicit additional information from the user via the client | |
initialize | Request to initialize the MCP client. | |
logging/setLevel | Request to set the logging level. | |
notifications/cancelled | Notification cancelling a previously-issued request. | |
notifications/initialized | Notification indicating that the MCP client has been initialized. | |
notifications/message | Notification indicating that a message has been received. | |
notifications/progress | Notification indicating the progress for a long-running operation. | |
notifications/prompts/list_changed | Notification indicating that the list of prompts has changed. | |
notifications/resources/list_changed | Notification indicating that the list of resources has changed. | |
notifications/resources/updated | Notification indicating that a resource has been updated. | |
notifications/roots/list_changed | Notification indicating that the list of roots has changed. | |
notifications/tools/list_changed | Notification indicating that the list of tools has changed. | |
ping | Request to check that the other party is still alive. | |
prompts/get | Request to get a prompt. | |
prompts/list | Request to list prompts available on server. | |
resources/list | Request to list resources available on server. | |
resources/read | Request to read a resource. | |
resources/subscribe | Request to subscribe to a resource. | |
resources/templates/list | Request to list resource templates available on server. | |
resources/unsubscribe | Request to unsubscribe from resource updates. | |
roots/list | Request to list roots available on server. | |
sampling/createMessage | Request to create a sampling message. | |
tools/call | Request to call a tool. | |
tools/list | Request to list tools available on server. |
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. | |
quic | QUIC | |
tcp | TCP | |
udp | UDP | |
unix | Unix domain socket |
Metrics
Metric: mcp.client.operation.duration
This metric is recommended.
This metric SHOULD be specified with
ExplicitBucketBoundaries
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. |
Attributes:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
mcp.method.name | Required | string | The name of the request or notification method. | notifications/cancelled; initialize; notifications/initialized | |
error.type | 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 | 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 | Conditionally Required When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | Flights | |
rpc.response.status_code | 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 | Recommended [3] | string | The name of the GenAI operation being performed. [4] | execute_tool | |
jsonrpc.protocol.version | 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 | Recommended | string | The version of the Model Context Protocol used. | 2025-06-18 | |
network.protocol.name | Recommended When applicable. | string | OSI application layer or non-OSI equivalent. [5] | http; websocket | |
network.protocol.version | Recommended When applicable. | string | The actual version of the protocol used for network communication. | 1.1; 2 | |
network.transport | Recommended | string | The transport protocol used for the MCP session. [6] | tcp; quic; pipe | |
server.address | 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 | Recommended When server.address is set | int | Server port number. [8] | 80; 8080; 443 | |
mcp.resource.uri | Opt-In | string | The value of the resource uri. [9] | postgres://database/customers/schema; file:///home/user/documents/report.pdf |
[1] error.type: This attribute SHOULD be set to the string representation of the JSON-RPC
error code, if one is returned.
When JSON-RPC call is successful, but an error is returned within the
result payload, this attribute SHOULD be set to the low-cardinality
string representation of the error. When
CallToolResult
is returned with isError set to true, this attribute SHOULD be set to
tool_error.
[2] rpc.response.status_code: Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes.
Semantic conventions for individual RPC frameworks SHOULD document what rpc.response.status_code means in the context of that system and which values are considered to represent errors.
[3] gen_ai.operation.name: SHOULD be set to execute_tool when the operation describes a tool call and SHOULD NOT be set otherwise.
[4] gen_ai.operation.name: Populating this attribute for tool calling along with mcp.method.name allows consumers to treat MCP tool calls spans similarly with other tool call types.
[5] network.protocol.name: The value SHOULD be normalized to lowercase.
[6] network.transport: This attribute SHOULD be set to tcp or quic if the transport protocol
is HTTP.
It SHOULD be set to pipe if the transport is stdio.
[7] server.address: When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it’s available.
[8] server.port: When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it’s available.
[9] mcp.resource.uri: This is a URI of the resource provided in the following requests or notifications: resources/read, resources/subscribe, resources/unsubscribe, or notifications/resources/updated.
error.type has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
| Value | Description | Stability |
|---|---|---|
_OTHER | A fallback error value to be used when the instrumentation doesn’t define a custom value. |
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 | |
create_agent | Create GenAI agent | |
embeddings | Embeddings operation such as OpenAI Create embeddings API | |
execute_tool | Execute a tool | |
generate_content | Multimodal content generation operation such as Gemini Generate Content | |
invoke_agent | Invoke GenAI agent | |
text_completion | Text completions operation such as OpenAI Completions API (Legacy) |
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. | |
elicitation/create | Request from the server to elicit additional information from the user via the client | |
initialize | Request to initialize the MCP client. | |
logging/setLevel | Request to set the logging level. | |
notifications/cancelled | Notification cancelling a previously-issued request. | |
notifications/initialized | Notification indicating that the MCP client has been initialized. | |
notifications/message | Notification indicating that a message has been received. | |
notifications/progress | Notification indicating the progress for a long-running operation. | |
notifications/prompts/list_changed | Notification indicating that the list of prompts has changed. | |
notifications/resources/list_changed | Notification indicating that the list of resources has changed. | |
notifications/resources/updated | Notification indicating that a resource has been updated. | |
notifications/roots/list_changed | Notification indicating that the list of roots has changed. | |
notifications/tools/list_changed | Notification indicating that the list of tools has changed. | |
ping | Request to check that the other party is still alive. | |
prompts/get | Request to get a prompt. | |
prompts/list | Request to list prompts available on server. | |
resources/list | Request to list resources available on server. | |
resources/read | Request to read a resource. | |
resources/subscribe | Request to subscribe to a resource. | |
resources/templates/list | Request to list resource templates available on server. | |
resources/unsubscribe | Request to unsubscribe from resource updates. | |
roots/list | Request to list roots available on server. | |
sampling/createMessage | Request to create a sampling message. | |
tools/call | Request to call a tool. | |
tools/list | Request to list tools available on server. |
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. | |
quic | QUIC | |
tcp | TCP | |
udp | UDP | |
unix | Unix domain socket |
Metric: mcp.server.operation.duration
This metric is recommended.
This metric SHOULD be specified with
ExplicitBucketBoundaries
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. |
Attributes:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
mcp.method.name | Required | string | The name of the request or notification method. | notifications/cancelled; initialize; notifications/initialized | |
error.type | 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 | 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 | Conditionally Required When operation is related to a specific tool. | string | Name of the tool utilized by the agent. | Flights | |
rpc.response.status_code | 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 | Recommended [3] | string | The name of the GenAI operation being performed. [4] | execute_tool | |
jsonrpc.protocol.version | 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 | Recommended | string | The version of the Model Context Protocol used. | 2025-06-18 | |
network.protocol.name | Recommended When applicable. | string | OSI application layer or non-OSI equivalent. [5] | http; websocket | |
network.protocol.version | Recommended When applicable. | string | The actual version of the protocol used for network communication. | 1.1; 2 | |
network.transport | Recommended | string | The transport protocol used for the MCP session. [6] | tcp; quic; pipe | |
mcp.resource.uri | Opt-In | string | The value of the resource uri. [7] | postgres://database/customers/schema; file:///home/user/documents/report.pdf |
[1] error.type: This attribute SHOULD be set to the string representation of the JSON-RPC
error code, if one is returned.
When JSON-RPC call is successful, but an error is returned within the
result payload, this attribute SHOULD be set to the low-cardinality
string representation of the error. When
CallToolResult
is returned with isError set to true, this attribute SHOULD be set to
tool_error.
[2] rpc.response.status_code: Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes.
Semantic conventions for individual RPC frameworks SHOULD document what rpc.response.status_code means in the context of that system and which values are considered to represent errors.
[3] gen_ai.operation.name: SHOULD be set to execute_tool when the operation describes a tool call and SHOULD NOT be set otherwise.
[4] gen_ai.operation.name: Populating this attribute for tool calling along with mcp.method.name allows consumers to treat MCP tool calls spans similarly with other tool call types.
[5] network.protocol.name: The value SHOULD be normalized to lowercase.
[6] network.transport: This attribute SHOULD be set to tcp or quic if the transport protocol
is HTTP.
It SHOULD be set to pipe if the transport is stdio.
[7] mcp.resource.uri: This is a URI of the resource provided in the following requests or notifications: resources/read, resources/subscribe, resources/unsubscribe, or notifications/resources/updated.
error.type has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
| Value | Description | Stability |
|---|---|---|
_OTHER | A fallback error value to be used when the instrumentation doesn’t define a custom value. |
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 | |
create_agent | Create GenAI agent | |
embeddings | Embeddings operation such as OpenAI Create embeddings API | |
execute_tool | Execute a tool | |
generate_content | Multimodal content generation operation such as Gemini Generate Content | |
invoke_agent | Invoke GenAI agent | |
text_completion | Text completions operation such as OpenAI Completions API (Legacy) |
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. | |
elicitation/create | Request from the server to elicit additional information from the user via the client | |
initialize | Request to initialize the MCP client. | |
logging/setLevel | Request to set the logging level. | |
notifications/cancelled | Notification cancelling a previously-issued request. | |
notifications/initialized | Notification indicating that the MCP client has been initialized. | |
notifications/message | Notification indicating that a message has been received. | |
notifications/progress | Notification indicating the progress for a long-running operation. | |
notifications/prompts/list_changed | Notification indicating that the list of prompts has changed. | |
notifications/resources/list_changed | Notification indicating that the list of resources has changed. | |
notifications/resources/updated | Notification indicating that a resource has been updated. | |
notifications/roots/list_changed | Notification indicating that the list of roots has changed. | |
notifications/tools/list_changed | Notification indicating that the list of tools has changed. | |
ping | Request to check that the other party is still alive. | |
prompts/get | Request to get a prompt. | |
prompts/list | Request to list prompts available on server. | |
resources/list | Request to list resources available on server. | |
resources/read | Request to read a resource. | |
resources/subscribe | Request to subscribe to a resource. | |
resources/templates/list | Request to list resource templates available on server. | |
resources/unsubscribe | Request to unsubscribe from resource updates. | |
roots/list | Request to list roots available on server. | |
sampling/createMessage | Request to create a sampling message. | |
tools/call | Request to call a tool. | |
tools/list | Request to list tools available on server. |
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. | |
quic | QUIC | |
tcp | TCP | |
udp | UDP | |
unix | Unix domain socket |
Metric: mcp.client.session.duration
This metric is recommended.
This metric SHOULD be specified with
ExplicitBucketBoundaries
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. |
Attributes:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
error.type | 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 | 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 | Recommended | string | The version of the Model Context Protocol used. | 2025-06-18 | |
network.protocol.name | Recommended When applicable. | string | OSI application layer or non-OSI equivalent. [2] | http; websocket | |
network.protocol.version | Recommended When applicable. | string | The actual version of the protocol used for network communication. | 1.1; 2 | |
network.transport | Recommended | string | The transport protocol used for the MCP session. [3] | tcp; quic; pipe | |
server.address | 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 | Recommended When server.address is set | int | Server port number. [5] | 80; 8080; 443 |
[1] error.type: The error.type SHOULD be predictable, and SHOULD have low cardinality.
When error.type is set to a type (e.g., an exception type), its
canonical class name identifying the type within the artifact SHOULD be used.
Instrumentations SHOULD document the list of errors they report.
The cardinality of error.type within one instrumentation library SHOULD be low.
Telemetry consumers that aggregate data from multiple instrumentation libraries and applications
should be prepared for error.type to have high cardinality at query time when no
additional filters are applied.
If the operation has completed successfully, instrumentations SHOULD NOT set error.type.
If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it’s RECOMMENDED to:
- Use a domain-specific attribute
- Set
error.typeto 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. |
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. | |
quic | QUIC | |
tcp | TCP | |
udp | UDP | |
unix | Unix domain socket |
Metric: mcp.server.session.duration
This metric is recommended.
This metric SHOULD be specified with
ExplicitBucketBoundaries
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. |
Attributes:
| Key | Stability | Requirement Level | Value Type | Description | Example Values |
|---|---|---|---|---|---|
error.type | 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 | 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 | Recommended | string | The version of the Model Context Protocol used. | 2025-06-18 | |
network.protocol.name | Recommended When applicable. | string | OSI application layer or non-OSI equivalent. [2] | http; websocket | |
network.protocol.version | Recommended When applicable. | string | The actual version of the protocol used for network communication. | 1.1; 2 | |
network.transport | Recommended | string | The transport protocol used for the MCP session. [3] | tcp; quic; pipe |
[1] error.type: The error.type SHOULD be predictable, and SHOULD have low cardinality.
When error.type is set to a type (e.g., an exception type), its
canonical class name identifying the type within the artifact SHOULD be used.
Instrumentations SHOULD document the list of errors they report.
The cardinality of error.type within one instrumentation library SHOULD be low.
Telemetry consumers that aggregate data from multiple instrumentation libraries and applications
should be prepared for error.type to have high cardinality at query time when no
additional filters are applied.
If the operation has completed successfully, instrumentations SHOULD NOT set error.type.
If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), it’s RECOMMENDED to:
- Use a domain-specific attribute
- Set
error.typeto 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. |
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. | |
quic | QUIC | |
tcp | TCP | |
udp | UDP | |
unix | Unix domain socket |
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 = httpnetwork.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 = httpnetwork.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 = httpnetwork.protocol.version = 2 | any | See gRPC conventions 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" |
Feedback
Was this page helpful?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!