Skip to content

Commit 627c2b2

Browse files
authored
fix(issue details): cap related replays in the structured payload (#1296)
1 parent 9f4cd36 commit 627c2b2

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

‎packages/mcp-core/src/tools/catalog/get-issue-details.test.ts‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2621,4 +2621,39 @@ describe("structuredContent", () => {
26212621
expect(payload.issue.queryPattern).toBe("SELECT * FROM users WHERE id = ?");
26222622
expect(payload.issue.location).toBe("/api/checkout");
26232623
});
2624+
2625+
it("caps related replays and reports the full count", async () => {
2626+
// a real issue came back with 51 of these
2627+
const many = Array.from({ length: 51 }, (_, i) =>
2628+
i.toString(16).padStart(32, "0"),
2629+
);
2630+
mswServer.use(
2631+
http.get(
2632+
"https://sentry.io/api/0/organizations/sentry-mcp-evals/issues/CLOUDFLARE-MCP-41/events/latest/",
2633+
() =>
2634+
HttpResponse.json({
2635+
...createDefaultEvent(),
2636+
formatted: { format: "json", content: FORMATTER_JSON },
2637+
}),
2638+
),
2639+
// related ids come from replay-count, keyed by numeric issue id. Echo back whichever
2640+
// id was asked for: a preceding test can leave a different issue fixture registered.
2641+
http.get(
2642+
"https://sentry.io/api/0/organizations/sentry-mcp-evals/replay-count/",
2643+
({ request }) => {
2644+
const query = new URL(request.url).searchParams.get("query") ?? "";
2645+
const issueId = query.match(/issue\.id:\[(\d+)\]/)?.[1];
2646+
return HttpResponse.json(issueId ? { [issueId]: many } : {});
2647+
},
2648+
),
2649+
);
2650+
2651+
const result = await getIssueDetails.handler(params, baseContext);
2652+
const payload = (result as { structuredContent: Record<string, any> })
2653+
.structuredContent;
2654+
2655+
expect(payload.replays).not.toBeNull();
2656+
expect(payload.replays.relatedCount).toBe(51);
2657+
expect(payload.replays.related).toHaveLength(5);
2658+
});
26242659
});

‎packages/mcp-core/src/tools/catalog/get-issue-details.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ import { logError } from "../../telem/logging";
4646
import type { ServerContext } from "../../types";
4747
import { resolveCodeLocation } from "../support/code-location";
4848

49+
// mirrors MAX_DISPLAY_REPLAYS in the markdown output
50+
const MAX_RELATED_REPLAYS = 5;
4951
const MAX_AI_CONVERSATION_MATCHES = 3;
5052
const AI_CONVERSATION_LOOKUP_WINDOW_MS = 24 * 60 * 60 * 1000;
5153
const TRACE_ID_PATTERN = /^[0-9a-fA-F]{32}$/;
@@ -108,6 +110,8 @@ export const getIssueDetailsOutputSchema = z.object({
108110
.object({
109111
attached: z.string().nullish(),
110112
related: z.array(z.string()),
113+
// the full count, since `related` is capped
114+
relatedCount: z.number(),
111115
})
112116
.nullish(),
113117
externalIssues: z
@@ -189,7 +193,12 @@ function buildReplays(
189193
if (!attached && related.length === 0) {
190194
return null;
191195
}
192-
return { attached, related };
196+
// markdown shows a count plus the first few, not every id
197+
return {
198+
attached,
199+
related: related.slice(0, MAX_RELATED_REPLAYS),
200+
relatedCount: related.length,
201+
};
193202
}
194203

195204
function buildIssueDetailsPayload({

0 commit comments

Comments
 (0)