Send MCP Server Errors to Sentry for Real-Time Alerting

Kashish Hora

Kashish Hora

Co-founder of MCPcat

Try out MCPcat

The Quick Answer

Connect your MCP server to Sentry in seconds using MCPcat telemetry for real-time error tracking:

import mcpcat from 'mcpcat'

mcpcat.track(server, null, {
  exporters: {
    sentry: {
      type: "sentry",
      dsn: process.env.SENTRY_DSN,
      environment: "production",
      enableTracing: true
    }
  }
})

This immediately starts forwarding MCP errors to Sentry's Issues tab and performance data to the Performance tab. Replace with your Sentry DSN from project settings.

Prerequisites

  • Sentry account with a project created
  • Sentry DSN from your project settings (Settings → Client Keys)
  • MCPcat SDK installed (npm install mcpcat or pip install mcpcat)
  • MCP server running in production or development

Installation

Install the MCPcat SDK for your language:

# TypeScript/JavaScript
$npm install mcpcat
 
# Python
$pip install mcpcat

Configuration

MCPcat's Sentry integration automatically formats MCP events as Sentry logs, errors, and optionally performance transactions. The integration maps MCP session IDs to Sentry trace IDs for complete session tracking.

Basic Error Tracking Setup

Start with basic error tracking to capture all MCP errors in Sentry's Issues tab:

import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import mcpcat from 'mcpcat'

const server = new Server({
  name: 'my-mcp-server',
  version: '1.0.0'
})

// Initialize Sentry error tracking
mcpcat.track(server, null, {
  exporters: {
    sentry: {
      type: "sentry",
      dsn: "https://key@o123456.ingest.sentry.io/789",
      environment: process.env.NODE_ENV || "development"
    }
  }
})

The DSN uniquely identifies your Sentry project. Find it in your Sentry project under Settings → Client Keys. The environment field helps you filter events by deployment environment.

Performance Monitoring Setup

Enable performance tracing to track operation durations and identify slow operations:

import mcpcat
from mcp import Server

server = Server(
    name="my-mcp-server",
    version="1.0.0"
)

# Enable both error and performance tracking
mcpcat.track(server, None, mcpcat.MCPCatOptions(
    exporters={
        "sentry": {
            "type": "sentry",
            "dsn": "https://key@o123456.ingest.sentry.io/789",
            "environment": "production",
            "release": "1.0.0",
            "enable_tracing": True  # Enables performance monitoring
        }
    }
))

With tracing enabled, Sentry receives transaction events showing operation timing, allowing you to identify performance bottlenecks in your MCP server's tool execution.

Multi-Platform Integration

You can send events to both MCPcat and Sentry simultaneously, or combine with other observability platforms:

mcpcat.track(server, "proj_YOUR_MCPCAT_ID", {
  exporters: {
    sentry: {
      type: "sentry",
      dsn: process.env.SENTRY_DSN,
      environment: "production",
      enableTracing: true
    },
    otlp: {
      type: "otlp",
      endpoint: "http://localhost:4318/v1/traces",
      headers: { "api-key": process.env.OTLP_API_KEY }
    }
  }
})

This configuration sends events to MCPcat's dashboard, Sentry for error tracking, and an OpenTelemetry backend for comprehensive observability.

Usage

Automatic Error Capture

MCPcat automatically captures and forwards errors from your MCP server operations:

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  try {
    const result = await processToolCall(request.params.name)
    return result
  } catch (error) {
    // MCPcat automatically sends this to Sentry
    throw new McpError(
      ErrorCode.InternalError,
      `Tool execution failed: ${error.message}`
    )
  }
})

When errors occur, Sentry receives a structured event containing the error details, session context, and user information if identified. The error appears in Sentry's Issues tab with full stack traces.

User Identification

Track which users encounter errors by identifying them in your MCP sessions:

// Identify user when session starts
mcpcat.identify({
  id: "user_123",
  name: "John Doe",
  email: "john@example.com",
  plan: "premium"
})

// All subsequent errors include user context

Sentry displays identified users in error reports, helping you understand impact and reach out to affected users proactively.

Custom Error Context

Add custom context to errors for better debugging:

# Track user intent for context
mcpcat.track_user_intent("analyzing database performance metrics")

# Errors now include the user's intent
try:
    result = analyze_database()
except Exception as e:
    # Sentry receives error with intent context
    raise McpError(
        ErrorCode.InternalError,
        f"Database analysis failed: {str(e)}"
    )

The user intent appears in Sentry's extra data, providing crucial context about what the user was trying to accomplish when the error occurred.

Performance Transaction Tracking

With tracing enabled, Sentry tracks operation performance automatically:

// Long-running operations are tracked as transactions
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  // Transaction starts automatically
  const data = await fetchLargeDataset()  // 2.3s
  const processed = await processData(data)  // 1.1s
  const result = await generateReport(processed)  // 0.8s

  // Transaction ends, total duration sent to Sentry: 4.2s
  return result
})

Sentry's Performance tab shows transaction waterfalls, helping identify which operations contribute most to response times.

Advanced Usage

Release Tracking

Track deployments and correlate errors with releases:

mcpcat.track(server, null, {
  exporters: {
    sentry: {
      type: "sentry",
      dsn: process.env.SENTRY_DSN,
      environment: "production",
      release: `my-mcp-server@${process.env.GIT_SHA || '1.0.0'}`,
      enableTracing: true
    }
  }
})

Sentry groups errors by release, showing regression trends and helping you identify which deployments introduced issues. Use semantic versioning or git SHAs for precise tracking.

Alert Configuration

Configure Sentry alerts for MCP-specific issues:

  1. Navigate to Alerts → Create Alert Rule in Sentry
  2. Set conditions like "When error rate exceeds 5% for tool calls"
  3. Filter by tags: event_type:tools/call or server_name:my-mcp-server
  4. Configure notifications via email, Slack, or PagerDuty

Sentry's alerting uses the tags MCPcat provides, allowing granular control over when you're notified about MCP server issues.

Common Issues

Issue: Events Not Appearing in Sentry

When events don't appear in Sentry, the DSN configuration is often incorrect. Verify your DSN matches exactly what's shown in Sentry's project settings, including the protocol, key, organization ID, and project ID.

// Incorrect: Missing protocol or wrong format
dsn: "key@o123456.ingest.sentry.io/789"  // Missing https://
dsn: "https://o123456.ingest.sentry.io/789"  // Missing key

// Correct: Full DSN from Sentry settings
dsn: "https://abc123def456@o123456.ingest.sentry.io/789"

Also ensure your network allows outbound HTTPS connections to Sentry's ingestion endpoints. Corporate firewalls sometimes block these connections.

Issue: Performance Data Missing

Performance transactions only appear when enableTracing is explicitly set to true. Without this flag, Sentry only receives error events, not timing data.

# Only sends errors, no performance data
exporters = {
    "sentry": {
        "type": "sentry",
        "dsn": dsn
    }
}

# Sends both errors and performance transactions
exporters = {
    "sentry": {
        "type": "sentry",
        "dsn": dsn,
        "enable_tracing": True  # Required for performance tab
    }
}

Performance monitoring requires a Sentry plan that includes transaction events. Free plans have limited transaction quotas.

Issue: User Context Not Attached

User identification must happen before errors occur in the session. Call identify early in your session lifecycle:

// Too late - error already occurred
server.onerror = (error) => {
  mcpcat.identify({ id: "user_123" })  // Won't attach to this error
  throw error
}

// Correct - identify when session starts
server.onsessionstart = () => {
  mcpcat.identify({ id: "user_123" })  // Attaches to all subsequent events
}

User context persists throughout the session once set, appearing in all subsequent error and transaction events.

Examples

Production Error Monitoring System

Here's a complete setup for production MCP server monitoring with Sentry:

import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import mcpcat from 'mcpcat'
import { config } from 'dotenv'

config()  // Load environment variables

const server = new Server({
  name: 'production-mcp-server',
  version: process.env.npm_package_version
})

// Configure comprehensive monitoring
mcpcat.track(server, process.env.MCPCAT_PROJECT_ID, {
  exporters: {
    sentry: {
      type: "sentry",
      dsn: process.env.SENTRY_DSN,
      environment: process.env.NODE_ENV,
      release: `${server.name}@${process.env.GIT_SHA}`,
      enableTracing: true
    }
  }
})

// Add error boundaries for critical operations
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const startTime = Date.now()

  try {
    // Track what user is trying to do
    mcpcat.trackUserIntent(request.params.arguments?.intent)

    const result = await executeToolWithTimeout(
      request.params.name,
      request.params.arguments,
      30000  // 30 second timeout
    )

    return {
      content: [{
        type: "text",
        text: JSON.stringify(result)
      }]
    }
  } catch (error) {
    // Sentry automatically receives this with full context
    console.error(`Tool ${request.params.name} failed:`, error)

    throw new McpError(
      ErrorCode.InternalError,
      `Tool execution failed after ${Date.now() - startTime}ms: ${error.message}`
    )
  }
})

// Graceful shutdown
process.on('SIGTERM', () => {
  console.log('Shutting down MCP server...')
  // MCPcat flushes pending events to Sentry
  server.close()
})

This production setup includes release tracking for deployment correlation, performance monitoring to identify slow operations, and graceful shutdown handling to ensure all events reach Sentry. The timeout wrapper prevents hung operations, and user intent tracking provides debugging context.

Debugging Workflow Integration

Combine Sentry alerts with debugging workflows for rapid incident response:

import mcpcat
import logging
from mcp import Server
from sentry_sdk import capture_message

server = Server(name="debug-enabled-server", version="1.0.0")

# Configure with debug mode awareness
is_debug = os.getenv("DEBUG", "false").lower() == "true"

mcpcat.track(server, None, mcpcat.MCPCatOptions(
    exporters={
        "sentry": {
            "type": "sentry",
            "dsn": os.getenv("SENTRY_DSN"),
            "environment": "debug" if is_debug else "production",
            "enable_tracing": True,
            "release": f"debug-{datetime.now().isoformat()}" if is_debug else os.getenv("RELEASE")
        }
    }
))

# Enhanced error handler with debug breadcrumbs
@server.call_tool()
async def analyze_data(name: str, arguments: dict) -> list:
    # Add breadcrumb for debugging
    if is_debug:
        capture_message(f"Starting {name} with args: {arguments}", level="debug")

    try:
        # Detailed logging in debug mode
        if is_debug:
            logging.info(f"Processing stage 1: data validation")

        validated = validate_input(arguments)

        if is_debug:
            logging.info(f"Processing stage 2: data transformation")

        result = transform_data(validated)
        return [{"type": "text", "text": str(result)}]

    except ValidationError as e:
        # Rich error context for debugging
        error_context = {
            "tool": name,
            "arguments": arguments,
            "validation_errors": e.errors(),
            "stage": "validation"
        }

        if is_debug:
            capture_message("Validation failed", level="warning", extras=error_context)

        raise McpError(
            ErrorCode.InvalidParams,
            f"Validation failed: {e.message}",
            data=error_context
        )

This debug-aware configuration sends detailed breadcrumbs to Sentry in debug mode while maintaining clean production logs. The separate debug environment in Sentry prevents development errors from triggering production alerts while still capturing valuable debugging information.