Skip to main content
Glama

MCP Server Sentry

sentry-client.ts4.87 kB
import axios, { AxiosError } from "axios"; // Response type for Sentry API export interface SentryIssue { id: string; title: string; status: string; level: string; firstSeen: string; lastSeen: string; count: number; stacktrace?: string; } export class SentryClient { private readonly baseUrl = process.env.SENTRY_BASE_URL || "https://sentry.com/api/0"; private readonly authToken: string; private readonly organizationSlug?: string; private readonly projectSlug?: string; constructor(authToken: string, organizationSlug?: string, projectSlug?: string) { this.authToken = authToken; this.organizationSlug = organizationSlug; this.projectSlug = projectSlug; } /** * Parse Sentry issue ID or URL */ private parseIssueIdOrUrl(issueIdOrUrl: string): { issueId: string; organizationSlug?: string; projectSlug?: string } { // Check if it's a URL if (issueIdOrUrl.startsWith("http")) { try { const url = new URL(issueIdOrUrl); const pathParts = url.pathname.split("/").filter(part => part.length > 0); // Try to extract organization, project, and issue ID from URL path if (pathParts.length >= 4 && pathParts[0] === "organizations") { return { organizationSlug: pathParts[1], projectSlug: pathParts[3], issueId: pathParts[pathParts.length - 1] }; } // Some older Sentry URLs may have different formats if (pathParts.length >= 3) { return { organizationSlug: pathParts[0], projectSlug: pathParts[1], issueId: pathParts[2] }; } } catch (error) { // URL parsing failed, fallback to using original input as issue ID } } // If not a URL or unable to parse URL, use input directly as issue ID return { issueId: issueIdOrUrl, organizationSlug: this.organizationSlug, projectSlug: this.projectSlug }; } /** * Get Sentry issue details */ async getIssue(issueIdOrUrl: string): Promise<SentryIssue> { const { issueId, organizationSlug, projectSlug } = this.parseIssueIdOrUrl(issueIdOrUrl); if (!organizationSlug || !projectSlug) { throw new Error( "Organization slug and project slug are required. Provide them either in the constructor " + "or as part of the issue URL." ); } try { // Get basic issue information const issueResponse = await axios.get( `${this.baseUrl}/organizations/${organizationSlug}/issues/${issueId}/`, { headers: { Authorization: `Bearer ${this.authToken}`, "Content-Type": "application/json" } } ); // Get the latest event to extract stack trace information const eventsResponse = await axios.get( `${this.baseUrl}/organizations/${organizationSlug}/issues/${issueId}/events/latest/`, { headers: { Authorization: `Bearer ${this.authToken}`, "Content-Type": "application/json" } } ); // Extract stack trace let stacktrace: string | undefined; if (eventsResponse.data.entries) { const exceptionEntry = eventsResponse.data.entries.find( (entry: any) => entry.type === "exception" ); if (exceptionEntry && exceptionEntry.data && exceptionEntry.data.values) { const exceptions = exceptionEntry.data.values; stacktrace = exceptions .map((exception: any) => { let frames = ""; if (exception.stacktrace && exception.stacktrace.frames) { frames = exception.stacktrace.frames .map((frame: any) => { return ` at ${frame.function || "unknown"} (${frame.filename || "unknown"}:${frame.lineno || "?"}:${frame.colno || "?"})`; }) .reverse() .join("\n"); } return `${exception.type}: ${exception.value}\n${frames}`; }) .join("\n\nCaused by: "); } } // Build and return issue details return { id: issueResponse.data.id, title: issueResponse.data.title, status: issueResponse.data.status, level: issueResponse.data.level || "error", firstSeen: issueResponse.data.firstSeen, lastSeen: issueResponse.data.lastSeen, count: issueResponse.data.count, stacktrace }; } catch (error: unknown) { if (axios.isAxiosError(error) && error.response) { throw new Error(`Sentry API error: ${error.response.status} - ${error.response.data.detail || JSON.stringify(error.response.data)}`); } throw error; } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Zzzccs123/mcp-sentry'

If you have feedback or need assistance with the MCP directory API, please join our Discord server