← Back to dashboard
sentrymonitoringfreshReader view (for NotebookLM)

Sentry Integration Guide

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

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:

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

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

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

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:

ToolDescription
find_projects / find_organizations / find_teamsDiscover org, project, and team slugs
search_issuesNatural-language / query search across issues
get_issue_detailsFull issue detail incl. stack trace, culprit, counts
get_event_stacktrace / get_issue_breadcrumbsDeep-dive a single event
search_eventsQuery events, errors, spans, and logs (replaces the old get_events/get_performance)
get_trace_details / get_span_detailsDistributed trace + span investigation (replaces get_trace/get_spans)
analyze_issue_with_seerTrigger Seer AI root-cause + fix analysis (replaces get_issue_summary)
search_docs / get_docSearch and read Sentry's own docs
whoamiConfirm 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:

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

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

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

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_details + analyze_issue_with_seer
Triage new issuesMCP search_issues + analysis, then update_issue to resolve/assign
Performance investigationMCP get_trace_details + get_span_details (or search_events)
Source map uploadsentry-cli releases files upload-sourcemaps
Release trackingsentry-cli releases new + set-commits
User impact assessmentMCP get_issue_details (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