Skip to content

feat(mcp): let Crashlytics event tools return more than 20 stack frames - #11061

Open
Ishkirat-Singh wants to merge 2 commits into
firebase:mainfrom
Ishkirat-Singh:feat/mcp-crashlytics-max-frames
Open

Ishkirat-Singh wants to merge 2 commits into
firebase:mainfrom
Ishkirat-Singh:feat/mcp-crashlytics-max-frames

Conversation

@Ishkirat-Singh

Copy link
Copy Markdown

Description

formatFrames capped every stack trace at 20 frames through a default parameter that no call site could override, and neither crashlytics_list_events nor crashlytics_batch_get_events exposed it in its input schema. An agent that needed frame 25 had no way to ask for it short of leaving the MCP server and calling the API directly.

This adds an optional maxFrames input (positive integer) to both tools and threads it through toText to formatFrames. The default stays at 20, so existing output is unchanged. The other truncations mentioned in the issue (per-frame fields, breadcrumbs, logs) are left as they are; happy to follow up on those separately if wanted.

Fixes #11027

Scenarios Tested

  • Added src/mcp/tools/crashlytics/events.spec.ts with listEvents/batchGetEvents stubbed: default output stops after 19 frames plus the "frames omitted" marker, maxFrames: 100 includes all 25 frames with no marker, and batch_get_events honours maxFrames: 5.
  • npx mocha src/mcp/tools/crashlytics/events.spec.ts: 3 passing.

Sample Commands

Via MCP: crashlytics_list_events with { "appId": "...", "filter": { "issueId": "..." }, "maxFrames": 100 }.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an optional 'maxFrames' parameter to the 'crashlytics_list_events' and 'crashlytics_batch_get_events' MCP tools, allowing users to retrieve more than the default 20 stack frames per trace. It also adds corresponding unit tests and updates the changelog. The review feedback suggests improving type safety in the new test file by avoiding 'any' and redundant type assertions (such as 'as unknown as Event'), aligning with the repository's style guide.

Comment on lines +1 to +9
import { expect } from "chai";
import * as sinon from "sinon";
import { batch_get_events, list_events } from "./events";
import * as crashlyticsEvents from "../../../crashlytics/events";
import { Event, Frame } from "../../../crashlytics/types";

describe("crashlytics events tools", () => {
const appId = "1:123456789:android:abcdef";
const ctx = {} as any;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid using any as an escape hatch. Instead, import and use the proper McpContext type to ensure type safety and adhere to the repository style guide.

Suggested change
import { expect } from "chai";
import * as sinon from "sinon";
import { batch_get_events, list_events } from "./events";
import * as crashlyticsEvents from "../../../crashlytics/events";
import { Event, Frame } from "../../../crashlytics/types";
describe("crashlytics events tools", () => {
const appId = "1:123456789:android:abcdef";
const ctx = {} as any;
import { expect } from "chai";
import * as sinon from "sinon";
import { batch_get_events, list_events } from "./events";
import * as crashlyticsEvents from "../../../crashlytics/events";
import { Event, Frame } from "../../../crashlytics/types";
import { McpContext } from "../../types";
describe("crashlytics events tools", () => {
const appId = "1:123456789:android:abcdef";
const ctx = {} as McpContext;
References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 78c7e3b: the spec uses McpContext for the context and drops the Frame[] / unknown assertions.

Comment on lines +11 to +20
function eventWithFrames(count: number): Event {
const frames: Frame[] = Array.from({ length: count }, (_, i) => ({
symbol: `frame${i + 1}`,
file: "Main.kt",
line: i + 1,
})) as Frame[];
return {
exceptions: [{ type: "java.lang.RuntimeException", exceptionMessage: "boom", frames }],
} as unknown as Event;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid using unnecessary type assertions like as Frame[] and as unknown as Event. Since all properties of Event and Frame are optional, these assertions are redundant and violate the repository style guide's rule against using unknown as an escape hatch.

Suggested change
function eventWithFrames(count: number): Event {
const frames: Frame[] = Array.from({ length: count }, (_, i) => ({
symbol: `frame${i + 1}`,
file: "Main.kt",
line: i + 1,
})) as Frame[];
return {
exceptions: [{ type: "java.lang.RuntimeException", exceptionMessage: "boom", frames }],
} as unknown as Event;
}
function eventWithFrames(count: number): Event {
const frames: Frame[] = Array.from({ length: count }, (_, i) => ({
symbol: `frame${i + 1}`,
file: "Main.kt",
line: i + 1,
}));
return {
exceptions: [{ type: "java.lang.RuntimeException", exceptionMessage: "boom", frames }],
};
}
References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

@Ishkirat-Singh
Ishkirat-Singh force-pushed the feat/mcp-crashlytics-max-frames branch 2 times, most recently from 78c7e3b to 9751d09 Compare September 13, 2026 15:55
formatFrames capped every stack trace at 20 frames through a default
parameter that no call site could override, and neither
crashlytics_list_events nor crashlytics_batch_get_events exposed it, so an
agent that needed a deeper frame had no way to ask for it short of calling
the API directly.

Add an optional maxFrames input to both tools and thread it through to
formatFrames. The default stays at 20, so existing output is unchanged.

Fixes firebase#11027
@Ishkirat-Singh
Ishkirat-Singh force-pushed the feat/mcp-crashlytics-max-frames branch from 9751d09 to c04aca9 Compare September 14, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MCP] Crashlytics stack traces are capped at 20 frames with no way to request more

2 participants