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:
- Declares an input schema (the subset of SDK options it accepts).
- Maps tool input → SDK options, defaulting
session/project from the server's defaultSessionId / cwd where it makes sense.
- Calls the SDK function in-process.
- 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
- 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? }.
- 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.
- 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.
- Export the new factory functions from
packages/mcp/src/index.ts.
- 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.
- 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.
Summary
@relayburn/mcpcurrently 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/sdkis the canonical in-process query/compute surface, and@relayburn/mcpconsumes 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, viasdk.sessionCost) has been wrapped. Meanwhile:sdk.summaryexists (Add @relayburn/sdk embeddable package (ingest, summary, hotspots) and update AGENTS guide #228).sdk.hotspotsexists (Add @relayburn/sdk embeddable package (ingest, summary, hotspots) and update AGENTS guide #228).sdk.overheadandsdk.overheadTrimexist (Lift runOverhead into @relayburn/sdk (closes #235) #236).sdk.comparedoes not yet exist — out of scope here, tracked separately.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
burn__summarysdk.summary(opts)burn__hotspotssdk.hotspots(opts)burn__overheadsdk.overhead(opts)burn__overheadTrimsdk.overheadTrim(opts)burn__comparesdk.compare(opts)burn__sessionCoststays as-is.burn__budgetis 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:session/projectfrom the server'sdefaultSessionId/ cwd where it makes sense.Use
session-cost.tsas the template — same shape, same test seam ({ summary },{ hotspots }, … injected for unit tests; real SDK in production).Implementation steps
packages/mcp/src/tools/:summary.ts— wrapssdk.summary, accepts{ session?, project?, since? }.hotspots.ts— wrapssdk.hotspots, accepts{ session?, patterns? }.overhead.ts— wrapssdk.overhead, accepts{ project?, since?, kind? }.overhead-trim.ts— wrapssdk.overheadTrim, accepts{ project?, since?, kind?, top?, includeDiff? }.sessionand the server has adefaultSessionId, inject it. Tools whose query is project-scoped (overhead,overhead trim) defaultprojecttoprocess.cwd()if absent.packages/cli/src/commands/mcp-server.ts:74alongside the existingcreateSessionCostToolcall. Update theMCP_HELPblock at the top of the same file.packages/mcp/src/index.ts.packages/mcp/src/tools/using the dependency-injection seam (mirrorssession-cost.test.ts).end-to-end.test.tsto assert the new tools show up intools/listand round-trip atools/callagainst a fixture ledger.[Unreleased]entries onpackages/mcp/CHANGELOG.mdandpackages/cli/CHANGELOG.md(the help-text touch).Out of scope
burn__compare— needssdk.compareto land first. Track in a separate issue once that SDK function is being designed.--jsonoutput shapes.Risks / questions
hotspotsreturn type isPromise<unknown>in the SDK type today. Tighten that as part of this work or as a precursor — MCP needs a stable shape to declare inoutputSchema.burn__prefix on every tool for consistency withburn__sessionCost.