UNPKG

@raygun.io/mcp-server-raygun

Version:

MCP Server for Raygun's API V3 endpoints for interacting with your Crash Reporting and Real User Monitoring applications

200 lines (199 loc) 9.24 kB
import { ConfigSchema, } from "./types.js"; import * as fs from "node:fs/promises"; export class RaygunError extends Error { status; details; constructor(message, status, details) { super(message); this.status = status; this.details = details; this.name = "RaygunError"; } } export class RaygunAPIV3Client { config; constructor(config) { this.config = ConfigSchema.parse({ baseUrl: "https://api.raygun.com/v3", ...config, }); } async request(method, path, body, queryParams) { const url = new URL(this.config.baseUrl + path); if (queryParams) { Object.entries(queryParams).forEach(([key, value]) => { if (value != null && value !== '') { url.searchParams.append(key, String(value)); } }); } const response = await fetch(url.toString(), { method, headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.config.apiKey}`, }, body: body ? JSON.stringify(body) : undefined, }); if (!response.ok) { throw new RaygunError(`Raygun API error: ${url.toString()}: ${response.status}`, response.status, await response.json().catch(() => undefined)); } if (response.status === 204) { return undefined; } return response.json(); } // Applications async listApplications(options) { return this.request("GET", "/applications", undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(",") || "", }); } async getApplication(applicationIdentifier) { return this.request('GET', `/applications/${applicationIdentifier}`); } async getApplicationByApiKey(apiKey) { return this.request('GET', `/applications/api-key/${apiKey}`); } async regenerateApplicationApiKey(applicationIdentifier) { return this.request('POST', `/applications/${applicationIdentifier}/regenerate-api-key`); } async listCustomers(applicationIdentifier, options) { return this.request('GET', `/applications/${applicationIdentifier}/customers`, undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(',') || '', }); } async listDeployments(applicationIdentifier, options) { return this.request('GET', `/applications/${applicationIdentifier}/deployments`, undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(',') || '', }); } async getDeployment(applicationIdentifier, deploymentIdentifier) { return this.request('GET', `/applications/${applicationIdentifier}/deployments/${deploymentIdentifier}`); } async deleteDeployment(applicationIdentifier, deploymentIdentifier) { return this.request('DELETE', `/applications/${applicationIdentifier}/deployments/${deploymentIdentifier}`); } async updateDeployment(applicationIdentifier, deploymentIdentifier, updateData) { return this.request('PATCH', `/applications/${applicationIdentifier}/deployments/${deploymentIdentifier}`, updateData); } async reprocessDeploymentCommits(applicationIdentifier, deploymentIdentifier) { return this.request('POST', `/applications/${applicationIdentifier}/deployments/${deploymentIdentifier}/reprocess-commits`); } async listErrorGroups(applicationIdentifier, options) { return this.request('GET', `/applications/${applicationIdentifier}/error-groups`, undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(',') || '', }); } async getErrorGroup(applicationIdentifier, errorGroupIdentifier) { return this.request('GET', `/applications/${applicationIdentifier}/error-groups/${errorGroupIdentifier}`); } async resolveErrorGroup(applicationIdentifier, errorGroupIdentifier, data) { return this.request('POST', `/applications/${applicationIdentifier}/error-groups/${errorGroupIdentifier}/resolve`, data); } async activateErrorGroup(applicationIdentifier, errorGroupIdentifier) { return this.request('POST', `/applications/${applicationIdentifier}/error-groups/${errorGroupIdentifier}/activate`); } async ignoreErrorGroup(applicationIdentifier, errorGroupIdentifier) { return this.request('POST', `/applications/${applicationIdentifier}/error-groups/${errorGroupIdentifier}/ignore`); } async permanentlyIgnoreErrorGroup(applicationIdentifier, errorGroupIdentifier, data) { return this.request('POST', `/applications/${applicationIdentifier}/error-groups/${errorGroupIdentifier}/permanently-ignore`, data); } async listInvitations(options) { return this.request('GET', '/invitations', undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(',') || '' }); } async sendInvitation(data) { return this.request('POST', '/invitations', data); } async getInvitation(invitationIdentifier) { return this.request('GET', `/invitations/${invitationIdentifier}`); } async revokeInvitation(invitationIdentifier) { return this.request('POST', `/invitations/${invitationIdentifier}/revoke`); } async listPages(applicationIdentifier, options) { return this.request('GET', `/applications/${applicationIdentifier}/pages`, undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(',') || '', }); } async getPageMetricsTimeSeries(applicationIdentifier, params) { return this.request('POST', `/metrics/${applicationIdentifier}/pages/time-series`, params); } async getPageMetricsHistogram(applicationIdentifier, params) { return this.request('POST', `/metrics/${applicationIdentifier}/pages/histogram`, params); } async getErrorMetricsTimeSeries(applicationIdentifier, params) { return this.request('POST', `/metrics/${applicationIdentifier}/errors/time-series`, params); } async listSessions(applicationIdentifier, options) { return this.request('GET', `/applications/${applicationIdentifier}/sessions`, undefined, { count: options?.count || 100, offset: options?.offset || 0, filter: options?.filter || '', orderby: options?.orderBy?.join(',') || '', }); } async getSession(applicationIdentifier, sessionIdentifier, options) { const params = {}; if (options?.include) { params.include = options.include.join(','); } return this.request('GET', `/applications/${applicationIdentifier}/sessions/${sessionIdentifier}`, undefined, params); } async listSourceMaps(applicationIdentifier, options) { return this.request('GET', `/applications/${applicationIdentifier}/source-maps`, undefined, { count: options?.count || 100, offset: options?.offset || 0, orderby: options?.orderBy?.join(',') || '' }); } async getSourceMap(applicationIdentifier, sourceMapIdentifier) { return this.request('GET', `/applications/${applicationIdentifier}/source-maps/${sourceMapIdentifier}`); } async updateSourceMap(applicationIdentifier, sourceMapIdentifier, data) { return this.request('PATCH', `/applications/${applicationIdentifier}/source-maps/${sourceMapIdentifier}`, data); } async deleteSourceMap(applicationIdentifier, sourceMapIdentifier) { return this.request('DELETE', `/applications/${applicationIdentifier}/source-maps/${sourceMapIdentifier}`); } async uploadSourceMap(applicationIdentifier, filePath, uri) { const formData = new FormData(); const fileStream = await fs.readFile(filePath); const file = new Blob([fileStream], { type: 'application/json' }); const fileName = filePath.split('/').pop() || 'sourcemap.js.map'; formData.append('file', file, fileName); formData.append('uri', uri); const url = new URL(this.config.baseUrl + `/applications/${applicationIdentifier}/source-maps`); const response = await fetch(url.toString(), { method: 'PUT', headers: { Authorization: `Bearer ${this.config.apiKey}`, }, body: formData, }); if (!response.ok) { throw new RaygunError(`Raygun API error: ${url.toString()}: ${response.status}`, response.status, await response.json().catch(() => undefined)); } return response.json(); } async deleteAllSourceMaps(applicationIdentifier) { return this.request('DELETE', `/applications/${applicationIdentifier}/source-maps`); } }