cd /news/ai-tools/show-hn-tallyhook-price-claude-code-… · home › topics › ai-tools › article
[ARTICLE · art-147591] src=github.com ↗ pub= topic=ai-tools verified=true sentiment=· neutral

Show HN: Tallyhook – price Claude Code and Codex logs per client you bill

Tallyhook, a dependency-free Node.js tool, prices Claude Code and Codex CLI session logs per repository and per billable client using public API list prices, running entirely on the user's machine with no account or upload. The tool reports a sample 30-day total of $2,740.96 across 266 sessions, with the previous 30 days at $1,602.11 across 186 sessions, a 71% increase. Tallyhook deduplicates streamed JSONL rows by message.id and prices cache reads, 5-minute cache writes at 1.25x input, and 1-hour cache writes at 2x input.

read6 min views10 publishedOct 8, 2026
Show HN: Tallyhook – price Claude Code and Codex logs per client you bill
Image: Michielbdejong (auto-discovered)

What your AI coding agents actually cost — per repo, 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%.

If you run agents on work you bill someone for, the number you need is not "what did this repo cost" — it's "what do I put on Acme's invoice this month." So group the repos and set a rate:

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.

That mapping lives in ~/.tallyhook/clients.json, on your machine, and it is still free and still uploads nothing. tallyhook clients on its own prints the map plus every repo no client claims yet, most expensive first — which is the list of work standing between you and a complete invoice.

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.

npx tallyhook                       # spend per repo, last 30 days
npx tallyhook --by client           # roll repos up into the clients you bill
npx tallyhook --by model            # the same spend per model
npx tallyhook clients               # the billing map, and which repos nobody claims
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 client|model|repo how to group. 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 andpriced isfalse . With--by client it also carriescounted andnot_counted_cost_usd , which always add up tototal_cost_usd , so a script can tell how much of the machine the client 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.

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 sameusage object. Rows are deduplicated bymessage.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, includingsubagents/*.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 meanslocal:<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.
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.

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" 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 client 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:clients plus the MCP server above.

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 a client anything. 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 client, and a report link you can send a client with no login. 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.

── more in #ai-tools 4 stories · sorted by recency
── more on @tallyhook 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-tallyhook-pr…] indexed:0 read:6min 2026-10-08 · —