Sentry Integration Guide

Technology: sentry · Category: monitoring · Last reviewed: 2026-08-23

Source: https://tech-stack.codeamanilabs.org/guide/sentry

Insight:

Sentry is the error/issue layer — wire it in early so production failures (especially M-Pesa callback edge cases) surface with stack traces instead of silent drops. Verify Sentry webhooks with Svix, and scrub PII/secrets from event payloads before they leave your servers.

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

Sentry 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 access to your issues, traces, spans, logs, and Seer (AI root-cause analysis) — and, as of the current server, it can also take triage actions (resolve/assign issues, create projects/DSNs, add notes). That enables 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:

flowchart LR
    A["App throws error<br/>e.g. M-Pesa callback"] --> B["Sentry SDK<br/>captures exception"]
    B --> C["Sentry platform<br/>issue + stack trace"]
    C --> D["Seer AI<br/>root-cause analysis"]
    C --> E["MCP server<br/>read + triage actions"]
    D --> E
    E --> F["Claude Code<br/>triage + propose fix"]

Official Documentation

Resource URL
Sentry Docs https://docs.sentry.io
Sentry MCP Server https://mcp.sentry.dev/
sentry-cli Reference https://docs.sentry.io/cli/
Performance Tutorial https://sentry.io/cookbook/performance-bot-sentry-claude/
Source Maps https://docs.sentry.io/platforms/javascript/sourcemaps/

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.

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

# Optionally scope the connection to one org/project so tools default to it
claude mcp add --transport http sentry \
  https://mcp.sentry.dev/mcp/{organizationSlug}/{projectSlug}

Then run /mcp inside Claude Code to authenticate with your Sentry organization via OAuth. Every connection uses OAuth; the first request triggers the browser auth flow.

.mcp.json Configuration (Token-based)

{
  "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

The MCP server now exposes ~50 tools. The old flat list_*/get_* names have been renamed and expanded; the ones you reach for most from a coding session:

Tool Description
find_projects / find_organizations / find_teams Discover org, project, and team slugs
search_issues Natural-language / query search across issues
get_issue_details Full issue detail incl. stack trace, culprit, counts
get_event_stacktrace / get_issue_breadcrumbs Deep-dive a single event
search_events Query events, errors, spans, and logs (replaces the old get_events/get_performance)
get_trace_details / get_span_details Distributed trace + span investigation (replaces get_trace/get_spans)
analyze_issue_with_seer Trigger Seer AI root-cause + fix analysis (replaces get_issue_summary)
search_docs / get_doc Search and read Sentry's own docs
whoami Confirm the authenticated account

Not read-only anymore. The MCP server now includes write/mutation tools — update_issue (resolve/assign/set status), add_issue_note, create_project, update_project, create_dsn/update_dsn, create_team, create_uptime_monitor, and analyze_issue_with_seer. Treat it as a full control surface, not just a viewer. There are also discovery meta-tools (search_sentry_tools, execute_sentry_tool) for the larger catalog. Guard the OAuth grant / token scopes accordingly (see Troubleshooting).

Claude Code Plugin Integration

Sentry also ships an official Claude Code plugin (skills such as sentry-debug-issue, sentry-instrument, sentry-setup-releases, sentry-fix-stack-traces, sentry-create-alert) that wraps these MCP tools into guided workflows:

# With the sentry plugin + MCP connected, just ask in natural language:
#   "Check Sentry for recent auth errors and propose a fix"
# Claude delegates to the Sentry MCP tools (search_issues → get_issue_details →
# analyze_issue_with_seer) automatically.

CLI Integration (sentry-cli)

Installation

# 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

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:

flowchart TD
    A["releases new<br/>v1.2.3"] --> B["set-commits<br/>--auto"]
    B --> C["files upload-sourcemaps<br/>./dist"]
    C --> D["releases finalize<br/>v1.2.3"]
    D --> E["releases deploys<br/>--env production"]
    E --> F["Errors resolve to<br/>original source lines"]
# 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

npm install @sentry/nextjs  # currently v10.x — or @sentry/node, @sentry/react, etc.

Next.js setup (v9/v10): init lives in four files — instrumentation.ts (server/edge + onRequestError), instrumentation-client.ts (browser + onRouterTransitionStart), sentry.server.config.ts, and sentry.edge.config.ts — plus withSentryConfig wrapping next.config.ts. The standalone sentry.client.config.ts is gone; client init moved to instrumentation-client.ts. See PATTERNS.md for the full recipe. The server config below is what instrumentation.ts imports for the Node.js runtime.

sentry.server.config.ts:

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

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.

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.

flowchart LR
    A["Error captured<br/>user · request · exception"] --> B["sendDefaultPii false<br/>drops IP · headers · cookies"]
    B --> C["beforeSend hook<br/>redact phones · tokens"]
    C --> D{"return event<br/>or null"}
    D -->|event| E["Server-side scrub<br/>best-effort on ingest"]
    D -->|null| F["Event dropped"]
    E --> G["Stored in Sentry"]

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


Environment Variables

# 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:

Investigate the Sentry issue: $ARGUMENTS

1. Use the Sentry MCP tool `get_issue_details` to fetch the full issue with stack trace (issue ID or URL: $ARGUMENTS)
2. Use `analyze_issue_with_seer` to get Seer's root cause analysis
3. Use `search_events` (or `get_event_stacktrace`) to pull the most recent 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), then optionally `update_issue` to assign/resolve it

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

Hook: Auto-create Sentry Release on Deploy

.claude/settings.json:

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

scripts/sentry-release.js:

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

# .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 Case Approach
Debug production error MCP get_issue_details + analyze_issue_with_seer
Triage new issues MCP search_issues + analysis, then update_issue to resolve/assign
Performance investigation MCP get_trace_details + get_span_details (or search_events)
Source map upload sentry-cli releases files upload-sourcemaps
Release tracking sentry-cli releases new + set-commits
User impact assessment MCP get_issue_details (user count field)

Troubleshooting

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

Official docs: