← Back to dashboard
sentrymonitoringfresh

Sentry + Claude Code Integration Guide

Text
███████╗███████╗███╗   ██╗████████╗██████╗ ██╗   ██╗
██╔════╝██╔════╝████╗  ██║╚══██╔══╝██╔══██╗╚██╗ ██╔╝
███████╗█████╗  ██╔██╗ ██║   ██║   ██████╔╝ ╚████╔╝
╚════██║██╔══╝  ██║╚██╗██║   ██║   ██╔══██╗  ╚██╔╝
███████║███████╗██║ ╚████║   ██║   ██║  ██║   ██║
╚══════╝╚══════╝╚═╝  ╚═══╝   ╚═╝   ╚═╝  ╚═╝   ╚═╝

Sentry + Claude Code Integration Guide

Focus: Error monitoring, issue triage, and automated debugging workflows from Claude Code using the official Sentry MCP server and sentry-cli.

Overview

Sentry is the leading error and performance monitoring platform. Its official MCP server gives Claude Code read access to your issues, traces, spans, and Seer (AI root-cause analysis) — enabling automated triage, log-driven debugging, and performance investigation without leaving a coding session. Combined with sentry-cli for release management and source maps, it closes the loop between deploy and error resolution.

Here is the core loop at a glance — from a failure in your app all the way to a proposed fix in Claude Code:

Official Documentation


MCP Server Setup

Official Sentry MCP Server (Remote, OAuth)

Sentry hosts its MCP server at https://mcp.sentry.dev/mcp. Authentication is via OAuth — nothing to install.

Bash
# Add Sentry MCP to Claude Code
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp

Then run /mcp inside Claude Code to authenticate with your Sentry organization via OAuth.

.mcp.json Configuration (Token-based)

JSON
{
  "mcpServers": {
    "sentry": {
      "type": "http",
      "url": "https://mcp.sentry.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${SENTRY_AUTH_TOKEN}"
      }
    }
  }
}

Get your auth token at: https://sentry.io/settings/account/api/auth-tokens/

Available MCP Tools

ToolDescription
list_issuesList issues filtered by project, status, or search query
get_issueGet full issue details including stack trace
get_issue_summaryGet Seer's AI-generated root cause analysis
get_eventsGet individual error events for an issue
search_issuesFull-text search across your Sentry issues
list_projectsList all Sentry projects
get_performanceGet performance transactions and metrics
get_spansGet detailed span data for a trace
get_traceGet full distributed trace

Note: The Sentry MCP server provides read-only access. It cannot create, update, or delete issues.

Claude Code Plugin Integration

Sentry is available as a built-in Claude Code plugin, enabling automatic sub-agent delegation:

Bash
# The sentry plugin ships with Claude Code's superpower stack
# Ask Claude: "Check Sentry for recent auth errors"
# Claude automatically delegates to the Sentry MCP server

CLI Integration (sentry-cli)

Installation

Bash
# npm
npm install -g @sentry/cli

# macOS (brew)
brew install getsentry/tools/sentry-cli

# curl (Linux)
curl -sL https://sentry.io/get-cli/ | bash

Authentication

Bash
sentry-cli login
# Or use environment variables:
export SENTRY_AUTH_TOKEN=...
export SENTRY_ORG=my-org
export SENTRY_PROJECT=my-project

Key Commands

These commands chain into the release and source-map flow below — finalize a release so future errors map back to readable code:

Bash
# Create a release
sentry-cli releases new v1.2.3

# Associate commits with a release
sentry-cli releases set-commits v1.2.3 --auto

# Upload source maps
sentry-cli releases files v1.2.3 upload-sourcemaps ./dist \
  --url-prefix "~/static/js"

# Finalize the release (marks it as deployed)
sentry-cli releases finalize v1.2.3

# Create a deploy record
sentry-cli releases deploys v1.2.3 new \
  --env production \
  --name "GitHub Actions Deploy"

# List projects
sentry-cli projects list

# List issues (basic)
sentry-cli issues list --project my-project --status unresolved

# Resolve an issue
sentry-cli issues resolve ISSUE_ID

SDK Integration

JavaScript / TypeScript

Bash
npm install @sentry/nextjs  # or @sentry/node, @sentry/react, etc.

sentry.server.config.ts:

TypeScript
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NODE_ENV,
  release: process.env.NEXT_PUBLIC_APP_VERSION,
  tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,
  integrations: [
    Sentry.prismaIntegration(),  // auto-instrument Prisma
  ],
});

Capture custom errors with context

TypeScript
import * as Sentry from "@sentry/nextjs";

try {
  await processPayment(userId, amount);
} catch (error) {
  Sentry.withScope((scope) => {
    scope.setUser({ id: userId });
    scope.setTag("payment.amount", String(amount));
    scope.setLevel("error");
    Sentry.captureException(error);
  });
  throw error;
}

Scrubbing PII & secrets

