Docs
Everything Tokenmeter does is configured in one JSON file and exposed through a small local API.
configuration
Create ~/.tokenmeter/config.json with only the keys you want to change. It is merged over the bundled price list at startup, so upgrades never touch your settings.
{
"_plans": {"claude": 100, "codex": 20},
"_budget": {"daily": 30, "monthly": 600},
"gpt-6-astra": {"input": 10, "cache_read": 1, "cache_write_5m": 0, "cache_write_1h": 0, "output": 50}
}
| Key | Meaning |
|---|---|
_plans | USD per month per tool. Drives the Subscription spend tile. 0 or missing means API-equivalent cost is shown on top. |
_budget | daily and monthly caps in API-equivalent USD. One desktop notification per period when exceeded. |
_context_windows | Context size by model prefix, for the context-fill gauge. |
| model prefixes | USD per million tokens: input, cache_read, cache_write_5m, cache_write_1h, output. Longest matching prefix wins. |
| Flag or variable | Default | Purpose |
|---|---|---|
--port N | 7788 | Listen port. With start it is saved, so later runs and the background service use it. Without a saved port, Tokenmeter tries 7788 and, if another app holds it, the next 10 ports |
TOKENMETER_PORT | Port for this run only | |
start, stop | Run in the background and open the browser; stop it again | |
--open | Open the browser when running in the terminal | |
--host | 127.0.0.1 | Bind address. Only use 0.0.0.0 for a team server |
--export URL | Push your last 30 days to a team server every hour | |
--user NAME | login name | Name shown in team mode |
TOKENMETER_TOKEN | Shared secret for team ingest | |
CLAUDE_CONFIG_DIR, CODEX_HOME, COPILOT_DB | the tools' defaults | Where each agent keeps its logs |
TOKENMETER_DIR | ~/.tokenmeter | Config, log and team data |
how cost is calculated
Each model reply reports tokens by type. Tokenmeter multiplies each type by that model's list price and adds them up:
cost = cached reads × read price
+ uncached input × input price
+ cache writes × write price
+ output × output price (all per million tokens)
The dashboard splits tokens into three columns so the number is legible. Cached is the conversation re-sent from cache each turn, about 2 percent of a fresh token's price on Claude. Fresh is uncached input plus cache writes, context sent for the first time or re-written after a cache miss, and it drives most of the cost. Output is what the model wrote, including thinking. Claude Code writes its cache at the 1-hour rate; OpenAI does not charge for cache writes. Expand any prompt row to see its arithmetic.
These are API list prices. If you are on a subscription you pay the plan price; the dashboard shows that first and this API-equivalent figure below it, so you can see how many times your plan the same usage would have cost.
usage limits
Codex writes its 5-hour and weekly quota usage into every session log, so Tokenmeter shows the real percentages and reset times as of your last Codex turn. Anthropic does not write Claude plan usage to disk; Tokenmeter shows rolling 5-hour and 7-day totals from the logs, and the real percentage when a Claude Code OAuth token is available in the macOS keychain.
team mode
On a shared machine run tokenmeter --host 0.0.0.0 with TOKENMETER_TOKEN set. On each laptop run tokenmeter --export http://that-host:7788 with the same token. The shared dashboard gains a user filter. Only token counts, models, project paths and timestamps travel. Prompt text stays local.
http api
| Endpoint | Returns |
|---|---|
GET /api/usage | Every turn and prompt, pricing in use, plans, limits, users |
GET /api/summary | Today, last 5 hours, month, projection, limits. Used by the menu bar |
GET /api/commits | Recent commits per repo, for cost per commit |
GET /api/export.csv?since=ISO | CSV of turns |
GET /api/version | Cheap change token the page polls |
POST /api/ingest | Team mode receiver |
GET /api/health | {"ok": true, "app": "tokenmeter"} |