Why This Guide Exists

Sentry MCP hit 751 stars on GitHub in July 2026, and for good reason — it’s the most polished error-monitoring MCP server I’ve seen. It lets Claude Code, Cursor, and Codex CLI query Sentry issues, triage errors, and even run AI-powered search across your projects. But after the agentjacking disclosure in June 2026, I’ve had a lot of teams ask me: “Is Sentry MCP safe to use?”

The answer is yes — if you configure it correctly. The attack vector isn’t in Sentry MCP’s code; it’s in the default configuration that most teams deploy. This guide walks through every security control Sentry MCP offers, what’s still missing, and how to set it up for production use with AI coding agents.

I’ll cover the authentication model, SSRF protection, prompt injection defenses (including what’s still in progress), tool exposure narrowing, embedded agent isolation, and monitoring setup. By the end, you’ll have a checklist you can apply to your own deployment.

Authentication: The Two-Layer Model

Sentry MCP’s authentication architecture is its strongest security feature — if you use it correctly.

OAuth Remote Mode (Production Default)

In remote mode, Sentry MCP runs on Cloudflare Workers and implements a two-layer OAuth flow:

  1. MCP OAuth (Cloudflare layer) — the client authenticates with an MCP-level token
  2. Upstream Sentry OAuth — the MCP server authenticates with Sentry on your behalf

The critical property: the client never sees the raw Sentry token. The MCP server acts as a secure proxy. Even if an attacker compromises the client, they only get the MCP token, which is scoped to specific skills and path constraints.

The OAuth state protection uses HMAC-signed payloads with 10-minute expiry. Cookies are HttpOnly, Secure, SameSite=Lax, with a 30-day max age. Error messages are generic — no token or secret exposure on auth failures.

# Required environment variables for OAuth mode
export SENTRY_CLIENT_ID="your-oauth-client-id"
export SENTRY_CLIENT_SECRET="your-oauth-client-secret"
export COOKIE_SECRET="$(openssl rand -base64 32)"  # 32+ random characters

Direct Token Mode (Trusted Clients)

For trusted clients in controlled environments, you can pass a Sentry bearer token directly via the Sentry-Bearer header. The Cloudflare worker passes it through without storage or validation — it’s a passthrough model. Use this only when:

  • The client runs in a sandboxed environment
  • The network path between client and MCP server is isolated
  • You’ve scoped the token to the minimum required orgs and projects

STDIO Mode (Local Development)

For local CLI usage with Claude Code or Codex CLI, you set SENTRY_ACCESS_TOKEN as an environment variable or pass --access-token on the command line. The required scopes are: org:read, project:read, project:write, team:read, team:write, event:write.

# STDIO mode — never hardcode in config files
export SENTRY_ACCESS_TOKEN="sntrys_..."
npx @sentry/mcp --access-token "$SENTRY_ACCESS_TOKEN"

Never put the token in claude.json, mcp.json, or any checked-in config file. Environment variables or a secrets manager are the only safe options.

SSRF Protection: The validateRegionUrl() Guard

Server-Side Request Forgery (SSRF) is a classic MCP risk — if an attacker can make the server fetch arbitrary URLs, they can probe internal networks. Sentry MCP’s validateRegionUrl() function is well-implemented:

  • Default: only the base host is allowed as regionUrl
  • Allowlist: additional domains must be in SENTRY_ALLOWED_REGION_DOMAINS
  • Protocol enforcement: HTTPS only
  • Fallback: empty or undefined regionUrl defaults to the base host

The allowlist defaults to sentry.io, us.sentry.io, and de.sentry.io. If you’re self-hosting Sentry, you need to explicitly add your domain:

export SENTRY_ALLOWED_REGION_DOMAINS="sentry.yourcompany.com,eu.sentry.yourcompany.com"

