|
| 1 | +--- |
| 2 | +title: Instrument MCP Servers |
| 3 | +sidebar_order: 600 |
| 4 | +description: "Learn how to manually instrument your code to use Sentry's MCP monitoring." |
| 5 | +supported: |
| 6 | + - javascript.node |
| 7 | + - javascript.aws-lambda |
| 8 | + - javascript.azure-functions |
| 9 | + - javascript.connect |
| 10 | + - javascript.express |
| 11 | + - javascript.fastify |
| 12 | + - javascript.gcp-functions |
| 13 | + - javascript.hapi |
| 14 | + - javascript.hono |
| 15 | + - javascript.koa |
| 16 | + - javascript.nestjs |
| 17 | + - javascript.bun |
| 18 | + - javascript.deno |
| 19 | + - javascript.nextjs |
| 20 | + - javascript.nuxt |
| 21 | + - javascript.astro |
| 22 | + - javascript.solidstart |
| 23 | + - javascript.sveltekit |
| 24 | + - javascript.remix |
| 25 | + - javascript.cloudflare |
| 26 | + - javascript.tanstackstart-react |
| 27 | +--- |
| 28 | + |
| 29 | +With Sentry's [MCP monitoring](/product/insights/ai/mcp/), you can track and debug MCP servers with full-stack context. You'll be able to monitor tool executions, prompt retrievals, resource access, and error rates. MCP monitoring data will be fully connected to your other Sentry data like logs, errors, and traces. |
| 30 | + |
| 31 | +As a prerequisite to setting up MCP monitoring with JavaScript, you'll need to first <PlatformLink to="/tracing/">set up tracing</PlatformLink>. Once this is done, the JavaScript SDK will automatically instrument MCP servers created with supported libraries. If that doesn't fit your use case, you can use custom instrumentation described below. |
| 32 | + |
| 33 | +## Automatic Instrumentation |
| 34 | + |
| 35 | +The JavaScript SDK supports automatic instrumentation for MCP servers. We recommend adding the MCP integration to your Sentry configuration to automatically capture spans for MCP operations. |
| 36 | + |
| 37 | +- <PlatformLink to="/integrations/mcp/"> |
| 38 | + MCP (Model Context Protocol) |
| 39 | + </PlatformLink> |
| 40 | + |
| 41 | +## Manual Instrumentation |
| 42 | + |
| 43 | +For your MCP data to show up in Sentry, spans must be created with well-defined names and data attributes. See below for the different types of MCP operations you can instrument. |
| 44 | + |
| 45 | +The [Sentry.startSpan()](/platforms/javascript/tracing/instrumentation/custom-instrumentation/#starting-a-span) method can be used to create these spans. |
| 46 | + |
| 47 | +## Spans |
| 48 | + |
| 49 | +### Tool Execution Span |
| 50 | + |
| 51 | +<Include name="tracing/mcp-module/tool-execution-span" /> |
| 52 | + |
| 53 | +#### Example Tool Execution Span: |
| 54 | + |
| 55 | +```javascript |
| 56 | +import * as Sentry from "@sentry/node"; |
| 57 | + |
| 58 | +Sentry.init({ |
| 59 | + // ... your Sentry configuration |
| 60 | +}); |
| 61 | + |
| 62 | +// Example tool execution |
| 63 | +const toolName = "get_weather"; |
| 64 | +const toolArguments = { city: "San Francisco" }; |
| 65 | + |
| 66 | +await Sentry.startSpan( |
| 67 | + { |
| 68 | + op: "mcp.server", |
| 69 | + name: `tools/call ${toolName}`, |
| 70 | + }, |
| 71 | + async (span) => { |
| 72 | + // Set MCP-specific attributes |
| 73 | + span.setAttribute("mcp.tool.name", toolName); |
| 74 | + span.setAttribute("mcp.method.name", "tools/call"); |
| 75 | + |
| 76 | + // Set request metadata |
| 77 | + span.setAttribute("mcp.request.id", "req_123abc"); |
| 78 | + span.setAttribute("mcp.session.id", "session_xyz789"); |
| 79 | + span.setAttribute("mcp.transport", "stdio"); // or "http", "sse" for HTTP/WebSocket/SSE |
| 80 | + span.setAttribute("network.transport", "pipe"); // or "tcp" for HTTP/SSE |
| 81 | + |
| 82 | + // Set tool arguments (optional, if send_default_pii=true) |
| 83 | + for (const [key, value] of Object.entries(toolArguments)) { |
| 84 | + span.setAttribute(`mcp.request.argument.${key}`, value); |
| 85 | + } |
| 86 | + |
| 87 | + // Execute the tool |
| 88 | + try { |
| 89 | + const result = executeTool(toolName, toolArguments); |
| 90 | + |
| 91 | + // Set result data |
| 92 | + span.setAttribute("mcp.tool.result.content", JSON.stringify(result)); |
| 93 | + span.setAttribute("mcp.tool.result.is_error", false); |
| 94 | + |
| 95 | + // Set result content count if applicable |
| 96 | + if ( |
| 97 | + Array.isArray(result) || |
| 98 | + (typeof result === "object" && result !== null) |
| 99 | + ) { |
| 100 | + span.setAttribute( |
| 101 | + "mcp.tool.result.content_count", |
| 102 | + Array.isArray(result) ? result.length : Object.keys(result).length |
| 103 | + ); |
| 104 | + } |
| 105 | + } catch (error) { |
| 106 | + span.setAttribute("mcp.tool.result.is_error", true); |
| 107 | + throw error; |
| 108 | + } |
| 109 | + } |
| 110 | +); |
| 111 | +``` |
| 112 | + |
| 113 | +### Prompt Retrieval Span |
| 114 | + |
| 115 | +<Include name="tracing/mcp-module/prompt-retrieval-span" /> |
| 116 | + |
| 117 | +#### Example Prompt Retrieval Span: |
| 118 | + |
| 119 | +```javascript |
| 120 | +import * as Sentry from "@sentry/node"; |
| 121 | + |
| 122 | +Sentry.init({ |
| 123 | + // ... your Sentry configuration |
| 124 | +}); |
| 125 | + |
| 126 | +// Example prompt retrieval |
| 127 | +const promptName = "code_review"; |
| 128 | +const promptArguments = { language: "python" }; |
| 129 | + |
| 130 | +await Sentry.startSpan( |
| 131 | + { |
| 132 | + op: "mcp.server", |
| 133 | + name: `prompts/get ${promptName}`, |
| 134 | + }, |
| 135 | + async (span) => { |
| 136 | + // Set MCP-specific attributes |
| 137 | + span.setAttribute("mcp.prompt.name", promptName); |
| 138 | + span.setAttribute("mcp.method.name", "prompts/get"); |
| 139 | + |
| 140 | + // Set request metadata |
| 141 | + span.setAttribute("mcp.request.id", "req_456def"); |
| 142 | + span.setAttribute("mcp.session.id", "session_xyz789"); |
| 143 | + span.setAttribute("mcp.transport", "http"); |
| 144 | + span.setAttribute("network.transport", "tcp"); |
| 145 | + |
| 146 | + // Set prompt arguments (optional, if send_default_pii=true) |
| 147 | + for (const [key, value] of Object.entries(promptArguments)) { |
| 148 | + span.setAttribute(`mcp.request.argument.${key}`, value); |
| 149 | + } |
| 150 | + |
| 151 | + // Retrieve the prompt |
| 152 | + const promptResult = getPrompt(promptName, promptArguments); |
| 153 | + |
| 154 | + // Set result data |
| 155 | + const messages = promptResult.messages || []; |
| 156 | + span.setAttribute("mcp.prompt.result.message_count", messages.length); |
| 157 | + |
| 158 | + // For single-message prompts, set role and content |
| 159 | + if (messages.length === 1) { |
| 160 | + span.setAttribute("mcp.prompt.result.message_role", messages[0].role); |
| 161 | + // Content is PII, only set if send_default_pii=true |
| 162 | + span.setAttribute( |
| 163 | + "mcp.prompt.result.message_content", |
| 164 | + JSON.stringify(messages[0].content) |
| 165 | + ); |
| 166 | + } |
| 167 | + } |
| 168 | +); |
| 169 | +``` |
| 170 | + |
| 171 | +### Resource Read Span |
| 172 | + |
| 173 | +<Include name="tracing/mcp-module/resource-read-span" /> |
| 174 | + |
| 175 | +#### Example Resource Read Span: |
| 176 | + |
| 177 | +```javascript |
| 178 | +import * as Sentry from "@sentry/node"; |
| 179 | + |
| 180 | +Sentry.init({ |
| 181 | + // ... your Sentry configuration |
| 182 | +}); |
| 183 | + |
| 184 | +// Example resource access |
| 185 | +const resourceUri = "file:///path/to/resource.txt"; |
| 186 | + |
| 187 | +await Sentry.startSpan( |
| 188 | + { |
| 189 | + op: "mcp.server", |
| 190 | + name: `resources/read ${resourceUri}`, |
| 191 | + }, |
| 192 | + async (span) => { |
| 193 | + // Set MCP-specific attributes |
| 194 | + span.setAttribute("mcp.resource.uri", resourceUri); |
| 195 | + span.setAttribute("mcp.method.name", "resources/read"); |
| 196 | + |
| 197 | + // Set request metadata |
| 198 | + span.setAttribute("mcp.request.id", "req_789ghi"); |
| 199 | + span.setAttribute("mcp.session.id", "session_xyz789"); |
| 200 | + span.setAttribute("mcp.transport", "http"); |
| 201 | + span.setAttribute("network.transport", "tcp"); |
| 202 | + |
| 203 | + // Access the resource |
| 204 | + const resourceData = readResource(resourceUri); |
| 205 | + } |
| 206 | +); |
| 207 | +``` |
| 208 | + |
| 209 | +## Common Span Attributes |
| 210 | + |
| 211 | +<Include name="tracing/mcp-module/common-span-attributes" /> |
0 commit comments