New
Apps 33Makers 33This week 33
Promote your app−30%
Tallyhook screenshot 1
1views in
the last 30 days

Tallyhook

Price Claude Code and Codex logs per client you bill

Built with Claude Code

by tallyhook · added Oct 28, 2026
no ratings0 comments
Open app Code

npx tallyhook

What your AI coding agents actually cost — per repo, per team, and per client you bill.

One dependency-free Node.js file. It reads the session logs Claude Code and Codex CLI already write on your machine and prices them. No account, no signup, nothing uploaded.

npx tallyhook
AI coding-agent usage on this machine, last 30 days (public API list prices)

REPO                              SESSIONS    OUTPUT    LIST COST
github.com/acme/storefront             118     10.8M    $1,450.59
github.com/acme/patient-portal         100      7.2M      $867.84
github.com/globex/intranet              44      3.1M      $402.17
local:scratch                            4     96.2k       $20.36
TOTAL                                  266     21.2M    $2,740.96

Previous 30 days: $1,602.11 across 186 sessions — up 71%.

Group the repos the way your business works

A per-repo table answers "what is this project costing me." The next question forks on who is asking: a lead wants these repos added up per team or service, and a shop wants them added up per client, with a rate on top. It is one map either way, so use the word that fits.

npx tallyhook teams add "Platform" acme/storefront globex/intranet
npx tallyhook teams add "Clinical" acme/patient-portal
npx tallyhook --by team
TEAM            SESSIONS    OUTPUT    LIST COST
Platform             162     13.9M    $1,852.76
Clinical             100      7.2M      $867.84
TOTAL                262     21.1M    $2,720.60

Not counted: $20.36 in repos no team claims. `tallyhook teams` lists them.

Add a rate and the same rows carry what to invoice — the number you need is not "what did this repo cost" but "what do I put on Acme's invoice this month":

npx tallyhook clients add "Acme Corp" acme/storefront acme/patient-portal --rate 20
npx tallyhook clients add "Globex" globex/ --rate 35
npx tallyhook --by client
CLIENT          SESSIONS    OUTPUT    LIST COST     BILLABLE
Acme Corp            218     18.0M    $2,318.43    $2,782.12
Globex                44      3.1M      $402.17      $542.93
TOTAL                262     21.1M    $2,720.60    $3,325.05

Not counted: $20.36 in repos no client claims. `tallyhook clients` lists them.

teams, groups and clients are one command under three names, over one map stored in ~/.tallyhook/clients.json — on your machine, still free, still uploading nothing. The word you type changes the heading and the wording around it and never the data, so a map set up as clients reads back as teams with nothing to migrate, and --json keeps its clients key whichever word you use. The BILLABLE column appears only once something actually has a rate.

tallyhook teams on its own prints the map plus every repo nothing claims yet, most expensive first — which is the list of work standing between you and the whole machine accounted for.

Billable totals are summed from rows rounded to the cent, deliberately: a client who adds up the lines you showed them has to land on the total you billed.

Commands

npx tallyhook                       # spend per repo, last 30 days
npx tallyhook --by team             # roll those repos up per team or service
npx tallyhook --by client           # the same roll-up, with a rate on top to bill
npx tallyhook --by model            # the same spend per model
npx tallyhook teams                 # the map, and which repos nothing claims yet
npx tallyhook mcp                   # MCP server, so an agent can ask what its own work cost
flag what it does
--days 90 a longer window. The trend line always compares against the equally long window immediately before it, so --days 7 compares this week against last week.
--by team|client|group|model|repo how to group. team, client and group are one grouping under three names. A session that spanned two models has its cost split between them rather than attributed whole.
--markup 20 try a rate without saving it. Beats any stored rate for that one run, so it never silently no-ops.
--json the same numbers with no prose, for a script. Nothing unpriceable is guessed: if the price table is unreachable every cost is null and priced is false. With --by team or --by client it also carries counted and not_counted_cost_usd, which always add up to total_cost_usd, so a script can tell how much of the machine the grouped rows actually cover.

