Skip to content

Commit 4a1d2ff

Browse files
betegoncoolguyzone
andauthored
dev-docs (MCP server): Add tracing and errors documentation (#14374)
## DESCRIBE YOUR PR Closes #14106 Adds developer docs for our MCP Server instrumentation. Route for the documentation `sdk/expected-features/mcp-instrumentation` that includes: ```bash .mcp-instrumentation ├── index.mdx # brief description on current features and limitations ├── errors.mdx # draft errors doc └── tracing.mdx # Tracing and span conventions ``` Followed this file structure as a start to (in the future) have this structure for all the other features, having something like this below, where we have : ``` .[Feature 1] ├── index.mdx ├── logs.mdx ├── errors.mdx . . . .[Feature 2] ├── index.mdx ├── errors.mdx ├── tracing.mdx . . . ``` The structure idea is from @abhi, who helped me settle this <3. **NOTE:** Error docs are going to change, addressing feedback from [sentry-javascript/pull/16817](getsentry/sentry-javascript#16817) ## IS YOUR CHANGE URGENT? ## PRE-MERGE CHECKLIST *Make sure you've checked the following before merging your changes:* - [x] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs) --------- Co-authored-by: Alex Krawiec <[email protected]>
1 parent 1a7aea4 commit 4a1d2ff

File tree

3 files changed

+286
-0
lines changed

3 files changed

+286
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: MCP Server Errors
3+
sidebar_title: Errors
4+
---
5+
6+
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**.
7+
8+
## Goals and Philosophy
9+
10+
- **Comprehensive context:** Errors are always associated with the active Sentry span, so you get full context (method, tool, arguments, etc.) in Sentry.
11+
- **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.
12+
- **Handler wrapping:** All MCP server handlers (`tool`, `resource`, `prompt`) are wrapped to ensure errors are captured and correlated with the correct request span.
13+
- **Span status tracking:** When errors occur, the active span status is automatically set to error for better trace correlation.
14+
15+
## Safe Error Capture
16+
17+
The core utility is an error capture function:
18+
19+
```ts
20+
import { getClient } from '../../currentScopes';
21+
import { captureException } from '../../exports';
22+
import { SPAN_STATUS_ERROR } from '../../tracing';
23+
import { getActiveSpan } from '../../utils/spanUtils';
24+
import type { McpErrorType } from './types';
25+
26+
export function captureError(error: Error, errorType?: McpErrorType, extraData?: Record<string, unknown>): void {
27+
try {
28+
const client = getClient();
29+
if (!client) return;
30+
31+
const activeSpan = getActiveSpan();
32+
if (activeSpan?.isRecording()) {
33+
activeSpan.setStatus({
34+
code: SPAN_STATUS_ERROR,
35+
message: 'internal_error',
36+
});
37+
}
38+
39+
captureException(error, {
40+
mechanism: {
41+
type: 'mcp_server',
42+
handled: false,
43+
data: {
44+
error_type: errorType || 'handler_execution',
45+
...extraData,
46+
},
47+
},
48+
});
49+
} catch {
50+
// Silently ignore capture errors so it never affects MCP operation
51+
}
52+
}
53+
```
54+
55+
- **Never throws an exception:** All error capture is wrapped in a try/catch and will never throw an exception.
56+
- **Mechanism-based categorization:** Error metadata is attached using the `mechanism` object.
57+
- **Flexible context:** Additional context can be passed via `extraData` and will be included in the mechanism data.
58+
59+
## Handler Wrapping for Error Capture
60+
61+
All MCP server method handlers (`tool`, `resource`, `prompt`) are wrapped to:
62+
- Correlate handler execution with the correct Sentry span (using request/session data)
63+
- Capture both synchronous and asynchronous errors
64+
- Categorize errors by handler type and error nature
65+
- Set span status to error for failed operations
66+
67+
### Error Categorization
68+
69+
Errors are categorized using the mechanism's data field according to the handler and type of error:
70+
71+
- **Tool handler errors:**
72+
- `validation` (e.g., protocol/validation errors)
73+
- `timeout` (e.g., server timeouts)
74+
- `tool_execution` (all other tool errors)
75+
- **Resource handler errors:**
76+
- `resource_operation`
77+
- **Prompt handler errors:**
78+
- `prompt_execution`
79+
- **Transport errors:**
80+
- `transport`
81+
- **Protocol errors:**
82+
- `protocol`
83+
84+
The mechanism approach ensures that error classification information is available in the Sentry UI for debugging and analysis.
85+
86+
**Note**: this mechanism data is not indexed so it is not searchable.
87+
88+
## Span Correlation
89+
90+
All errors are captured within the context of the active Sentry span, so you can:
91+
- See which MCP method, tool, or resource caused the error
92+
- View all arguments and context for the failed request
93+
- Correlate errors with traces and performance data
94+
95+
## Transport Layer Error Instrumentation
96+
97+
The MCP transport layer is also instrumented to:
98+
- Create spans for incoming/outgoing messages
99+
- Capture errors in transport event handlers (e.g., `onerror`)
100+
- Correlate protocol errors with the correct request/response
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: MCP Instrumentation
3+
---
4+
5+
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/).
6+
7+
## Features
8+
9+
- [Tracing](./tracing)
10+
- [Errors](./errors)
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
---
2+
title: MCP Tracing
3+
sidebar_title: Tracing
4+
---
5+
6+
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/).
7+
8+
## Spans Conventions
9+
10+
For your MCP Server data to show up in Sentry, specific spans must be created with well-defined names and data attributes. See below.
11+
12+
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.
13+
14+
### Common Span Attributes
15+
16+
All MCP Server spans share common attributes and follow consistent patterns:
17+
18+
| Data Attribute | Type | Requirement Level | Description | Example |
19+
| :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- |
20+
| `mcp.method.name` | string | required | The name of the request or notification method. | `"tools/call"` |
21+
| `mcp.transport` | string | required | The transport method used for MCP communication. **[2]** | `"stdio"` |
22+
| `network.transport` | string | required | OSI transport layer protocol. **[3]** | `"pipe"` |
23+
| `mcp.request.id` | string | optional | A unique identifier for the request. | `"42"` |
24+
| `mcp.session.id` | string | optional | Identifies the MCP session. Can be undefined as MCP servers can be stateless. | `"191c4850af6c49..."` |
25+
| `network.protocol.version` | string | optional | The version of JSON RPC protocol used. | `"2.0"` |
26+
27+
**[2]** Well-defined values for data attribute `mcp.transport`:
28+
29+
| Value | Description |
30+
| :------- | :------------------------------------ |
31+
| `"http"` | HTTP transport |
32+
| `"sse"` | Server-Sent Events transport |
33+
| `"stdio"` | Standard input/output transport |
34+
| `"unknown"`* | Unknown transport (for custom transports)|
35+
36+
*`"unknown"` is a placeholder for custom transports. We could try to infer the name from the transport object.
37+
38+
**[3]** Well-defined values for data attribute `network.transport`:
39+
40+
| Value | Description |
41+
| :------- | :------------------------------------ |
42+
| `"pipe"` | Named pipe (for stdio transport) |
43+
| `"tcp"` | TCP (for HTTP/SSE transport) |
44+
45+
### Session Management
46+
47+
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.)
48+
49+
#### Stateless vs Stateful Servers
50+
51+
**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.
52+
53+
**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.
54+
55+
#### Session Data Attributes
56+
57+
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.
58+
59+
| Data Attribute | Type | Requirement Level | Description | Example |
60+
| :-------------------------- | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- |
61+
| `mcp.client.name` | string | optional | Name of the MCP client application. | `"claude-desktop"` |
62+
| `mcp.client.title` | string | optional | Display title of the MCP client application. | `"Claude Desktop"` |
63+
| `mcp.client.version` | string | optional | Version of the MCP client application. | `"1.0.0"` |
64+
| `mcp.server.name` | string | optional | Name of the MCP server application. | `"my-mcp-server"` |
65+
| `mcp.server.title` | string | optional | Display title of the MCP server application. | `"My MCP Server"` |
66+
| `mcp.server.version` | string | optional | Version of the MCP server application. | `"2.1.3"` |
67+
| `mcp.protocol.version` | string | optional | MCP protocol version used in the session. | `"2024-11-05"` |
68+
69+
#### Session Lifecycle
70+
71+
1. **Initialization**: During the `initialize` request, session metadata (client info, server info, protocol version) is established and stored.
72+
73+
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.
74+
75+
3. **Evolution**: As the MCP specification evolves, additional session-level metadata may be captured and propagated, providing richer context for observability.
76+
77+
This session-based approach allows us to:
78+
- Track client and server versions across infrastructure
79+
- Analyze protocol version adoption and compatibility
80+
- Group and correlate all operations within a single client session
81+
- Monitor session duration and patterns
82+
83+
### MCP Server Span Types
84+
85+
MCP Server spans use the operation value `"mcp.server"` and fall into these categories:
86+
87+
**Server Methods** (op: `"mcp.server"`):
88+
- **Tool calls** - `tools/call {tool_name}` - Execute client-requested tools
89+
- **Prompt requests** - `prompts/get {prompt_name}` - Provide prompt templates to clients
90+
- **Resource access** - `resources/read {resource_uri}` - Serve resources to clients
91+
92+
**Notifications** (op: `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`):
93+
- One-way messages that don't expect responses (e.g., `notifications/cancelled`)
94+
95+
**Others** (op: `"mcp.server"`):
96+
- **Initialization** - `initialize` - Handle client connection setup
97+
98+
### Tool Call Span
99+
100+
Describes MCP tool execution requests from clients.
101+
102+
- The spans `op` MUST be `"mcp.server"`.
103+
- The span `name` SHOULD follow the pattern `"tools/call {mcp.tool.name}"`. (e.g. `"tools/call get_weather"`)
104+
- The `mcp.method.name` attribute MUST be `"tools/call"`.
105+
- The `mcp.tool.name` attribute SHOULD be set to the tool name. (e.g. `"get_weather"`)
106+
- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set).
107+
108+
Additional attributes on the span:
109+
110+
| Data Attribute | Type | Requirement Level | Description | Example |
111+
| :------------------------------------ | :------ | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- |
112+
| `mcp.tool.result.is_error` | boolean | optional | Whether the tool execution resulted in an error. | `true` |
113+
| `mcp.tool.result.content_count` | int | optional | Number of content items in the tool result. | `3` |
114+
| `mcp.tool.result.content` | string | optional | Serialized content of the tool result. **[0]** | `"[{\"type\":\"text\"}]"` |
115+
| `mcp.request.argument.<key>` | string | optional | Arguments passed to the tool. **[1]** | `"Seattle, WA"` |
116+
117+
**[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\"}]"`.
118+
**[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`.
119+
120+
### Prompt Span
121+
122+
Describes MCP prompt requests from clients.
123+
124+
- The spans `op` MUST be `"mcp.server"`.
125+
- The span `name` SHOULD follow the pattern `"prompts/get {mcp.prompt.name}"`. (e.g. `"prompts/get analyze-code"`)
126+
- The `mcp.method.name` attribute MUST be `"prompts/get"`.
127+
- The `mcp.prompt.name` attribute SHOULD be set to the prompt name. (e.g. `"analyze-code"`)
128+
- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set).
129+
130+
Additional attributes on the span:
131+
132+
| Data Attribute | Type | Requirement Level | Description | Example |
133+
| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- |
134+
| `mcp.request.argument.<key>` | string | optional | Additional arguments passed to the prompt. **[1]** | `"javascript"` |
135+
136+
### Resource Span
137+
138+
Describes MCP resource access requests from clients.
139+
140+
- The spans `op` MUST be `"mcp.server"`.
141+
- The span `name` SHOULD follow the pattern `"resources/read {mcp.resource.uri}"`. (e.g. `"resources/read file:///path/to/file"`)
142+
- The `mcp.method.name` attribute MUST be `"resources/read"`.
143+
- The `mcp.resource.uri` attribute SHOULD be set to the resource URI. (e.g. `"file:///path/to/file"`)
144+
- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set).
145+
146+
Additional attributes on the span:
147+
148+
| Data Attribute | Type | Requirement Level | Description | Example |
149+
| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- |
150+
| `mcp.resource.name` | string | optional | The name of the resource being accessed. | `"sentry-docs-platform"` |
151+
152+
### Initialize Span
153+
154+
Describes MCP initialization requests from clients.
155+
156+
- The spans `op` MUST be `"mcp.server"`.
157+
- The span `name` SHOULD be `"initialize"`.
158+
- The `mcp.method.name` attribute MUST be `"initialize"`.
159+
- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set).
160+
161+
Additional attributes on the span:
162+
163+
| Data Attribute | Type | Requirement Level | Description | Example |
164+
| :------------------------------------ | :----- | :---------------- | :---------------------------------------------------------------------------- | :------------------------------------- |
165+
| `client.address` | string | optional | Client address - domain name or IP address. | `"127.0.0.1"` |
166+
| `client.port` | int | optional | Client port number. | `8080` |
167+
168+
### Notification Span
169+
170+
Describes MCP notification messages (one-way messages that don't expect a response).
171+
172+
- The spans `op` MUST be `"mcp.notification.client_to_server"` or `"mcp.notification.server_to_client"`.
173+
- The span `name` SHOULD be the notification method name. (e.g. `"notifications/cancelled"`)
174+
- The `mcp.method.name` attribute MUST be set to the notification method. (e.g. `"notifications/cancelled"`)
175+
- All [Common Span Attributes](#common-span-attributes) SHOULD be set (all `required` common attributes MUST be set).
176+

0 commit comments

Comments
 (0)