Skip to content

mcp: expand tool catalog to cover the read surface (summary, hotspots, overhead, overhead trim) #237

@willwashburn

Description

@willwashburn

Summary

@relayburn/mcp currently exposes a single tool — burn__sessionCost. The CLI's read surface is much larger (summary, hotspots, overhead, overhead trim, compare), and every new verb makes that gap worse. Expand the MCP catalog to wrap each public SDK read function so MCP's surface tracks the SDK's surface in lockstep.

Background

After #232, @relayburn/sdk is the canonical in-process query/compute surface, and @relayburn/mcp consumes it. New read verbs land in SDK first as pure functions; CLI and MCP are presenters over the same calls. That structure is in place but only one tool (burn__sessionCost, via sdk.sessionCost) has been wrapped. Meanwhile:

This issue replaces the original #210 proposal (subprocess to burn <verb> --json), which was rejected in favor of the in-process SDK approach in #232.

Proposed tool catalog

MCP tool SDK call Status of underlying SDK fn
burn__summary sdk.summary(opts) exists
burn__hotspots sdk.hotspots(opts) exists
burn__overhead sdk.overhead(opts) exists
burn__overheadTrim sdk.overheadTrim(opts) exists
burn__compare sdk.compare(opts) not yet — out of scope

burn__sessionCost stays as-is.

burn__budget is intentionally not in the catalog — the budget surface was removed in #229.

Tool shape

Each tool is a thin file under packages/mcp/src/tools/ that:

  1. Declares an input schema (the subset of SDK options it accepts).
  2. Maps tool input → SDK options, defaulting session/project from the server's defaultSessionId / cwd where it makes sense.
  3. Calls the SDK function in-process.
  4. Returns the SDK result as the tool's structured content.

Use session-cost.ts as the template — same shape, same test seam ({ summary }, { hotspots }, … injected for unit tests; real SDK in production).

Implementation steps

  1. One file per tool under packages/mcp/src/tools/:
    • summary.ts — wraps sdk.summary, accepts { session?, project?, since? }.
    • hotspots.ts — wraps sdk.hotspots, accepts { session?, patterns? }.
    • overhead.ts — wraps sdk.overhead, accepts { project?, since?, kind? }.
    • overhead-trim.ts — wraps sdk.overheadTrim, accepts { project?, since?, kind?, top?, includeDiff? }.
  2. Default-injection rule: when a tool's input omits session and the server has a defaultSessionId, inject it. Tools whose query is project-scoped (overhead, overhead trim) default project to process.cwd() if absent.
  3. Register the new tools in packages/cli/src/commands/mcp-server.ts:74 alongside the existing createSessionCostTool call. Update the MCP_HELP block at the top of the same file.
  4. Export the new factory functions from packages/mcp/src/index.ts.
  5. Tests:
    • Per-tool unit test under packages/mcp/src/tools/ using the dependency-injection seam (mirrors session-cost.test.ts).
    • Extend end-to-end.test.ts to assert the new tools show up in tools/list and round-trip a tools/call against a fixture ledger.
  6. Changelogs: [Unreleased] entries on packages/mcp/CHANGELOG.md and packages/cli/CHANGELOG.md (the help-text touch).

Out of scope

  • burn__compare — needs sdk.compare to land first. Track in a separate issue once that SDK function is being designed.
  • Auto-deriving tool input schemas from CLI flag definitions. Schemas stay hand-written; they're small and per-tool.
  • Any change to the CLI's --json output shapes.

Risks / questions

  • Schema drift between MCP input and SDK options. Adding a new SDK option won't appear in the MCP tool until someone updates the schema. Acceptable — the surfaces are small and reviewed together. If drift becomes a real problem, revisit by exporting Zod schemas from SDK directly.
  • hotspots return type is Promise<unknown> in the SDK type today. Tighten that as part of this work or as a precursor — MCP needs a stable shape to declare in outputSchema.
  • Naming. Keep the burn__ prefix on every tool for consistency with burn__sessionCost.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions