Skip to content

Instantly share code, notes, and snippets.

@wspruijt
Created March 12, 2025 11:14
Show Gist options
  • Select an option

  • Save wspruijt/f8ee8a8f4fd2ba7dc040880de5f9a3be to your computer and use it in GitHub Desktop.

Select an option

Save wspruijt/f8ee8a8f4fd2ba7dc040880de5f9a3be to your computer and use it in GitHub Desktop.
Vibecoded Sentry MCP server
import os
from typing import Dict
from fastmcp import FastMCP
from dotenv import load_dotenv
import requests
load_dotenv()
# Initialize environment variables
SENTRY_AUTH_TOKEN = os.getenv("SENTRY_AUTH_TOKEN")
SENTRY_ORG = os.getenv("SENTRY_ORG")
SENTRY_PROJECT = os.getenv("SENTRY_PROJECT")
if not all([SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT]):
raise ValueError("Missing required Sentry configuration in .env")
# Create MCP server
mcp = FastMCP(host="127.0.0.1", port=7777)
# Configure Sentry API
SENTRY_API_BASE = f"https://sentry.io/api/0/organizations/{SENTRY_ORG}"
HEADERS = {
"Authorization": f"Bearer {SENTRY_AUTH_TOKEN}",
"Content-Type": "application/json"
}
@mcp.tool()
async def get_issue_details(sentry_ref: str) -> Dict:
"""
Get issue details from Sentry using the issue reference.
Args:
sentry_ref: The Sentry issue reference/ID
Returns:
Dict containing issue description, file path, and stack trace
"""
# Remove any 'getsentry/' prefix if present
sentry_ref = sentry_ref.replace("getsentry/", "")
try:
# Get issue details from Sentry API
url = f"{SENTRY_API_BASE}/issues/{sentry_ref}/"
response = requests.get(url, headers=HEADERS)
response.raise_for_status()
issue_data = response.json()
# Get the latest event for this issue to get stack trace
events_url = f"{SENTRY_API_BASE}/issues/{sentry_ref}/events/latest/"
event_response = requests.get(events_url, headers=HEADERS)
event_response.raise_for_status()
event_data = event_response.json()
# Extract stack trace information
stack_trace = None
file_path = None
if event_data.get("entries"):
for entry in event_data["entries"]:
if entry.get("type") == "exception":
values = entry.get("data", {}).get("values", [])
if values:
frames = values[0].get("stacktrace", {}).get("frames", [])
if frames:
# Get the most relevant frame (usually the last one)
frame = frames[-1]
file_path = f"{frame.get('filename')}:{frame.get('lineno')}"
stack_trace = "\n".join([
f"{f.get('filename')}:{f.get('lineno')} in {f.get('function')}"
for f in frames
])
return {
"description": issue_data.get("title", "No description available"),
"file_path": file_path or "File path not available",
"stack_trace": stack_trace or "Stack trace not available"
}
except Exception as e:
return {"error": f"Failed to get issue details: {str(e)}"}
if __name__ == "__main__":
mcp.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment