---
title: "MCP Monitoring"
description: "Monitor MCP server tool executions, prompt retrievals, resource access, and errors."
url: https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring/
---

# Set Up MCP Monitoring | Sentry for Flue

With Sentry's [MCP Monitoring](https://docs.sentry.io/product/mcp-servers.md), you can track and debug MCP servers with full-stack context. You can monitor tool executions, prompt retrievals, resource access, and error rates alongside your other Sentry data, including logs, errors, and traces.

Before you begin, [set up tracing](https://docs.sentry.io/platforms/javascript/guides/flue/tracing.md).

## [Instrument the MCP Server](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#instrument-the-mcp-server)

Wrap each `McpServer` instance with `wrapMcpServerWithSentry` to automatically record MCP requests, tool calls, prompt retrievals, resource reads, and handler errors.

Import Sentry from your framework's SDK package, then wrap the MCP server instance before connecting it to a transport:

```javascript
import * as Sentry from "<sdk-package-name>";
import { McpServer } from "@modelcontextprotocol/server";

const server = Sentry.wrapMcpServerWithSentry(
  new McpServer({
    name: "my-mcp-server",
    version: "1.0.0",
  }),
);
```

Register tools, prompts, and resources on `server` as usual. The wrapper returns the same server instance.

Support for `@modelcontextprotocol/server` 2.x requires Sentry JavaScript SDK version `10.70.0` or newer. For `@modelcontextprotocol/sdk` 1.x, use Sentry JavaScript SDK version `9.46.0` or newer and import `McpServer` from `@modelcontextprotocol/sdk/server/mcp.js`. The Sentry wrapper is otherwise the same.

### [Configure Input and Output Recording](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#configure-input-and-output-recording)

By default, the SDK sends the inputs and outputs of your MCP tool calls, prompt retrievals, and resource reads. This gives you rich debugging context. MCP payloads can carry sensitive data, such as tokens, file paths, or private user content. Review what your server handles before you deploy to production.

The [`dataCollection.genAI`](https://docs.sentry.io/platforms/javascript/guides/flue/configuration/options.md#dataCollection) option controls this recording globally for both MCP and AI instrumentation:

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  dataCollection: {
    genAI: { inputs: false, outputs: false },
  },
});
```

Use `recordInputs` and `recordOutputs` to control recording for a specific server. These options override the `dataCollection.genAI` settings:

```javascript
const server = Sentry.wrapMcpServerWithSentry(mcpServer, {
  recordInputs: false,
  recordOutputs: false,
});
```

The `recordInputs` and `recordOutputs` options require Sentry JavaScript SDK version `10.33.0` or newer. In version 10, the SDK records inputs and outputs only when you set the `dataCollection` option or enable them on the wrapper. Starting with version 11, it records them by default.

## [Manual Instrumentation](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#manual-instrumentation)

The setup above automatically instruments MCP servers built with the official [MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk) (`@modelcontextprotocol/sdk`). If your server uses a different library or a custom implementation that `wrapMcpServerWithSentry` can't wrap, you can record the same spans manually.

You don't need this if you're already using `wrapMcpServerWithSentry` — it creates these spans for you. Otherwise, use [Sentry.startSpan()](https://docs.sentry.io/platforms/javascript/tracing/instrumentation/custom-instrumentation.md#starting-a-span) to create the spans described below.

## [Spans](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#spans)

### [Tool Execution Span](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#tool-execution-span)

Describes MCP tool execution.

* The span `op` (transaction mode) or the span's `sentry.op` attribute (stream mode) MUST be `"mcp.server"`.
* The span `name` SHOULD be `"tools/call {mcp.tool.name}"`.
* The `mcp.tool.name` attribute MUST be set to the tool's name. (e.g. `"get_weather"`)
* The `mcp.method.name` attribute SHOULD be set to `"tools/call"`.
* All [Common Span Attributes](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#common-span-attributes) SHOULD be set.

Additional attributes on the span:

| Data Attribute                  | Type    | Requirement Level | Description                                              | Example                                           |
| ------------------------------- | ------- | ----------------- | -------------------------------------------------------- | ------------------------------------------------- |
| `mcp.tool.name`                 | string  | required          | The name of the MCP tool being called.                   | `"get_weather"`                                   |
| `mcp.method.name`               | string  | recommended       | Should be set to "tools/call".                           | `"tools/call"`                                    |
| `mcp.request.id`                | string  | optional          | The unique identifier for the MCP request.               | `"req_123abc"`                                    |
| `mcp.request.argument.*`        | any     | optional          | Tool input arguments (requires `send_default_pii=True`). | `"San Francisco"` for `mcp.request.argument.city` |
| `mcp.tool.result.content`       | string  | optional          | The result/output content from the tool execution.       | `"The weather is sunny"`                          |
| `mcp.tool.result.content_count` | int     | optional          | The number of items/keys in the tool result.             | `5`                                               |
| `mcp.tool.result.is_error`      | boolean | optional          | Whether the tool execution resulted in an error.         | `True`                                            |

#### [Example Tool Execution Span:](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#example-tool-execution-span)

```javascript
// Example tool execution
const toolName = "get_weather";
const toolArguments = { city: "San Francisco" };

