getsentry / getsentry/sentry-python

MCPIntegration bypasses ignore_errors when FastMCP wraps exceptions in ToolError

Abierto
#5,473 2 comentarios 0 reacciones 1 asignado Reclamado por @alexander-alderman-webb Ver en GitHub
Bug Errors Python
Lenguaje dominante
Python
Estrellas
2.2k
Forks
669
Merge medio
1 d 40 min
PR fusionados (30 d)
212

Descripción

## Problem

The `MCPIntegration` (auto-enabled since sentry-sdk 2.45) captures exceptions that should be filtered by `ignore_errors` because it sees the FastMCP-wrapped `ToolError` instead of the original exception type.

When using `ignore_errors` to suppress specific exception types raised by MCP tool handlers, the filtering doesn't work because of the order of exception wrapping:

1. Tool handler raises a custom exception (e.g. `ExpectedToolError`)
2. FastMCP's `tool_manager.call_tool()` catches it and wraps it in `ToolError`: `raise ToolError(...) from e`
3. `ToolError` propagates up through FastMCP's `_call_tool_mcp`
4. The `MCPIntegration`'s `_async_handler_wrapper` catches `ToolError` and calls `sentry_sdk.capture_exception(e)` ([link](https://github.com/getsentry/sentry-python/blob/master/sentry_sdk/integrations/mcp.py#L429))
5. `_is_ignored_error` checks `issubclass(ToolError, ExpectedToolError)` → **False** → event is sent to Sentry

The `ignore_errors` configuration never sees the original exception type because FastMCP has already wrapped it.

## Expected Behavior

Exceptions listed in `ignore_errors` (or their subclasses) should not be sent to Sentry, even when FastMCP wraps them in `ToolError`. The integration should either walk the exception chain (`__cause__`) or skip capturing exceptions that are already handled by the framework.

## Reproduction

```python
import sentry_sdk
from sentry_sdk.integrations.mcp import MCPIntegration
from fastmcp import FastMCP

class ExpectedToolError(Exception):
"""Should not be reported to Sentry."""
pass

sentry_sdk.init(
dsn="...",
ignore_errors=[ExpectedToolError],
)

mcp = FastMCP("test")

@mcp.tool()
def my_tool() -> str:
raise ExpectedToolError("This is expected and should not go to Sentry")
```

When `my_tool` is called, the `ExpectedToolError` ends up in Sentry because the MCPIntegration captures the wrapping `ToolError`.

## Workaround

Disable the `MCPIntegration` if you handle MCP error reporting yourself:

```python
sentry_sdk.init(
dsn="...",
disabled_integrations=[MCPIntegration()],
ignore_errors=[ExpectedToolError],
)
```

## Environment

- sentry-sdk: 2.51.0
- fastmcp: 2.14.4
- mcp: 1.26.0
- Python: 3.13

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.