When running Claude Code with multiple agents and models, the first problem you hit is cost. "How much did we spend this week?" seems like a simple question, but when agent A uses Pro and B uses Sonnet, knowing only the total does not tell you where budget is leaking. sqgroup-official released cc-token-ledger on October 31. A tool that creates a table aggregating token usage by date/agent/model from Claude Code conversations. This article is a record of reading the original text and repository documentation, then reproducing an aggregation table with a small Node.js example. We did not build or run cc-token-ledger itself.

What "date/agent/model" three axes mean

The original text introduces cc-token-ledger as a "token usage table by date/agent/model from Claude Code conversations." Instead of a single total, it aggregates across three axes.

Table example from cc-token-ledger's official repository. Date, agent name, and model name appear as rows, with token counts and costs calculated in columns.

Image: Screenshot from sqgroup-official/cc-token-ledger official repository.

This design means two things. First, budget allocation becomes clear. Breaking down agent A's Pro usage from B's Sonnet usage tells you where budget is leaking. Second, you can measure model swap effects. You can compare date-by-date "how much do we save switching from Pro to Sonnet?"

The three stages of token aggregation

The work cc-token-ledger performs can be divided into three stages.

First, conversation log collection. Token usage is extracted from Claude Code's conversation logs. This step can be completed by parsing log files or API responses.

Second, axis classification. Extracted tokens are classified across three axes: date, agent, and model. Even on the same date, different agents are recorded in separate rows.

Third, table rendering. Classified data is rendered as a table. Displaying totals, averages, and trends together makes analysis easier.

A small example reproduced in Node.js

CodeBridge implemented a small example of cc-token-ledger's core flow in Node.js. This is not a reproduction of cc-token-ledger's actual implementation, but only shows the flow: log collection → classification → table rendering.

import fs from "node:fs";
import path from "node:path";

class TokenLedger {
  constructor() {
    this.entries = [];
  }

  addEntry(date, agent, model, promptTokens, completionTokens) {
    this.entries.push({
      date, agent, model,
      promptTokens, completionTokens,
      totalTokens: promptTokens + completionTokens
    });
  }

  buildTable() {
    const byDate = new Map();
    const byAgent = new Map();
    const byModel = new Map();

    for (const entry of this.entries) {
      // By date
      if (!byDate.has(entry.date)) byDate.set(entry.date, 0);
      byDate.set(entry.date, byDate.get(entry.date) + entry.totalTokens);

      // By agent
      if (!byAgent.has(entry.agent)) byAgent.set(entry.agent, 0);
      byAgent.set(entry.agent, byAgent.get(entry.agent) + entry.totalTokens);

      // By model
      if (!byModel.has(entry.model)) byModel.set(entry.model, 0);
      byModel.set(entry.model, byModel.get(entry.model) + entry.totalTokens);
    }

    return {
      byDate: Object.fromEntries(byDate),
      byAgent: Object.fromEntries(byAgent),
      byModel: Object.fromEntries(byModel)
    };
  }

  renderMarkdown() {
    const table = this.buildTable();
    let md = "| Category | Total Tokens |\n| --- | --- |\n";

    for (const [date, tokens] of Object.entries(table.byDate)) {
      md += `| ${date} | ${tokens.toLocaleString()} |\n`;
    }

    md += "\n| Agent | Total Tokens |\n| --- | --- |\n";
    for (const [agent, tokens] of Object.entries(table.byAgent)) {
      md += `| ${agent} | ${tokens.toLocaleString()} |\n`;
    }

    md += "\n| Model | Total Tokens |\n| --- | --- |\n";
    for (const [model, tokens] of Object.entries(table.byModel)) {
      md += `| ${model} | ${tokens.toLocaleString()} |\n`;
    }

    return md;
  }
}

export { TokenLedger };

This example does not copy cc-token-ledger's implementation verbatim. It only shows the flow: log collection → classification → table rendering. The actual cc-token-ledger may have more complex parsing logic tailored to Claude Code's log format.

Questions to check before adopting cc-token-ledger

Summarizing the checklist from cc-token-ledger's documentation:

Question Evidence to check Common misconception
Does the log format vary by Claude Code version? Version-by-version test results All Claude Code versions use the same log format
How are agent names identified? Naming rules, alias handling Agent names are always fixed
Does the model name match actual usage? API response parsing method Model names always map accurately
Does cost calculation match current pricing? Unit price table, exchange rate policy Token count × unit price = exact cost
Can past data be re-aggregated? Reparsing support Logs mean you can always recalculate

Constraints before adoption

cc-token-ledger does not include Claude Code's log format by default. Since the log format may vary by version, you must verify the parsing logic. The original text emphasizes the advantage of aggregating across date/agent/model, but if the log format changes, the table may break.

Cost calculation accuracy, past data re-aggregation capability, and multi-account support are not measured in this article. In particular, "token count × unit price" does not always lead to exact costs; if discounted rates or volume discounts apply, the table may differ from actual invoices.

What to learn from cc-token-ledger is not the log parsing method or table rendering style. It is changing token usage from a single total to three axes. When analyzing Claude Code costs next time, try making a table of "where, which model, how much" before the total amount.

The paid course below covers verification and constraint design of AI coding harnesses including Claude Code. It is not a course providing cc-token-ledger usage or reproduction of this experiment; the link is a promotional link.