Sentry never captures user IP or request headers/cookies by default — that behavior is gated behind sendDefaultPii, which defaults to false. Leave it off in production. For anything the SDK does capture (request bodies, query strings, exception values), use the beforeSend hook to redact M-Pesa phone numbers, OAuth tokens, and other secrets before the event leaves your server. beforeSend runs after all scope data is applied, so it's the last line of defense — return a modified event, or null to drop it entirely. Sentry also runs best-effort server-side scrubbing on ingest, but never rely on it alone for known-sensitive fields.

TypeScript
import * as Sentry from "@sentry/nextjs";

const REDACT = /(254\d{9})|(sntrys_[\w-]+)|(Bearer\s+[\w.-]+)/gi;

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NODE_ENV,
  sendDefaultPii: false, // keep IPs/headers/cookies out of events (default)
  beforeSend(event) {
    // Drop user email; keep only a non-PII id for impact counts
    if (event.user) delete event.user.email;

    // Redact M-Pesa numbers and tokens from the exception message
    if (event.exception?.values) {
      for (const ex of event.exception.values) {
        if (ex.value) ex.value = ex.value.replace(REDACT, "[redacted]");
      }
    }

    // Strip sensitive request data captured on the server
    if (event.request) {
      delete event.request.cookies;
      if (event.request.headers) {
        delete event.request.headers["authorization"];
        delete event.request.headers["cookie"];
      }
    }

    return event;
  },
});

Gotcha: Scrub on the server config (sentry.server.config.ts), not just the client — server events carry request bodies and headers where M-Pesa payloads and SENTRY_AUTH_TOKEN-style secrets leak. And never console.log raw callback payloads "for debugging"; if a log integration is enabled, those breadcrumbs ship to Sentry too.

Reference: https://docs.sentry.io/platforms/javascript/guides/nextjs/data-management/sensitive-data


Environment Variables

Bash
# DSN (public, safe in frontend)
NEXT_PUBLIC_SENTRY_DSN=https://...@sentry.io/...
SENTRY_DSN=https://...@sentry.io/...

# Auth token (server-side only — NEVER expose in frontend)
SENTRY_AUTH_TOKEN=sntrys_...

# Organization and project slugs
SENTRY_ORG=my-org
SENTRY_PROJECT=my-project

# Release tracking
NEXT_PUBLIC_APP_VERSION=1.2.3

Automation Workflows

Claude Code Slash Command: Debug Error

.claude/commands/sentry.md:

Markdown
Investigate the Sentry issue: $ARGUMENTS

1. Use the Sentry MCP tool `get_issue` to fetch the full issue with stack trace (issue ID or URL: $ARGUMENTS)
2. Use `get_issue_summary` to get Seer's root cause analysis
3. Use `get_events` to get the most recent 3 error events
4. Analyze the stack trace and identify the root cause
5. Look at the relevant source files using the Read tool
6. Propose a fix with a code diff
7. Estimate the blast radius (how many users are affected)

Usage: /project:sentry 1234567890 or /project:sentry https://my-org.sentry.io/issues/1234567890/

Hook: Auto-create Sentry Release on Deploy

.claude/settings.json:

JSON
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node scripts/sentry-release.js"
          }
        ]
      }
    ]
  }
}

scripts/sentry-release.js:

JavaScript
import { execFileSync } from "child_process";

const version = execFileSync("git", ["describe", "--tags", "--abbrev=0"])
  .toString()
  .trim();

if (!version) process.exit(0);

try {
  execFileSync("sentry-cli", ["releases", "new", version], { stdio: "inherit" });
  execFileSync("sentry-cli", ["releases", "set-commits", version, "--auto"], { stdio: "inherit" });
  console.log(`Sentry release created: ${version}`);
} catch (err) {
  console.error("Sentry release failed:", err.message);
}

GitHub Actions: Upload Source Maps

YAML
# .github/workflows/sentry-release.yml
name: Sentry Release
on:
  push:
    tags: ['v*']

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: npm ci && npm run build
      - name: Create Sentry release
        env:
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
          SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
        run: |
          npx @sentry/cli releases new ${{ github.ref_name }}
          npx @sentry/cli releases set-commits ${{ github.ref_name }} --auto
          npx @sentry/cli releases files ${{ github.ref_name }} \
            upload-sourcemaps .next --url-prefix "~/_next"
          npx @sentry/cli releases finalize ${{ github.ref_name }}
          npx @sentry/cli releases deploys ${{ github.ref_name }} new \
            --env production

Common Use Cases

Use CaseApproach
Debug production errorMCP get_issue + get_issue_summary
Triage new issuesMCP list_issues + analysis
Performance investigationMCP get_trace + get_spans
Source map uploadsentry-cli releases files upload-sourcemaps
Release trackingsentry-cli releases new + set-commits
User impact assessmentMCP get_issue (user count field)

Troubleshooting

IssueFix
OAuth auth failsClear browser cache and retry /mcp in Claude Code
Token 401Ensure token has org:read, project:read, issue:read scopes
Source maps not resolvingCheck --url-prefix matches the deployed JS bundle path
No issues visibleEnsure integration has access to the correct organization
Seer analysis emptyIssue may be too new; wait a few minutes for analysis to complete