await Sentry.startSpan(
  {
    op: "mcp.server",
    name: `tools/call ${toolName}`,
  },
  async (span) => {
    // Set MCP-specific attributes
    span.setAttribute("mcp.tool.name", toolName);
    span.setAttribute("mcp.method.name", "tools/call");

    // Set request metadata
    span.setAttribute("mcp.request.id", "req_123abc");
    span.setAttribute("mcp.session.id", "session_xyz789");
    span.setAttribute("mcp.transport", "stdio"); // or "http", "sse" for HTTP/WebSocket/SSE
    span.setAttribute("network.transport", "pipe"); // or "tcp" for HTTP/SSE

    // Set tool arguments (optional, requires recordInputs: true)
    for (const [key, value] of Object.entries(toolArguments)) {
      span.setAttribute(`mcp.request.argument.${key}`, value);
    }

    // Execute the tool
    try {
      const result = executeTool(toolName, toolArguments);

      // Set result data
      span.setAttribute("mcp.tool.result.content", JSON.stringify(result));
      span.setAttribute("mcp.tool.result.is_error", false);

      // Set result content count if applicable
      if (
        Array.isArray(result) ||
        (typeof result === "object" && result !== null)
      ) {
        span.setAttribute(
          "mcp.tool.result.content_count",
          Array.isArray(result)
            ? result.length
            : Object.keys(result).length,
        );
      }
    } catch (error) {
      span.setAttribute("mcp.tool.result.is_error", true);
      throw error;
    }
  },
);
```

### [Prompt Retrieval Span](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#prompt-retrieval-span)

Describes MCP prompt retrieval.

* The span `op` (transaction mode) or the span's `sentry.op` attribute (stream mode) MUST be `"mcp.server"`.
* The span `name` SHOULD be `"prompts/get {mcp.prompt.name}"`.
* The `mcp.prompt.name` attribute MUST be set to the prompt's name. (e.g. `"code_review"`)
* The `mcp.method.name` attribute SHOULD be set to `"prompts/get"`.
* All [Common Span Attributes](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#common-span-attributes) SHOULD be set.

Additional attributes on the span:

| Data Attribute                      | Type   | Requirement Level | Description                                                                       | Example                                        |
| ----------------------------------- | ------ | ----------------- | --------------------------------------------------------------------------------- | ---------------------------------------------- |
| `mcp.prompt.name`                   | string | required          | The name of the MCP prompt being retrieved.                                       | `"code_review"`                                |
| `mcp.method.name`                   | string | recommended       | Should be set to "prompts/get".                                                   | `"prompts/get"`                                |
| `mcp.request.id`                    | string | optional          | The unique identifier for the MCP request.                                        | `"req_456def"`                                 |
| `mcp.request.argument.*`            | any    | optional          | Prompt input arguments (requires `send_default_pii=True`).                        | `"python"` for `mcp.request.argument.language` |
| `mcp.prompt.result.message_content` | string | optional          | The message content from the prompt retrieval (requires `send_default_pii=True`). | `"Review the following code..."`               |
| `mcp.prompt.result.message_role`    | string | optional          | The role of the message (only for single-message prompts).                        | `"user"`, `"assistant"`, `"system"`            |
| `mcp.prompt.result.message_count`   | int    | optional          | The number of messages in the prompt result.                                      | `1`, `3`                                       |

#### [Example Prompt Retrieval Span:](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#example-prompt-retrieval-span)

```javascript
// Example prompt retrieval
const promptName = "code_review";
const promptArguments = { language: "python" };

await Sentry.startSpan(
  {
    op: "mcp.server",
    name: `prompts/get ${promptName}`,
  },
  async (span) => {
    // Set MCP-specific attributes
    span.setAttribute("mcp.prompt.name", promptName);
    span.setAttribute("mcp.method.name", "prompts/get");

    // Set request metadata
    span.setAttribute("mcp.request.id", "req_456def");
    span.setAttribute("mcp.session.id", "session_xyz789");
    span.setAttribute("mcp.transport", "http");
    span.setAttribute("network.transport", "tcp");

    // Set prompt arguments (optional, requires recordInputs: true)
    for (const [key, value] of Object.entries(promptArguments)) {
      span.setAttribute(`mcp.request.argument.${key}`, value);
    }

    // Retrieve the prompt
    const promptResult = getPrompt(promptName, promptArguments);

    // Set result data
    const messages = promptResult.messages || [];
    span.setAttribute("mcp.prompt.result.message_count", messages.length);

    // For single-message prompts, set role and content
    if (messages.length === 1) {
      span.setAttribute(
        "mcp.prompt.result.message_role",
        messages[0].role,
      );
      // Content may contain sensitive data, only set if recordOutputs: true
      span.setAttribute(
        "mcp.prompt.result.message_content",
        JSON.stringify(messages[0].content),
      );
    }
  },
);
```

### [Resource Read Span](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#resource-read-span)

Describes MCP resource access.

* The span `op` (transaction mode) or the span's `sentry.op` attribute (stream mode) MUST be `"mcp.server"`.
* The span `name` SHOULD be `"resources/read {mcp.resource.uri}"`.
* The `mcp.resource.uri` attribute MUST be set to the resource's URI. (e.g. `"file:///path/to/resource"`)
* The `mcp.method.name` attribute SHOULD be set to `"resources/read"`.
* All [Common Span Attributes](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#common-span-attributes) SHOULD be set.

Additional attributes on the span:

| Data Attribute          | Type   | Requirement Level | Description                                  | Example                       |
| ----------------------- | ------ | ----------------- | -------------------------------------------- | ----------------------------- |
| `mcp.resource.uri`      | string | required          | The URI of the MCP resource being accessed.  | `"file:///path/to/resource"`  |
| `mcp.method.name`       | string | recommended       | Should be set to "resources/read"            | `"resources/read"`            |
| `mcp.request.id`        | string | optional          | The unique identifier for the MCP request.   | `"req_789ghi"`                |
| `mcp.resource.protocol` | string | optional          | The protocol/scheme of the MCP resource URI. | `"file"`, `"http"`, `"https"` |

#### [Example Resource Read Span:](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#example-resource-read-span)

```javascript
// Example resource access
const resourceUri = "file:///path/to/resource.txt";

await Sentry.startSpan(
  {
    op: "mcp.server",
    name: `resources/read ${resourceUri}`,
  },
  async (span) => {
    // Set MCP-specific attributes
    span.setAttribute("mcp.resource.uri", resourceUri);
    span.setAttribute("mcp.method.name", "resources/read");

    // Set request metadata
    span.setAttribute("mcp.request.id", "req_789ghi");
    span.setAttribute("mcp.session.id", "session_xyz789");
    span.setAttribute("mcp.transport", "http");
    span.setAttribute("network.transport", "tcp");

    // Access the resource
    const resourceData = readResource(resourceUri);
  },
);
```

## [Common Span Attributes](https://docs.sentry.io/platforms/javascript/guides/flue/mcp-monitoring.md#common-span-attributes)

The following attributes are common across all MCP span types and SHOULD be set when available:

| Data Attribute      | Type   | Requirement Level | Description                                      | Example                    |
| ------------------- | ------ | ----------------- | ------------------------------------------------ | -------------------------- |
| `mcp.transport`     | string | recommended       | The transport method used for MCP communication. | `"stdio"`, `"sse", "http"` |
| `network.transport` | string | recommended       | The network transport used.                      | `"pipe"`, `"tcp"`          |
| `mcp.session.id`    | string | recommended       | The session identifier for the MCP connection.   | `"a1b2c3d4e5f6"`           |
| `mcp.request.id`    | string | optional          | The unique identifier for the MCP request.       | `"req_123abc"`             |
