From c8d4a223d03378afa80d0687c7920603a42253b6 Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 15 Jul 2025 20:23:58 +0200 Subject: [PATCH 01/14] docs(telemetry): Add MCP Server Module documentation with span conventions and usage guidelines --- .../telemetry/traces/modules/mcp-server.mdx | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx diff --git a/develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx b/develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx new file mode 100644 index 0000000000000..4c575b230bb7c --- /dev/null +++ b/develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx @@ -0,0 +1,149 @@ +--- +title: MCP Server Module +--- + +The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP typescript sdk](https://github.com/modelcontextprotocol/typescript-sdk/). + +## Spans Conventions + +For your MCP Server data to show up in Sentry, specific spans must be created with well-defined names and data attributes. See below. + +We follow the draft [OpenTelemetry MCP Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/pull/2083) as closely as possible, with some opinionated additions for improved MCP observability. We should keep an eye on the conventions and update this guide as needed as they are currently in draft and subject to change. + +### Common Span Attributes + +All MCP Server spans share common attributes and follow consistent patterns: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.method.name` | string | required | The name of the request or notification method. | `"tools/call"` | +| `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` | +| `mcp.session.id` | string | optional | Identifies the MCP session. can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | +| `mcp.transport` | string | required | The transport method used for MCP communication. **[2]** | `"stdio"` | +| `network.transport` | string | required | OSI transport layer protocol. **[3]** | `"pipe"` | +| `network.protocol.version` | string | optional | The version of JSON RPC protocol used. | `"2.0"` | + +**[2]** Well defined values for data attribute `mcp.transport`: + +| Value | Description | +| :------- | :------------------------------------ | +| `"http"` | HTTP transport | +| `"sse"` | Server-Sent Events transport | +| `"stdio"` | Standard input/output transport | +| `"unknown"`* | Unknown transport (for custom transports)| + +*`"unknown"` is a placeholder for custom transports. We could try to infer the name from the transport object. + +**[3]** Well defined values for data attribute `network.transport`: + +| Value | Description | +| :------- | :------------------------------------ | +| `"pipe"` | Named pipe (for stdio transport) | +| `"tcp"` | TCP (for HTTP/SSE transport) | + +### MCP Server Span Types + +MCP Server spans use the operation value `"mcp.server"` and fall into these categories: + +**Server Methods** (op: `"mcp.server"`): +- **Tool calls** - `tools/call {tool_name}` - Execute client-requested tools +- **Prompt requests** - `prompts/get {prompt_name}` - Provide prompt templates to clients +- **Resource access** - `resources/read {resource_uri}` - Serve resources to clients + +**Notifications** (op: `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`): +- One-way messages that don't expect responses (e.g., `notifications/cancelled`) + +**Others** (op: `"mcp.server"`): +- **Initialization** - `initialize` - Handle client connection setup + +### Tool Call Span + +Describes MCP tool execution requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD follow the pattern `"tools/call {mcp.tool.name}"`. (e.g. `"tools/call get_weather"`) +- The `mcp.method.name` attribute MUST be `"tools/call"`. +- The `mcp.tool.name` attribute SHOULD be set to the tool name. (e.g. `"get_weather"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :------ | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.tool.result.is_error` | boolean | optional | Whether the tool execution resulted in an error. | `true` | +| `mcp.tool.result.content_count` | int | optional | Number of content items in the tool result. | `3` | +| `mcp.tool.result.content` | string | optional | Serialized content of the tool result. **[0]** | `"[{\"type\":\"text\"}]"` | +| `mcp.request.argument.` | string | optional | Arguments passed to the tool. **[1]** | `"Seattle, WA"` | + +### Prompt Span + +Describes MCP prompt requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD follow the pattern `"prompts/get {mcp.prompt.name}"`. (e.g. `"prompts/get analyze-code"`) +- The `mcp.method.name` attribute MUST be `"prompts/get"`. +- The `mcp.prompt.name` attribute SHOULD be set to the prompt name. (e.g. `"analyze-code"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.request.argument.` | string | optional | Additional arguments passed to the prompt. **[1]** | `"javascript"` | + +### Resource Span + +Describes MCP resource access requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD follow the pattern `"resources/read {mcp.resource.uri}"`. (e.g. `"resources/read file:///path/to/file"`) +- The `mcp.method.name` attribute MUST be `"resources/read"`. +- The `mcp.resource.uri` attribute SHOULD be set to the resource URI. (e.g. `"file:///path/to/file"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.resource.name` | string | optional | The name of the resource being accessed. | `"sentry-docs-platform"` | + +### Initialize Span + +Describes MCP initialization requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD be `"initialize"`. +- The `mcp.method.name` attribute MUST be `"initialize"`. +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `client.address` | string | optional | Client address - domain name or IP address. | `"127.0.0.1"` | +| `client.port` | int | optional | Client port number. | `8080` | + +### Notification Span + +Describes MCP notification messages (one-way messages that don't expect a response). + +- The spans `op` MUST be `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`. +- The span `name` SHOULD be the notification method name. (e.g. `"notifications/cancelled"`) +- The `mcp.method.name` attribute MUST be set to the notification method. (e.g. `"notifications/cancelled"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +## Current limitations + +Instrumentation has to be done by wrapping the MCP server instance. This is done by the `wrapMcpServerWithSentry` function. For example: + +```ts +import * as Sentry from "@sentry/core"; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; + +const mcpServer = new McpServer({ + name: 'My MCP Server', +}); + +const server = Sentry.wrapMcpServerWithSentry(mcpServer); +``` + From e4cb9035b50a01186554cdfa4fb6b483e444bbff Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 15 Jul 2025 21:20:47 +0200 Subject: [PATCH 02/14] add mcp-server page --- .../mcp-instrumentation/index.mdx | 8 + .../mcp-instrumentation/tracing.mdx | 137 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx create mode 100644 develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx new file mode 100644 index 0000000000000..748ed475c051d --- /dev/null +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx @@ -0,0 +1,8 @@ +--- +title: MCP Instrumentation +--- + +We have instrumented the MCP server from the Anthropic SDK, including both errors and tracing. + +- [Tracing](./tracing) +- [Errors](./errors) \ No newline at end of file diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx new file mode 100644 index 0000000000000..d57bcdfbe6da0 --- /dev/null +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx @@ -0,0 +1,137 @@ +--- +title: Tracing +--- + +The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP typescript sdk](https://github.com/modelcontextprotocol/typescript-sdk/). + +## Spans Conventions + +For your MCP Server data to show up in Sentry, specific spans must be created with well-defined names and data attributes. See below. + +We follow the draft [OpenTelemetry MCP Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/pull/2083) as closely as possible, with some opinionated additions for improved MCP observability. We should keep an eye on the conventions and update this guide as needed as they are currently in draft and subject to change. + +### Common Span Attributes + +All MCP Server spans share common attributes and follow consistent patterns: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.method.name` | string | required | The name of the request or notification method. | `"tools/call"` | +| `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` | +| `mcp.session.id` | string | optional | Identifies the MCP session. can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | +| `mcp.transport` | string | required | The transport method used for MCP communication. **[2]** | `"stdio"` | +| `network.transport` | string | required | OSI transport layer protocol. **[3]** | `"pipe"` | +| `network.protocol.version` | string | optional | The version of JSON RPC protocol used. | `"2.0"` | + +**[2]** Well defined values for data attribute `mcp.transport`: + +| Value | Description | +| :------- | :------------------------------------ | +| `"http"` | HTTP transport | +| `"sse"` | Server-Sent Events transport | +| `"stdio"` | Standard input/output transport | +| `"unknown"`* | Unknown transport (for custom transports)| + +*`"unknown"` is a placeholder for custom transports. We could try to infer the name from the transport object. + +**[3]** Well defined values for data attribute `network.transport`: + +| Value | Description | +| :------- | :------------------------------------ | +| `"pipe"` | Named pipe (for stdio transport) | +| `"tcp"` | TCP (for HTTP/SSE transport) | + +### MCP Server Span Types + +MCP Server spans use the operation value `"mcp.server"` and fall into these categories: + +**Server Methods** (op: `"mcp.server"`): +- **Tool calls** - `tools/call {tool_name}` - Execute client-requested tools +- **Prompt requests** - `prompts/get {prompt_name}` - Provide prompt templates to clients +- **Resource access** - `resources/read {resource_uri}` - Serve resources to clients + +**Notifications** (op: `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`): +- One-way messages that don't expect responses (e.g., `notifications/cancelled`) + +**Others** (op: `"mcp.server"`): +- **Initialization** - `initialize` - Handle client connection setup + +### Tool Call Span + +Describes MCP tool execution requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD follow the pattern `"tools/call {mcp.tool.name}"`. (e.g. `"tools/call get_weather"`) +- The `mcp.method.name` attribute MUST be `"tools/call"`. +- The `mcp.tool.name` attribute SHOULD be set to the tool name. (e.g. `"get_weather"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :------ | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.tool.result.is_error` | boolean | optional | Whether the tool execution resulted in an error. | `true` | +| `mcp.tool.result.content_count` | int | optional | Number of content items in the tool result. | `3` | +| `mcp.tool.result.content` | string | optional | Serialized content of the tool result. **[0]** | `"[{\"type\":\"text\"}]"` | +| `mcp.request.argument.` | string | optional | Arguments passed to the tool. **[1]** | `"Seattle, WA"` | + +**[0]**: Span attributes only allow primitive data types. This means you need to use a stringified version of a list of dictionaries. Do NOT set `[{"type": "text"}]` but rather the string `"[{\"type\": \"text\"}]"`. +**[1]**: Arguments are prefixed with `mcp.request.argument.` followed by the argument key. For example, if a tool receives `{location: "Seattle, WA"}`, it becomes `mcp.request.argument.location`. + +### Prompt Span + +Describes MCP prompt requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD follow the pattern `"prompts/get {mcp.prompt.name}"`. (e.g. `"prompts/get analyze-code"`) +- The `mcp.method.name` attribute MUST be `"prompts/get"`. +- The `mcp.prompt.name` attribute SHOULD be set to the prompt name. (e.g. `"analyze-code"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.request.argument.` | string | optional | Additional arguments passed to the prompt. **[1]** | `"javascript"` | + +### Resource Span + +Describes MCP resource access requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD follow the pattern `"resources/read {mcp.resource.uri}"`. (e.g. `"resources/read file:///path/to/file"`) +- The `mcp.method.name` attribute MUST be `"resources/read"`. +- The `mcp.resource.uri` attribute SHOULD be set to the resource URI. (e.g. `"file:///path/to/file"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.resource.name` | string | optional | The name of the resource being accessed. | `"sentry-docs-platform"` | + +### Initialize Span + +Describes MCP initialization requests from clients. + +- The spans `op` MUST be `"mcp.server"`. +- The span `name` SHOULD be `"initialize"`. +- The `mcp.method.name` attribute MUST be `"initialize"`. +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + +Additional attributes on the span: + +| Data Attribute | Type | Requirement Level | Description | Example | +| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `client.address` | string | optional | Client address - domain name or IP address. | `"127.0.0.1"` | +| `client.port` | int | optional | Client port number. | `8080` | + +### Notification Span + +Describes MCP notification messages (one-way messages that don't expect a response). + +- The spans `op` MUST be `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`. +- The span `name` SHOULD be the notification method name. (e.g. `"notifications/cancelled"`) +- The `mcp.method.name` attribute MUST be set to the notification method. (e.g. `"notifications/cancelled"`) +- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). + From c0a1d0a2e270a57b17f173115c65bb1ce5c7055f Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 15 Jul 2025 21:23:03 +0200 Subject: [PATCH 03/14] include current limitations --- .../mcp-instrumentation/index.mdx | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx index 748ed475c051d..5288e69f4e271 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx @@ -2,7 +2,26 @@ title: MCP Instrumentation --- -We have instrumented the MCP server from the Anthropic SDK, including both errors and tracing. +The MCP Server module instruments Anthropic's Model Context Protocol (MCP) SDKs. At the moment it only supports the [MCP typescript sdk](https://github.com/modelcontextprotocol/typescript-sdk/). + +## Features - [Tracing](./tracing) -- [Errors](./errors) \ No newline at end of file +- [Errors](./errors) + +## Current limitations + +Currently, it doesn't support automatic instrumentation due to [this issue](https://github.com/getsentry/sentry-javascript/issues/16052) related to `import-in-the-middle`. + +Instrumentation has to be done by wrapping the MCP server instance. This is done by the `wrapMcpServerWithSentry` function. For example: + +```ts +import * as Sentry from "@sentry/core"; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; + +const mcpServer = new McpServer({ + name: 'My MCP Server', +}); + +const server = Sentry.wrapMcpServerWithSentry(mcpServer); +``` From ef7e2a91abfcd4b59eacdd341c1cbb530bb9b149 Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 15 Jul 2025 21:52:54 +0200 Subject: [PATCH 04/14] change docs placement --- .../telemetry/traces/modules/mcp-server.mdx | 149 ------------------ 1 file changed, 149 deletions(-) delete mode 100644 develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx diff --git a/develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx b/develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx deleted file mode 100644 index 4c575b230bb7c..0000000000000 --- a/develop-docs/sdk/telemetry/traces/modules/mcp-server.mdx +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: MCP Server Module ---- - -The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP typescript sdk](https://github.com/modelcontextprotocol/typescript-sdk/). - -## Spans Conventions - -For your MCP Server data to show up in Sentry, specific spans must be created with well-defined names and data attributes. See below. - -We follow the draft [OpenTelemetry MCP Semantic Conventions](https://github.com/open-telemetry/semantic-conventions/pull/2083) as closely as possible, with some opinionated additions for improved MCP observability. We should keep an eye on the conventions and update this guide as needed as they are currently in draft and subject to change. - -### Common Span Attributes - -All MCP Server spans share common attributes and follow consistent patterns: - -| Data Attribute | Type | Requirement Level | Description | Example | -| :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | -| `mcp.method.name` | string | required | The name of the request or notification method. | `"tools/call"` | -| `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` | -| `mcp.session.id` | string | optional | Identifies the MCP session. can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | -| `mcp.transport` | string | required | The transport method used for MCP communication. **[2]** | `"stdio"` | -| `network.transport` | string | required | OSI transport layer protocol. **[3]** | `"pipe"` | -| `network.protocol.version` | string | optional | The version of JSON RPC protocol used. | `"2.0"` | - -**[2]** Well defined values for data attribute `mcp.transport`: - -| Value | Description | -| :------- | :------------------------------------ | -| `"http"` | HTTP transport | -| `"sse"` | Server-Sent Events transport | -| `"stdio"` | Standard input/output transport | -| `"unknown"`* | Unknown transport (for custom transports)| - -*`"unknown"` is a placeholder for custom transports. We could try to infer the name from the transport object. - -**[3]** Well defined values for data attribute `network.transport`: - -| Value | Description | -| :------- | :------------------------------------ | -| `"pipe"` | Named pipe (for stdio transport) | -| `"tcp"` | TCP (for HTTP/SSE transport) | - -### MCP Server Span Types - -MCP Server spans use the operation value `"mcp.server"` and fall into these categories: - -**Server Methods** (op: `"mcp.server"`): -- **Tool calls** - `tools/call {tool_name}` - Execute client-requested tools -- **Prompt requests** - `prompts/get {prompt_name}` - Provide prompt templates to clients -- **Resource access** - `resources/read {resource_uri}` - Serve resources to clients - -**Notifications** (op: `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`): -- One-way messages that don't expect responses (e.g., `notifications/cancelled`) - -**Others** (op: `"mcp.server"`): -- **Initialization** - `initialize` - Handle client connection setup - -### Tool Call Span - -Describes MCP tool execution requests from clients. - -- The spans `op` MUST be `"mcp.server"`. -- The span `name` SHOULD follow the pattern `"tools/call {mcp.tool.name}"`. (e.g. `"tools/call get_weather"`) -- The `mcp.method.name` attribute MUST be `"tools/call"`. -- The `mcp.tool.name` attribute SHOULD be set to the tool name. (e.g. `"get_weather"`) -- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). - -Additional attributes on the span: - -| Data Attribute | Type | Requirement Level | Description | Example | -| :------------------------------------ | :------ | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | -| `mcp.tool.result.is_error` | boolean | optional | Whether the tool execution resulted in an error. | `true` | -| `mcp.tool.result.content_count` | int | optional | Number of content items in the tool result. | `3` | -| `mcp.tool.result.content` | string | optional | Serialized content of the tool result. **[0]** | `"[{\"type\":\"text\"}]"` | -| `mcp.request.argument.` | string | optional | Arguments passed to the tool. **[1]** | `"Seattle, WA"` | - -### Prompt Span - -Describes MCP prompt requests from clients. - -- The spans `op` MUST be `"mcp.server"`. -- The span `name` SHOULD follow the pattern `"prompts/get {mcp.prompt.name}"`. (e.g. `"prompts/get analyze-code"`) -- The `mcp.method.name` attribute MUST be `"prompts/get"`. -- The `mcp.prompt.name` attribute SHOULD be set to the prompt name. (e.g. `"analyze-code"`) -- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). - -Additional attributes on the span: - -| Data Attribute | Type | Requirement Level | Description | Example | -| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | -| `mcp.request.argument.` | string | optional | Additional arguments passed to the prompt. **[1]** | `"javascript"` | - -### Resource Span - -Describes MCP resource access requests from clients. - -- The spans `op` MUST be `"mcp.server"`. -- The span `name` SHOULD follow the pattern `"resources/read {mcp.resource.uri}"`. (e.g. `"resources/read file:///path/to/file"`) -- The `mcp.method.name` attribute MUST be `"resources/read"`. -- The `mcp.resource.uri` attribute SHOULD be set to the resource URI. (e.g. `"file:///path/to/file"`) -- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). - -Additional attributes on the span: - -| Data Attribute | Type | Requirement Level | Description | Example | -| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | -| `mcp.resource.name` | string | optional | The name of the resource being accessed. | `"sentry-docs-platform"` | - -### Initialize Span - -Describes MCP initialization requests from clients. - -- The spans `op` MUST be `"mcp.server"`. -- The span `name` SHOULD be `"initialize"`. -- The `mcp.method.name` attribute MUST be `"initialize"`. -- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). - -Additional attributes on the span: - -| Data Attribute | Type | Requirement Level | Description | Example | -| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | -| `client.address` | string | optional | Client address - domain name or IP address. | `"127.0.0.1"` | -| `client.port` | int | optional | Client port number. | `8080` | - -### Notification Span - -Describes MCP notification messages (one-way messages that don't expect a response). - -- The spans `op` MUST be `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`. -- The span `name` SHOULD be the notification method name. (e.g. `"notifications/cancelled"`) -- The `mcp.method.name` attribute MUST be set to the notification method. (e.g. `"notifications/cancelled"`) -- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set). - -## Current limitations - -Instrumentation has to be done by wrapping the MCP server instance. This is done by the `wrapMcpServerWithSentry` function. For example: - -```ts -import * as Sentry from "@sentry/core"; -import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; - -const mcpServer = new McpServer({ - name: 'My MCP Server', -}); - -const server = Sentry.wrapMcpServerWithSentry(mcpServer); -``` - From 557513f614686a542e19ce360ff56a832c025045 Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 15 Jul 2025 21:53:08 +0200 Subject: [PATCH 05/14] add errors doc --- .../mcp-instrumentation/errors.mdx | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx new file mode 100644 index 0000000000000..d20ced58a6551 --- /dev/null +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx @@ -0,0 +1,76 @@ +--- +title: Errors +--- + +MCP Server error instrumentation ensures that all errors occurring within the Model Context Protocol (MCP) server are captured and reported to Sentry, **without ever interfering with the operation of the MCP service itself**. + +## Goals and Philosophy + +- **Comprehensive context:** Errors are always associated with the active Sentry span, so you get full context (method, tool, arguments, etc.) in Sentry. +- **Categorized errors:** Errors are tagged by type (e.g., `validation`, `timeout`, `tool_execution`, `resource_operation`, `prompt_execution`, `transport`, etc.) for easy filtering and analysis in Sentry. +- **Handler wrapping:** All MCP server handlers (`tool`, `resource`, `prompt`) are wrapped to ensure errors are captured and correlated with the correct request span. + + +## Safe Error Capture + +The core utility is an error capture function: + +```ts +import { getClient } from '../../currentScopes'; +import { captureException } from '../../exports'; + +export function captureError(error: Error, errorType?: string): void { + try { + const client = getClient(); + if (!client) return; + captureException(error, { + tags: { + mcp_error_type: errorType || 'handler_execution', + }, + }); + } catch { + // Silently ignore capture errors - never affect MCP operation + } +} +``` + +- **Never throws:** All error capture is wrapped in a try/catch and will never throw. +- **Tags errors:** Errors are tagged with `mcp_error_type` for later filtering. + +## Handler Wrapping for Error Capture + +All MCP server method handlers (`tool`, `resource`, `prompt`) are wrapped to: +- Correlate handler execution with the correct Sentry span (using request/session data) +- Capture both synchronous and asynchronous errors +- Categorize errors by handler type and error nature + +### Error Categorization + +Errors are categorized and tagged based on the handler and error type: + +- **Tool handler errors:** + - `validation` (e.g., protocol/validation errors) + - `timeout` (e.g., server timeouts) + - `tool_execution` (all other tool errors) +- **Resource handler errors:** + - `resource_operation` +- **Prompt handler errors:** + - `prompt_execution` +- **Transport errors:** + - `transport` +- **Protocol errors:** + - `protocol` + +## Span Correlation + +All errors are captured within the context of the active Sentry span, so you can: +- See which MCP method, tool, or resource caused the error +- View all arguments and context for the failed request +- Correlate errors with traces and performance data + +## Transport Layer Error Instrumentation + +The MCP transport layer is also instrumented to: +- Create spans for incoming/outgoing messages +- Capture errors in transport event handlers (e.g., `onerror`) +- Correlate protocol errors with the correct request/response \ No newline at end of file From e839978fbbe1b6de7c77ec188d957c360d24ceaf Mon Sep 17 00:00:00 2001 From: betegon Date: Wed, 16 Jul 2025 12:08:20 +0200 Subject: [PATCH 06/14] typo/grammar pass --- .../sdk/expected-features/mcp-instrumentation/errors.mdx | 6 +++--- .../sdk/expected-features/mcp-instrumentation/index.mdx | 4 ++-- .../sdk/expected-features/mcp-instrumentation/tracing.mdx | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx index d20ced58a6551..a98453adb294a 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx @@ -29,13 +29,13 @@ export function captureError(error: Error, errorType?: string): void { }, }); } catch { - // Silently ignore capture errors - never affect MCP operation + // Silently ignore capture errors so it never affects MCP operation } } ``` -- **Never throws:** All error capture is wrapped in a try/catch and will never throw. -- **Tags errors:** Errors are tagged with `mcp_error_type` for later filtering. +- **Never throws an exception:** All error capture is wrapped in a try/catch and will never throw an exception. +- **Tags errors:** [WIP] will be removed as tags are intended for users. ## Handler Wrapping for Error Capture diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx index 5288e69f4e271..94fce399f4481 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx @@ -2,7 +2,7 @@ title: MCP Instrumentation --- -The MCP Server module instruments Anthropic's Model Context Protocol (MCP) SDKs. At the moment it only supports the [MCP typescript sdk](https://github.com/modelcontextprotocol/typescript-sdk/). +The MCP Server module instruments Anthropic's Model Context Protocol (MCP) SDKs. At the moment it only supports the [MCP Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk/). ## Features @@ -13,7 +13,7 @@ The MCP Server module instruments Anthropic's Model Context Protocol (MCP) SDKs. Currently, it doesn't support automatic instrumentation due to [this issue](https://github.com/getsentry/sentry-javascript/issues/16052) related to `import-in-the-middle`. -Instrumentation has to be done by wrapping the MCP server instance. This is done by the `wrapMcpServerWithSentry` function. For example: +Instrumentation must be done by wrapping the MCP server instance. This is done by the `wrapMcpServerWithSentry` function. For example: ```ts import * as Sentry from "@sentry/core"; diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx index d57bcdfbe6da0..73fb8c672c0ad 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx @@ -2,7 +2,7 @@ title: Tracing --- -The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP typescript sdk](https://github.com/modelcontextprotocol/typescript-sdk/). +The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk/). ## Spans Conventions @@ -18,12 +18,12 @@ All MCP Server spans share common attributes and follow consistent patterns: | :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | | `mcp.method.name` | string | required | The name of the request or notification method. | `"tools/call"` | | `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` | -| `mcp.session.id` | string | optional | Identifies the MCP session. can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | +| `mcp.session.id` | string | optional | Identifies the MCP session. Can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | | `mcp.transport` | string | required | The transport method used for MCP communication. **[2]** | `"stdio"` | | `network.transport` | string | required | OSI transport layer protocol. **[3]** | `"pipe"` | | `network.protocol.version` | string | optional | The version of JSON RPC protocol used. | `"2.0"` | -**[2]** Well defined values for data attribute `mcp.transport`: +**[2]** Well-defined values for data attribute `mcp.transport`: | Value | Description | | :------- | :------------------------------------ | @@ -34,7 +34,7 @@ All MCP Server spans share common attributes and follow consistent patterns: *`"unknown"` is a placeholder for custom transports. We could try to infer the name from the transport object. -**[3]** Well defined values for data attribute `network.transport`: +**[3]** Well-defined values for data attribute `network.transport`: | Value | Description | | :------- | :------------------------------------ | From 80aa0868653e8cc8123f919bfc3e58b4ff159516 Mon Sep 17 00:00:00 2001 From: betegon Date: Wed, 16 Jul 2025 12:57:49 +0200 Subject: [PATCH 07/14] put required attributes first in table --- .../sdk/expected-features/mcp-instrumentation/tracing.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx index 73fb8c672c0ad..10ac3053caa3f 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx @@ -17,10 +17,10 @@ All MCP Server spans share common attributes and follow consistent patterns: | Data Attribute | Type | Requirement Level | Description | Example | | :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | | `mcp.method.name` | string | required | The name of the request or notification method. | `"tools/call"` | -| `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` | -| `mcp.session.id` | string | optional | Identifies the MCP session. Can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | | `mcp.transport` | string | required | The transport method used for MCP communication. **[2]** | `"stdio"` | | `network.transport` | string | required | OSI transport layer protocol. **[3]** | `"pipe"` | +| `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` | +| `mcp.session.id` | string | optional | Identifies the MCP session. Can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` | | `network.protocol.version` | string | optional | The version of JSON RPC protocol used. | `"2.0"` | **[2]** Well-defined values for data attribute `mcp.transport`: From 6d2da975c34beab4bf212d9b56e61b9a18f6b3a1 Mon Sep 17 00:00:00 2001 From: betegon Date: Wed, 16 Jul 2025 16:23:16 +0200 Subject: [PATCH 08/14] remove js specific info --- .../mcp-instrumentation/index.mdx | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx index 94fce399f4481..f55ed937f5c62 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/index.mdx @@ -8,20 +8,3 @@ The MCP Server module instruments Anthropic's Model Context Protocol (MCP) SDKs. - [Tracing](./tracing) - [Errors](./errors) - -## Current limitations - -Currently, it doesn't support automatic instrumentation due to [this issue](https://github.com/getsentry/sentry-javascript/issues/16052) related to `import-in-the-middle`. - -Instrumentation must be done by wrapping the MCP server instance. This is done by the `wrapMcpServerWithSentry` function. For example: - -```ts -import * as Sentry from "@sentry/core"; -import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; - -const mcpServer = new McpServer({ - name: 'My MCP Server', -}); - -const server = Sentry.wrapMcpServerWithSentry(mcpServer); -``` From 6c602f63f9526821f012fb1633b878e6e9b64f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Beteg=C3=B3n?= Date: Tue, 22 Jul 2025 11:28:11 +0200 Subject: [PATCH 09/14] Update develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx Co-authored-by: Alex Krawiec --- .../sdk/expected-features/mcp-instrumentation/errors.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx index a98453adb294a..3098555a52fa6 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx @@ -1,5 +1,6 @@ --- -title: Errors +title: MCP Server Errors +sidebar_title: Errors --- MCP Server error instrumentation ensures that all errors occurring within the Model Context Protocol (MCP) server are captured and reported to Sentry, **without ever interfering with the operation of the MCP service itself**. From 7e6e323bd5e958c1c5a805111892a58c4091ac22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Beteg=C3=B3n?= Date: Tue, 22 Jul 2025 11:28:19 +0200 Subject: [PATCH 10/14] Update develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx Co-authored-by: Alex Krawiec --- .../sdk/expected-features/mcp-instrumentation/tracing.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx index 10ac3053caa3f..e56b7313f6019 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx @@ -1,5 +1,6 @@ --- -title: Tracing +title: MCP Tracing +sidebar_title: Tracing --- The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk/). From 2ace1dd893c60ee01fab9880dd75634faa68b5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Beteg=C3=B3n?= Date: Tue, 22 Jul 2025 11:28:37 +0200 Subject: [PATCH 11/14] Update develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx Co-authored-by: Alex Krawiec --- .../sdk/expected-features/mcp-instrumentation/tracing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx index e56b7313f6019..1b4ed7ee2c2d3 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx @@ -3,7 +3,7 @@ title: MCP Tracing sidebar_title: Tracing --- -The MCP Server module is the instrumentation for the anthropic MCP SDKs. At the moment it only supports the [MCP Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk/). +The MCP Server module is the instrumentation for the [anthropic MCP](https://www.anthropic.com/news/model-context-protocol) SDKs. At the moment it only supports the [MCP Typescript SDK](https://github.com/modelcontextprotocol/typescript-sdk/). ## Spans Conventions From 7c0a8dbdf18f1c70a71b40f06694d33151363f7b Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 22 Jul 2025 11:38:46 +0200 Subject: [PATCH 12/14] Refine error categorization language in errors.mdx for clarity --- .../sdk/expected-features/mcp-instrumentation/errors.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx index 3098555a52fa6..1053084310b19 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx @@ -47,7 +47,7 @@ All MCP server method handlers (`tool`, `resource`, `prompt`) are wrapped to: ### Error Categorization -Errors are categorized and tagged based on the handler and error type: +Errors are categorized and tagged according to the handler and type of error: - **Tool handler errors:** - `validation` (e.g., protocol/validation errors) @@ -74,4 +74,4 @@ All errors are captured within the context of the active Sentry span, so you can The MCP transport layer is also instrumented to: - Create spans for incoming/outgoing messages - Capture errors in transport event handlers (e.g., `onerror`) -- Correlate protocol errors with the correct request/response \ No newline at end of file +- Correlate protocol errors with the correct request/response From 46958b0f665fbc74b5bd66e11a440e1e31be6576 Mon Sep 17 00:00:00 2001 From: betegon Date: Tue, 22 Jul 2025 11:57:11 +0200 Subject: [PATCH 13/14] fix: change tags in error in favor of mechanism --- .../mcp-instrumentation/errors.mdx | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx index 1053084310b19..37a39c19b4abc 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/errors.mdx @@ -10,7 +10,7 @@ MCP Server error instrumentation ensures that all errors occurring within the Mo - **Comprehensive context:** Errors are always associated with the active Sentry span, so you get full context (method, tool, arguments, etc.) in Sentry. - **Categorized errors:** Errors are tagged by type (e.g., `validation`, `timeout`, `tool_execution`, `resource_operation`, `prompt_execution`, `transport`, etc.) for easy filtering and analysis in Sentry. - **Handler wrapping:** All MCP server handlers (`tool`, `resource`, `prompt`) are wrapped to ensure errors are captured and correlated with the correct request span. - +- **Span status tracking:** When errors occur, the active span status is automatically set to error for better trace correlation. ## Safe Error Capture @@ -19,14 +19,31 @@ The core utility is an error capture function: ```ts import { getClient } from '../../currentScopes'; import { captureException } from '../../exports'; +import { SPAN_STATUS_ERROR } from '../../tracing'; +import { getActiveSpan } from '../../utils/spanUtils'; +import type { McpErrorType } from './types'; -export function captureError(error: Error, errorType?: string): void { +export function captureError(error: Error, errorType?: McpErrorType, extraData?: Record): void { try { const client = getClient(); if (!client) return; + + const activeSpan = getActiveSpan(); + if (activeSpan?.isRecording()) { + activeSpan.setStatus({ + code: SPAN_STATUS_ERROR, + message: 'internal_error', + }); + } + captureException(error, { - tags: { - mcp_error_type: errorType || 'handler_execution', + mechanism: { + type: 'mcp_server', + handled: false, + data: { + error_type: errorType || 'handler_execution', + ...extraData, + }, }, }); } catch { @@ -36,7 +53,8 @@ export function captureError(error: Error, errorType?: string): void { ``` - **Never throws an exception:** All error capture is wrapped in a try/catch and will never throw an exception. -- **Tags errors:** [WIP] will be removed as tags are intended for users. +- **Mechanism-based categorization:** Error metadata is attached using the `mechanism` object. +- **Flexible context:** Additional context can be passed via `extraData` and will be included in the mechanism data. ## Handler Wrapping for Error Capture @@ -44,10 +62,11 @@ All MCP server method handlers (`tool`, `resource`, `prompt`) are wrapped to: - Correlate handler execution with the correct Sentry span (using request/session data) - Capture both synchronous and asynchronous errors - Categorize errors by handler type and error nature +- Set span status to error for failed operations ### Error Categorization -Errors are categorized and tagged according to the handler and type of error: +Errors are categorized using the mechanism's data field according to the handler and type of error: - **Tool handler errors:** - `validation` (e.g., protocol/validation errors) @@ -62,6 +81,10 @@ Errors are categorized and tagged according to the handler and type of error: - **Protocol errors:** - `protocol` +The mechanism approach ensures that error classification information is available in the Sentry UI for debugging and analysis. + +**Note**: this mechanism data is not indexed so it is not searchable. + ## Span Correlation All errors are captured within the context of the active Sentry span, so you can: From 40fca7128c15eec8319906ef7d30c9b701f6c9b6 Mon Sep 17 00:00:00 2001 From: betegon Date: Wed, 23 Jul 2025 21:13:20 +0200 Subject: [PATCH 14/14] include session data --- .../mcp-instrumentation/tracing.mdx | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx index 1b4ed7ee2c2d3..a9d1a3d64929e 100644 --- a/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx +++ b/develop-docs/sdk/expected-features/mcp-instrumentation/tracing.mdx @@ -42,6 +42,44 @@ All MCP Server spans share common attributes and follow consistent patterns: | `"pipe"` | Named pipe (for stdio transport) | | `"tcp"` | TCP (for HTTP/SSE transport) | +### Session Management + +MCP servers can be either stateless or stateful. Understanding this distinction is important for proper tracing implementation and session data handling. (See [MCP Server Session Management](https://modelcontextprotocol.io/docs/concepts/transports#session-management) for more details.) + +#### Stateless vs Stateful Servers + +**Stateless Servers**: These servers treat each request independently without maintaining session state between requests. The `mcp.session.id` attribute may be undefined or not meaningful for such servers. + +**Stateful Servers**: These servers maintain session state across multiple requests from the same client. They use a consistent `mcp.session.id` that is shared across all messages within the same session lifecycle. All MCP request from the client should always have the HTTP header `X-MCP-Session-Id` set to the same value. + +#### Session Data Attributes + +For stateful servers, additional session metadata is collected during the initialization phase and attached to all subsequent spans within the same session. This provides observability and context for the entire session lifecycle. + +| Data Attribute | Type | Requirement Level | Description | Example | +| :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- | +| `mcp.client.name` | string | optional | Name of the MCP client application. | `"claude-desktop"` | +| `mcp.client.title` | string | optional | Display title of the MCP client application. | `"Claude Desktop"` | +| `mcp.client.version` | string | optional | Version of the MCP client application. | `"1.0.0"` | +| `mcp.server.name` | string | optional | Name of the MCP server application. | `"my-mcp-server"` | +| `mcp.server.title` | string | optional | Display title of the MCP server application. | `"My MCP Server"` | +| `mcp.server.version` | string | optional | Version of the MCP server application. | `"2.1.3"` | +| `mcp.protocol.version` | string | optional | MCP protocol version used in the session. | `"2024-11-05"` | + +#### Session Lifecycle + +1. **Initialization**: During the `initialize` request, session metadata (client info, server info, protocol version) is established and stored. + +2. **Session Propagation**: For all subsequent requests within the same session (tool calls, prompt requests, resource access), the session metadata is automatically attached to each span. + +3. **Evolution**: As the MCP specification evolves, additional session-level metadata may be captured and propagated, providing richer context for observability. + +This session-based approach allows us to: +- Track client and server versions across infrastructure +- Analyze protocol version adoption and compatibility +- Group and correlate all operations within a single client session +- Monitor session duration and patterns + ### MCP Server Span Types MCP Server spans use the operation value `"mcp.server"` and fall into these categories: