@rui.branco/sentry-mcp 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +24 -97
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -156,7 +156,26 @@ async function fetchSentry(apiPath, instance, options = {}) {
156
156
 
157
157
  // ── Helpers ─────────────────────────────────────────────────────────────────
158
158
 
159
- function formatIssue(issue) {
159
+ // Strip noisy/internal fields that waste context but keep everything useful
160
+ function cleanIssueData(issue) {
161
+ const skip = new Set(["pluginActions", "pluginContexts", "pluginIssues", "activity", "seenBy", "stats"]);
162
+ const cleaned = {};
163
+ for (const [k, v] of Object.entries(issue)) {
164
+ if (!skip.has(k) && v != null && v !== "") cleaned[k] = v;
165
+ }
166
+ return cleaned;
167
+ }
168
+
169
+ function cleanEventData(event) {
170
+ const skip = new Set(["_meta", "groupID", "eventID", "sdk", "dist", "fingerprints"]);
171
+ const cleaned = {};
172
+ for (const [k, v] of Object.entries(event)) {
173
+ if (!skip.has(k) && v != null && v !== "") cleaned[k] = v;
174
+ }
175
+ return cleaned;
176
+ }
177
+
178
+ function formatIssueSummary(issue) {
160
179
  const meta = issue.metadata || {};
161
180
  const lines = [];
162
181
  lines.push(`**${issue.title}**`);
@@ -175,98 +194,6 @@ function formatIssue(issue) {
175
194
  return lines.join("\n");
176
195
  }
177
196
 
178
- function formatEvent(event) {
179
- const lines = [];
180
-
181
- // Stack traces
182
- const exceptions =
183
- event.entries?.find((e) => e.type === "exception")?.data?.values || [];
184
- if (exceptions.length) {
185
- lines.push("## Stack Trace\n");
186
- for (const ex of exceptions) {
187
- if (ex.type || ex.value) lines.push(`**${ex.type || "Exception"}:** ${ex.value || ""}\n`);
188
- const frames = ex.stacktrace?.frames;
189
- if (frames?.length) {
190
- lines.push("```");
191
- for (const f of frames) {
192
- const loc = f.lineNo ? `:${f.lineNo}${f.colNo ? ":" + f.colNo : ""}` : "";
193
- const marker = f.inApp ? "-> " : " ";
194
- lines.push(`${marker}${f.function || "?"} (${f.filename || "?"}${loc})`);
195
- }
196
- lines.push("```\n");
197
- }
198
- }
199
- }
200
-
201
- // Breadcrumbs
202
- const breadcrumbs =
203
- event.entries?.find((e) => e.type === "breadcrumbs")?.data?.values || [];
204
- if (breadcrumbs.length) {
205
- const last = breadcrumbs.slice(-20);
206
- lines.push(`## Breadcrumbs (last ${last.length})\n`);
207
- for (const bc of last) {
208
- const msg = bc.message || bc.data?.url || bc.data?.to || "";
209
- lines.push(`- **${bc.category || "?"}** [${bc.level || "info"}] ${msg}`);
210
- }
211
- lines.push("");
212
- }
213
-
214
- // HTTP Request
215
- const httpReq =
216
- event.entries?.find((e) => e.type === "request")?.data;
217
- if (httpReq) {
218
- lines.push("## HTTP Request\n");
219
- lines.push(`\`${httpReq.method || "GET"} ${httpReq.url || ""}\``);
220
- if (httpReq.headers) {
221
- lines.push("\n```");
222
- for (const [k, v] of httpReq.headers) {
223
- lines.push(`${k}: ${v}`);
224
- }
225
- lines.push("```");
226
- }
227
- lines.push("");
228
- }
229
-
230
- // Tags
231
- if (event.tags?.length) {
232
- lines.push("## Tags\n");
233
- lines.push("| Key | Value |");
234
- lines.push("|-----|-------|");
235
- for (const t of event.tags) {
236
- lines.push(`| ${t.key} | ${t.value} |`);
237
- }
238
- lines.push("");
239
- }
240
-
241
- // Contexts
242
- if (event.contexts) {
243
- lines.push("## Contexts\n");
244
- for (const [name, ctx] of Object.entries(event.contexts)) {
245
- if (name === "trace" || name === "replay" || !ctx || typeof ctx !== "object") continue;
246
- const entries = Object.entries(ctx).filter(([k, v]) => k !== "type" && v != null && v !== "");
247
- if (!entries.length) continue;
248
- const title = name.charAt(0).toUpperCase() + name.slice(1).replace(/_/g, " ");
249
- lines.push(`**${title}:**`);
250
- for (const [k, v] of entries.slice(0, 15)) {
251
- const display = typeof v === "object" ? JSON.stringify(v) : String(v);
252
- lines.push(`- ${k}: ${display}`);
253
- }
254
- lines.push("");
255
- }
256
- }
257
-
258
- // User
259
- if (event.user) {
260
- const u = event.user;
261
- lines.push("## User\n");
262
- lines.push(`${u.username || u.name || u.email || u.id || "unknown"}${u.email ? " (" + u.email + ")" : ""}`);
263
- if (u.ip_address) lines.push(`IP: ${u.ip_address}`);
264
- lines.push("");
265
- }
266
-
267
- return lines.join("\n") || "No event data available.";
268
- }
269
-
270
197
  // ── MCP Server ──────────────────────────────────────────────────────────────
271
198
 
272
199
  const server = new Server(
@@ -573,7 +500,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
573
500
  content: [{ type: "text", text: `No issues found for query: ${query}` }],
574
501
  };
575
502
  }
576
- const formatted = data.map(formatIssue);
503
+ const formatted = data.map(formatIssueSummary);
577
504
  return {
578
505
  content: [
579
506
  {
@@ -591,7 +518,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
591
518
  inst,
592
519
  );
593
520
  return {
594
- content: [{ type: "text", text: formatIssue(data) }],
521
+ content: [{ type: "text", text: JSON.stringify(cleanIssueData(data), null, 2) }],
595
522
  };
596
523
 
597
524
  } else if (name === "sentry_get_latest_event") {
@@ -602,7 +529,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
602
529
  inst,
603
530
  );
604
531
  return {
605
- content: [{ type: "text", text: formatEvent(data) }],
532
+ content: [{ type: "text", text: JSON.stringify(cleanEventData(data), null, 2) }],
606
533
  };
607
534
 
608
535
  } else if (name === "sentry_resolve_issue") {
@@ -659,7 +586,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
659
586
  content: [{ type: "text", text: `No issues found for query: ${args.query}` }],
660
587
  };
661
588
  }
662
- const formatted = data.map(formatIssue);
589
+ const formatted = data.map(formatIssueSummary);
663
590
  return {
664
591
  content: [
665
592
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rui.branco/sentry-mcp",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Sentry MCP server for Claude Code - fetch issues, search errors, resolve/ignore issues, get stack traces and breadcrumbs",
5
5
  "main": "index.js",
6
6
  "bin": {