Everything above runs entirely on your machine. The only network call is a GET for the public price table (https://tallyhook.dev/api/prices). Prefer to read it before you run it? It is one file, tallyhook.js, in this repo — download it, read it, then node tallyhook.js.

What it gets right

Most of the work in this file is in not being wrong:

  • Streamed rows: Claude Code writes one JSONL row per content block, each carrying the same usage object. Rows are deduplicated by message.id, or the same tokens get counted many times.
  • Subagents: forked subagent transcripts copy the parent's assistant rows. Deduplication spans every file of a session, including subagents/*.jsonl.
  • Cache pricing: cache reads, 5-minute cache writes (1.25× input) and 1-hour cache writes (2× input) are each priced separately. Fast-mode messages are priced at the fast-mode rate.
  • Codex: reads ~/.codex/sessions/**/*.jsonl, and the .jsonl.zst files Codex compresses after seven days (needs Node 22.15+; older Node skips them rather than guessing).
  • Repos, not folders: sessions group by git remote (host/org/repo), so the same repo in two checkouts is one line. No remote means local:<folder>.
  • Files, not just cwd: a session that edited files in three repos is attributed to the repos the files belong to, not to whichever directory the agent happened to start in.
  • Honest numbers: costs are list-price equivalents from the vendors' public API pricing. On a subscription that is the value of what you used, not a bill. A model with no known price is reported as unpriced rather than guessed at.

Ask your agent what it just cost you

claude mcp add tallyhook -- npx -y tallyhook mcp

An MCP server over stdio, so Claude Code (or any MCP client) can answer cost questions about its own work. No account, no token, nothing uploaded — it reads the same local logs the report does. Or by hand, in .mcp.json:

{ "mcpServers": { "tallyhook": { "command": "npx", "args": ["-y", "tallyhook", "mcp"] } } }

Then ask it "what has this repo cost me this month?", "which sessions were the expensive ones?" or "am I spending more than last month?"

tool answers
usage_by_repo spend grouped by git repository over the last N days
usage_by_model the same spend grouped by model — a session spanning two models is split between them, so the totals agree
expensive_sessions the individual sessions that cost the most, for finding a runaway agent loop
usage_summary total and session count, against the equally long window immediately before

Parsing every local log is the slow part, so it is cached for a minute per process: the first question takes a few seconds on a busy machine, the rest are instant. Set "privacy": true in ~/.tallyhook/config.json and expensive_sessions omits the prompt snippet too.

Install it as an agent skill

npx skills add tallyhook/tallyhook-collector

Installs agent-cost-report for Claude Code, Codex, Cline, Amp and twenty-odd other agents at once, so the agent itself can answer "what has this project cost", "what is the Platform team spending" and "what do I bill Acme this month" without being told how. The skill carries the rules that stop the answer being wrong: that these are list-price equivalents rather than a bill, that a grouped report covers only mapped repositories and says in money what it excluded, and that an unreachable price table means report tokens rather than guess at dollars.

For Claude Code specifically there is also a plugin, with /tallyhook:cost and /tallyhook:groups plus the MCP server above.

When one machine is not enough

Everything above reads only what is on this disk, which is also its limit: it cannot see your colleagues' sessions, it forgets history once Claude Code rotates its logs, and it cannot hand anybody else a link. Tallyhook is the hosted layer for those three: every developer's sessions in one total, history that outlives the logs, a budget and alert per repo, team or client, and a read-only report link that needs no login — for a lead, for finance, or for the client you are billing. There is a live demo that needs no signup.

npx tallyhook install <token>       # registers Claude Code hooks (SessionEnd, and Stop at most every 10 min), uploads history
npx tallyhook sync [--dry-run]      # upload anything new now; --dry-run prints a summary and never touches the network
npx tallyhook status                # what is configured
npx tallyhook uninstall             # remove the hooks and ~/.tallyhook

The local commands stay local and account-free either way; installing a token does not change what they read or send anything extra.

Uploaded per session (install/sync only): token counts by model, start and end time, tool and version, git remote and branch, which repositories the edited files belong to, developer identity from git config, machine hostname, turn and tool-call counts, paths of edited files, and the first 160 characters of the first prompt (turn that off with "privacy": true).

Never uploaded: transcripts, code, diffs, tool output, environment variables.


Node.js 18+. macOS and Linux; Windows is newly allowed as of 0.4.2 and not yet verified. Licence: MIT.

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#billing · #claude-code · #cli