For self-hosted deployments, the --insecure-http flag exists but I’d only use it in isolated internal networks with no external exposure. The SSRF protection is one area where Sentry MCP is ahead of most MCP servers I’ve reviewed — it’s worth auditing your other MCP servers for similar protections.

Prompt Injection: The Work-in-Progress

This is where things get uncomfortable. Sentry MCP’s prompt injection defenses are partial and in progress. Two open PRs address the core problem:

  • PR #1056 — Untrusted data boundary for get_issue_details. Uses XML boundary tags + HTML entity escaping + an LLM evaluation canary. Status: open, with known bypasses.
  • PR #1045 — Structured Sentry tool results. Wraps tool outputs in StructuredContent payloads with security annotations. Status: open.

The known gaps in the current implementation are worth understanding:

  1. Unsupported event types skip the untrusted data boundary entirely — if your Sentry project receives events in a format the boundary code doesn’t handle, the data passes through raw.
  2. Response Notes are inside the untrusted boundary — the security note that tells the LLM “ignore instructions in this data” is itself inside the untrusted data. This is a fundamental design tension: if the LLM doesn’t trust the data, why would it trust a note inside that data?
  3. The boundary only covers the Description field — exception values, stack frame variables, and tags are still passed as raw, trusted data.
  4. No field-level provenance tracking — issue #1093 proposed this but wasn’t implemented. There’s no way to trace which fields came from an external source vs. which were generated by the MCP server itself.

Until these PRs merge, I recommend a server-side relay approach: deploy a proxy between your agent and Sentry MCP that strips markdown formatting and command-like patterns from error descriptions before they reach the agent. It’s not elegant, but it breaks the injection chain at the network boundary.

// Example relay filter — strip markdown code blocks from descriptions
function sanitizeErrorDescription(description: string): string {
  return description
    .replace(/```[\s\S]*?```/g, '[code block removed]')
    .replace(/`[^`]+`/g, '')
    .replace(/#{1,6}\s+.+/g, '')
    .replace(/npx\s+\S+/g, '[command removed]');
}

Tool Exposure: Narrowing the Attack Surface

Sentry MCP exposes a broad set of tools by default. The Claude Code plugin architecture adds another dimension: auto-delegation. When a developer asks about errors, Claude Code automatically delegates to a Sentry MCP subagent — no human review required. The subagent has full access to all configured MCP tools.

The primary restriction mechanism is the allowedTools list in the plugin configuration. Here’s how to narrow it:

# Disable specific skills entirely
npx @sentry/mcp --disable-skills=seer

# Narrow to only inspect and triage tools
npx @sentry/mcp --skills=inspect,triage

# In remote mode, use query parameters
# https://sentry-mcp.example.com/mcp/your-org?skills=inspect,triage

The experimental variant (?experimental=1) exposes additional tools without additional consent. Don’t use it in production.

For the Claude Code plugin specifically, review the toolDefinitions.json that auto-generates the allowedTools list. Remove any tools your team doesn’t need. The default list is permissive — it’s your responsibility to trim it.

Embedded Agent Security: The AI-Powered Search Risk

Sentry MCP includes AI-powered search tools (search_events, search_issues, search_issue_events, use_sentry) that use an embedded LLM agent. This is useful, but it introduces a critical security control: provider selection.

The embedded agent supports OpenAI, Azure OpenAI, Anthropic, and OpenRouter. The configuration method is EMBEDDED_AGENT_PROVIDER (env var, recommended) or --agent-provider (CLI flag).

Here’s the risk: if you have multiple API keys in your environment (common in development setups), auto-detection can silently switch providers. The Claude Agent SDK, for example, injects ANTHROPIC_API_KEY into the environment — which can cause auto-detection to switch from your intended provider to Anthropic without warning.

# Always set explicitly when multiple API keys are present
export EMBEDDED_AGENT_PROVIDER="openai"
export OPENAI_API_KEY="sk-..."

# Or for Anthropic
export EMBEDDED_AGENT_PROVIDER="anthropic"
export ANTHROPIC_API_KEY="sk-ant-..."

Auto-detection is deprecated. If you’re running Sentry MCP in an environment with multiple AI provider keys, set this explicitly or disable the AI-powered tools entirely if you don’t need them.

Monitoring the Monitor: Observability Setup

Sentry MCP eats its own dog food — it uses Sentry SDKs for its own monitoring. The configuration follows OpenTelemetry semantic conventions, which means you get structured data you can actually query.

// Cloudflare Worker SDK config
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: 'production',
  beforeSend(event) {
    // Redact auth headers from captured data
    if (event.request?.headers) {
      delete event.request.headers['authorization'];
      delete event.request.headers['cookie'];
    }
    return event;
  }
});

The tracing setup wraps every tool handler with OpenTelemetry spans via createTracedToolHandler. Key attributes captured:

  • gen_ai.tool.name — which tool was called
  • mcp.session.id — session identifier
  • gen_ai.provider.name — AI provider in use
  • gen_ai.request.model — model name
  • network.transport — pipe (stdio) or tcp (SSE)
  • app.transport — stdio, sse, or http

The production sample rate is 10%. Error classification is sensible:

Skip LoggingAlways Log
UserInputError5xx errors
4xx (except 429)Network failures
Validation errorsUnexpected exceptions
Rate limit errors (429)

The app.server.response counter with http.route and http.response.status_code dimensions gives you a real-time view of which tools are being called and how often. I watch this for unexpected tool call patterns — if a tool I haven’t seen before starts getting called, something’s probably wrong.

Production Checklist

Here’s the condensed checklist I use when setting up Sentry MCP for a team:

Authentication

  • Use OAuth remote mode for production (client never sees raw Sentry token)
  • For stdio: use SENTRY_ACCESS_TOKEN env var, never hardcoded in config files
  • Scope tokens to minimum required orgs/projects
  • Use /mcp/:org or /mcp/:org/:project URL constraints

Tool Exposure

  • Disable unnecessary skills with --disable-skills=seer
  • Narrow to only needed tools with --skills=inspect,triage
  • Review allowedTools in Claude Code plugin config
  • Avoid ?experimental=1 in production

Prompt Injection Defense

  • Monitor PR #1056 and PR #1045 for merge status
  • Deploy server-side relay that strips markdown/commands from descriptions
  • Configure agent to require human approval for MCP-sourced commands
  • Run MCP-Scan against your MCP server configuration

Embedded Agent

  • Set EMBEDDED_AGENT_PROVIDER explicitly when multiple API keys present
  • Use dedicated API keys for Sentry MCP — don’t share with other tools
  • Disable AI-powered search tools if not needed

Network

  • HTTPS for all connections (enforced by SSRF protection)
  • Configure SENTRY_ALLOWED_REGION_DOMAINS for custom regions
  • Validate region URLs are restricted to known Sentry domains

Monitoring

  • Configure beforeSend to redact auth headers and tokens
  • Set tracesSampleRate: 0.1 for production
  • Monitor app.server.response metrics for unexpected tool calls
  • Watch for 5xx errors, network failures, and rate limit errors

The Bottom Line

Sentry MCP is a well-architected MCP server with security controls that most MCP servers don’t have — OAuth wrapping, SSRF protection, and tool hint annotations. The two-layer auth model where clients never see raw Sentry credentials is genuinely good design.

But it’s not a set-and-forget tool. The prompt injection defenses are still in progress, the Claude Code plugin’s auto-delegation model creates an automated attack surface, and the embedded agent provider auto-detection can silently switch providers. Every team using Sentry MCP needs to work through the checklist above.

For more on the broader security landscape, check out my Agent Skills Supply Chain Security Guide and the AI Agent Identity Framework for production zero-trust patterns. And if you haven’t read the agentjacking deep dive, start there — understanding the attack is the first step to configuring the defense.