Context
burn hotspots already attributes per-tool cost across a session, but MCP server tools (mcp__<server>__<tool>) show up as N separate rows — one per tool name. For workspaces using a chatty MCP server like relaycast (DM send, channel list, message reactions, agent register, …) there can be 50+ distinct tools, none of which individually look expensive but which collectively can dominate spend.
Today there's no way to ask "how much did relaycast as a whole cost me?" without manually filtering and summing the rows downstream.
Proposal
Add an MCP-server rollup alongside the existing file / bash / bash-verb / subagent aggregations in crates/relayburn-sdk/src/analyze/hotspots.rs:
- Group any tool whose name matches
mcp__<server>__<tool> by <server>.
- Sum
call_count, initial_tokens, persistence_tokens, riding_turns, total_cost.
- Carry the top 3 representative tool names (cost desc) like
BashVerbAggregation::top_examples.
- Sort by
total_cost desc.
Surface in the CLI under burn hotspots (new section in the human renderer, new field in the JSON output). Wire it through relayburn-sdk-node / @relayburn/sdk so the MCP presenter can ask the same question.
Scope
SDK (relayburn-sdk)
- New
McpServerAggregation struct in analyze/hotspots.rs.
- New
aggregate_by_mcp_server(&[ToolAttribution]) -> Vec<McpServerAggregation> mirroring aggregate_by_bash_verb's shape.
- Add the field to
HotspotsResult (or whichever struct the CLI presenter consumes).
CLI (relayburn-cli)
- New section in
commands/hotspots.rs human renderer (gated on non-empty rollup).
- Include in
--json output.
Node facade
- Re-export the new aggregation field via
packages/sdk-node.
Acceptance
Context
burn hotspotsalready attributes per-tool cost across a session, but MCP server tools (mcp__<server>__<tool>) show up as N separate rows — one per tool name. For workspaces using a chatty MCP server like relaycast (DM send, channel list, message reactions, agent register, …) there can be 50+ distinct tools, none of which individually look expensive but which collectively can dominate spend.Today there's no way to ask "how much did relaycast as a whole cost me?" without manually filtering and summing the rows downstream.
Proposal
Add an MCP-server rollup alongside the existing file / bash / bash-verb / subagent aggregations in
crates/relayburn-sdk/src/analyze/hotspots.rs:mcp__<server>__<tool>by<server>.call_count,initial_tokens,persistence_tokens,riding_turns,total_cost.BashVerbAggregation::top_examples.total_costdesc.Surface in the CLI under
burn hotspots(new section in the human renderer, new field in the JSON output). Wire it throughrelayburn-sdk-node/@relayburn/sdkso the MCP presenter can ask the same question.Scope
SDK (
relayburn-sdk)McpServerAggregationstruct inanalyze/hotspots.rs.aggregate_by_mcp_server(&[ToolAttribution]) -> Vec<McpServerAggregation>mirroringaggregate_by_bash_verb's shape.HotspotsResult(or whichever struct the CLI presenter consumes).CLI (
relayburn-cli)commands/hotspots.rshuman renderer (gated on non-empty rollup).--jsonoutput.Node facade
packages/sdk-node.Acceptance
aggregate_by_mcp_serverunit test against a fixture containing two MCP servers + non-MCP tools (verifies tools without themcp__prefix are skipped, costs sum, sort order is total_cost desc).burn hotspots --jsonincludes the rollup field.MCP serverssection ordered by total_cost desc with top tool examples.CHANGELOG.mdand (if surface changes)packages/sdk-node/CHANGELOG.md.