Sentry MCP Server
A stateless FastMCP server for Sentry API integration, supporting multiple Sentry instances (US, EU, self-hosted) with a single deployment.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Customer VPC │
│ │
│ ┌──────────────┐ ┌─────────────────────────────┐ │
│ │ Satellite │ ──MCP──▶│ Sentry MCP Server │ │
│ └──────────────┘ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │sentryUS │ │sentryEU │ │ │
│ │ └────┬────┘ └────┬────┘ │ │
│ └───────┼───────────┼─────────┘ │
└───────────────────────────────────┼───────────┼─────────────┘
│ │
▼ ▼
sentry.io de.sentry.io
(US) (EU)
Features
- Multi-instance support: Configure multiple Sentry accounts (US, EU, self-hosted)
- Base tools + instance parameter: 11 tools that work across all instances
- Stateless HTTP: Scales horizontally, no session state
- Secure: Auth tokens stored in K8s secrets, never exposed to Claude
Tools
| Tool | Description |
|---|---|
list_sentry_instances | Discovery - list all configured Sentry accounts |
find_organizations | List organizations accessible with the token |
find_teams | List teams in an organization |
find_projects | List projects in an organization |
find_releases | List releases in an org/project |
get_issue_details | Get detailed info about a specific issue |
search_issues | Search for grouped issues in a project |
search_issue_events | Search events within a specific issue |
search_events | Search events and perform aggregations |
get_trace_details | Get trace overview and span breakdown |
get_event_attachment | Download attachments from an event |
Quick Start
1. Create Internal Integration in Sentry
For each Sentry organization you want to connect:
-
Go to Settings → Developer Settings → Internal Integrations
- US:
https://sentry.io/settings/{org}/developer-settings/ - EU:
https://de.sentry.io/settings/{org}/developer-settings/
- US:
-
Click Create New Internal Integration
-
Configure:
- Name:
Deeptrace MCP - Scopes (read-only):
org:readproject:readevent:readteam:readmember:read
- Name:
-
Click Save and copy the generated token (starts with
sntrys_...)
2. Create Kubernetes Secrets
# US Sentry
kubectl create secret generic sentry-us-creds \
--from-literal=auth_token="sntrys_eyJ..." \
-n deeptrace
# EU Sentry
kubectl create secret generic sentry-eu-creds \
--from-literal=auth_token="sntrys_eyJ..." \
-n deeptrace
3. Deploy with Helm
Create a values.yaml:
instances:
sentryUS:
enabled: true
region: "us"
orgSlug: "your-org-slug"
secretName: "sentry-us-creds"
labels:
dataResidency: "US"
description: "US customer data and services"
sentryEU:
enabled: true
region: "eu"
orgSlug: "your-org-slug-eu"
secretName: "sentry-eu-creds"
labels:
dataResidency: "EU"
description: "EU customer data (GDPR)"
Install:
helm install sentry-mcp ./helm/sentry-mcp \
-f values.yaml \
-n deeptrace
4. Configure Satellite
Add to your satellite's values.yaml:
mcpServers:
sentryMCP:
create: true
type: mcp
connection:
url: "http://sentry-mcp.deeptrace:8080/mcp"
transport: "streamable_http"
stateless: true
auditLogging: true
domainAllowlist:
- "sentry-mcp.deeptrace"
Configuration Reference
Instance Configuration
| Field | Required | Description |
|---|---|---|
enabled | No | Enable/disable instance (default: true) |
region | Yes | us, eu, or custom |
orgSlug | Yes | Sentry organization slug |
baseUrl | For custom | Full URL for self-hosted Sentry |
secretName | Yes | K8s secret name with auth_token key |
labels.dataResidency | No | Data residency label (e.g., "US", "EU") |
labels.description | No | Human-readable description |
labels.team | No | Team that owns this instance |
labels.environment | No | Environment (production, staging) |
Self-Hosted Example
instances:
sentrySelfHosted:
enabled: true
region: "custom"
baseUrl: "https://sentry.internal.company.com"
orgSlug: "internal"
secretName: "sentry-internal-creds"
labels:
dataResidency: "On-Premise"
description: "Self-hosted Sentry for internal services"
How It Works
Claude's Workflow
- Discovery: Claude calls
list_sentry_instances()to see available Sentry accounts - Query: Claude uses the instance name when calling other tools
- Multi-region: Claude queries both instances when context is ambiguous
Example conversation:
User: "Find unresolved errors in the Platform team's Sentry"
Claude: I'll check the available Sentry instances first.
→ list_sentry_instances()
→ Returns: [sentryUS (US), sentryEU (EU)]
Claude: The Platform team uses the EU instance based on the labels.
→ search_issues(instance="sentryEU", query="is:unresolved level:error")
→ "Found 5 unresolved errors in the EU Sentry..."
Why Internal Integration?
| Auth Type | Tied To | Multi-Org? | Best For |
|---|---|---|---|
| Personal Token | User | Yes (user's orgs) | Personal scripts |
| Internal Integration | Organization | No (single org) | Automated systems |
| Public Integration | OAuth | Yes (via OAuth) | Third-party SaaS |
Internal Integration is correct because:
- Not tied to a person - survives employee departures
- Organization-scoped - clear access boundaries
- No OAuth complexity - simple bearer token
- Fine-grained scopes - request only what you need
Development
Local Setup
# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -e ".[dev]"
# Create local config
mkdir -p /tmp/sentry-mcp
cat > /tmp/sentry-mcp/config.yaml << EOF
instances:
sentryUS:
enabled: true
region: us
orgSlug: your-org
EOF
# Create local secret
mkdir -p /tmp/secrets/sentryUS
echo "sntrys_your_token" > /tmp/secrets/sentryUS/auth_token
# Run server
SENTRY_MCP_CONFIG=/tmp/sentry-mcp/config.yaml \
SENTRY_MCP_SECRETS=/tmp/secrets \
python -m sentry_mcp
Building Docker Image
docker build -t deeptrace/sentry-mcp:latest .
Running Tests
pytest
Troubleshooting
"Unknown Sentry instance" Error
The instance name in your tool call doesn't match any configured instance.
- Check
list_sentry_instances()output - Verify the instance is enabled in config
- Ensure the K8s secret exists and has
auth_tokenkey
"No auth token configured" Error
The secret for the instance wasn't found or is empty.
- Verify secret exists:
kubectl get secret <secretName> -n deeptrace - Check secret has
auth_tokenkey:kubectl get secret <secretName> -o yaml - Ensure secret is mounted correctly in deployment
API Rate Limiting
Sentry has rate limits. If you hit them:
- Reduce
limitparameter in search queries - Add delays between bulk operations
- Consider caching frequently-accessed data
License
MIT