seatledger

io.github.agentwaresv0.2.0更新於 Oct 8, 2026

Local ledger of Claude Code and Codex tokens, API-equivalent cost, limits and token-rate changes.

已驗證STDIO僅桌面Developer ToolsData & Analytics

概覽

AI 產生的概覽

讀取本機 Claude Code 與 Codex 紀錄,回報 token 用量、API 等價成本、額度與速率變化。

功能
seatledger 讀取 Claude Code 與 Codex 已存放在本機的對話紀錄,整理成本機帳本:依日期、專案資料夾、模型與用戶端統計 token 與 API 等價美元,並顯示你設定額度的消耗速度。速率變化偵測器會標出每次請求 token 數、快取讀取占比或每輪 token 數出現階梯式變化的日期,並附上對應的用戶端版本。MCP 伺服器為唯讀,提供 seatledger_usage_summary、seatledger_rate_changes,以及加入團隊帳本後的 seatledger_team_summary。
適用情境
適合想了解程式代理席次實際消耗、以 API 等價成本比較方案或月份,或在用戶端更新後同一工作突然更耗 token 時及早發現的人。它是本機、免帳號的工具,面向個人開發者與小型團隊,而非廠商端帳單。
執行需求
透過 npx 以 stdio 在本機執行(需要 Node.js)。預設讀取 ~/.claude/projects 與 ~/.codex/sessions,可用 CLAUDE_CONFIG_DIR、CODEX_HOME、SEATLEDGER_HOME 覆寫。本機使用不需帳號或 API 金鑰。選用的團隊帳本需要邀請連結與推送金鑰,由 seatledger team join 儲存或以 SEATLEDGER_KEY 提供。
安裝前請注意
它會讀取本機代理對話紀錄,並在 ~/.seatledger 保存計數、時間戳、請求與工作階段 id、模型 id、用戶端版本與專案資料夾名稱;其說明稱從不儲存提示、回覆、工具或檔案內容。本機工具不發起網路請求,但 seatledger push、seatledger team 與 seatledger_team_summary 工具會把每日彙總與發現結果傳送到你加入的託管團隊帳本,使用 --project-names 時還會包含資料夾名稱。團隊方案為付費。工具回傳內容(含資料夾名稱)會進入你的模型供應商。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 seatledger,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

seatledger

What your coding-agent seats and tokens bought, from your own machine — and when the rate changed.

sh
npx seatledger

[seatledger and seatledger rates on synthetic history]

The picture is the real output of npx seatledger demo, which runs on synthetic history. It is regenerated by pnpm screenshot and a test fails if it drifts from what the CLI prints.

seatledger reads the transcripts Claude Code and Codex already keep on your machine and tells you:

  • tokens and API-equivalent dollars by day, project folder, model and client;
  • how fast you are burning toward limits you set, and when you would reach them at this rate;
  • when the rate changed: the same work suddenly costing more tokens per request, cache reads dropping because writes moved to a shorter cache lifetime, more tokens per turn after a client update, or Codex's own 5-hour window filling faster for the same tokens — with the date and the client version where it starts.

No vendor will build that last one: it is an alarm about their own rate. seatledger is MIT, has no telemetry and no runtime dependencies, and needs no account. It makes no network calls unless you join a team ledger and run seatledger push — and then it sends daily aggregates only, which seatledger push --dry-run prints in full.

Commands

sh
npx seatledger                                  # today and the last 7 days, your limits, vendor readingsnpx seatledger report --since 30d --by project  # --by day | project | model | client, --since 2026-09-01npx seatledger rates                            # step changes over the last 90 days (--since, --client, --model)npx seatledger limits set --window 5h --tokens 40M     # or --usd 25; --window weekly; --client codexnpx seatledger limits                           # your limits, burn rate, projected time to eachnpx seatledger mcp                              # read-only MCP server on stdionpx seatledger demo                             # all of the above on synthetic history
# the team ledger (optional; the only commands that send anything)npx seatledger team join <invite link> --as alice   # your key goes to ~/.seatledger/team.json (0600)npx seatledger push --dry-run                   # exactly what would be sent; sends nothingnpx seatledger push                             # this machine's daily aggregates to the teamnpx seatledger team                             # the team's plan and your seat

Every command takes --json, --client claude-code|codex, --claude-dir, --codex-dir and --no-cache. Without npm: npx github:agentwares/seatledger runs the same CLI from this repository (it ships its built dist/).

What it reads

ClientWhereWhat it takes
Claude Code~/.claude/projects/**/*.jsonl (or $CLAUDE_CONFIG_DIR/projects, ~/.config/claude/projects)each response's usage (input, output, cache reads, cache writes split into 5-minute and 1-hour), model, version, requestId, timestamp, working-directory folder
Codex CLI~/.codex/sessions/** and archived_sessions/ (or $CODEX_HOME)token_usage_record per response (newer versions) or token_count events, the turn's model, cli_version, and the rate_limits readings Codex writes

Checked on 7 October 2026 against Claude Code transcripts written by versions up to 2.1.286 (the changelog was at 2.1.292) and Codex rollouts written by 0.144–0.159, plus the Codex source at rust-v0.160.1 (TokenUsage, TokenUsageRecord, RateLimitSnapshot). Things the formats do that a naive reader gets wrong, and seatledger handles:

  • Claude Code writes one response as several lines, and only the last carries the final output_tokens. seatledger merges them per message.id:requestId and keeps the largest count.
  • The same response appears in more than one file (subagent transcripts, resumed and set-aside sessions); requests are deduplicated across files.
  • Codex's input_tokens already includes cached and cache-written input.
  • Unknown fields are ignored and a line cut off mid-write is skipped, never fatal.

Not read (yet): Gemini CLI was not installed where this was built, so its local record could not be checked against real files; Cursor's local store is an undocumented SQLite database and the copy checked held no per-request token counts. Neither is guessed at.

API-equivalent, not your bill

Dollars are API-equivalent: what the same tokens would cost at the vendor's API list prices. On a Pro, Max, Plus or Team seat you pay a flat fee; this is what that seat's usage would have cost on the API, which is the number to compare seats, plans and months by. It is labelled everywhere it appears. Prices come from a dated table in the package, with its sources:

A model without a list price (Codex's internal codex-auto-review, for one) is counted in tokens and its dollars are reported as unpriced, never estimated.

The rate-change detector

seatledger rates looks, per client and model, at complete days with at least 20 requests:

MetricWhat a step in it usually means
tokens per requesta bigger fixed prompt (system prompt, tools, skills, MCP definitions) or bigger context
cache-read share of prompt tokensthe cache is being read less, written more
cache writes per cache readthe same, as a ratio
tokens per user turnmore requests per prompt: more tool calls or subagents
share of cache writes at 1-hour (CC)recorded directly: writes moved between the 1-hour and 5-minute cache lifetimes
tokens per 1% of the 5-hour window (Codex)the vendor's own quota reading against the tokens spent: allowance per token

A day D is flagged when the median of D and up to 6 active days after it differs from the median of up to 7 active days before it by at least 30% (10 percentage points for shares), at least three quarters of the days on each side sit on their own side of the midpoint, and the difference is more than three times the day-to-day spread. It reports the date, the client version in use and whether D was the first day on it, the before and after values, and what the change is consistent with — for example:

From 30 Sep (Claude Code 2.1.230, the first day on it), cache reads per request fell 37%, cache writes per request rose 6.8x … — the transcript itself shows writes moving from the 1-hour to the 5-minute cache lifetime.

It sees requests on your machine, not the vendor's servers, so it never names a cause. A change in your own work (a new repository, a bigger task, more subagents) moves these numbers too, and when no client version change coincides it says so.

Limits

sh
npx seatledger limits set --window 5h --tokens 40Mnpx seatledger limits set --window weekly --usd 300 --client claude-codenpx seatledger limits clear --window 5h

seatledger does not ship any vendor's plan limits. They are not published as token counts, they change without notice, and a hard-coded number would be wrong in a way you could not see. Set your own — the "busiest window in 30 days" figure is a good start if you hit the limit then. A 5-hour window opens at your first request and lasts five hours, the way Claude Code and Codex describe theirs; weekly is the rolling last 7 days. Codex also writes its own 5-hour and weekly percentages to disk; seatledger shows the latest as Codex reported them.

Your history outlives the transcripts

Claude Code deletes transcripts older than cleanupPeriodDays, 30 days by default (docs). seatledger keeps the counts it has taken — never text — in ~/.seatledger/cache-v1/, one small file per transcript, so the ledger and the rate baselines keep their history after the transcript is gone. It also makes later runs fast: only new or changed transcripts are read. Delete the directory to forget it, or pass --no-cache.

The team ledger

The local ledger answers "what did my seat buy". A team lead paying for ten seats wants the same for everyone, kept longer than a laptop keeps it, and an email when the rate changes on anyone's machine. That is the hosted team ledger, run by agentwares:

PlanPriceDevelopersHistoryAlertsCSV
Free$0330 daysfindings on the dashboard—
Team$49/month1013 monthsemail and Slackyes
Business$149/month5013 monthsemail and Slackyes

The lead signs in with GitHub at agentwares-agentcheck.vercel.app/seatledger, which creates the team, and shares its invite link. Each developer runs npx seatledger team join <link> --as <name> once, then npx seatledger push (by hand, or from a cron or a session-end hook). An agent can create a free team with no human: POST /api/seatledger/v1/teams {"accept_terms": true} returns an owner key and an invite link.

Exactly what push sends

One JSON document (seatledger.push/v1); seatledger push --dry-run prints it in full and sends nothing.

  • days — every local day the push covers, from the first day this machine has history for. The ledger's rows for those days become exactly the pushed rows, so pushing a day again replaces it, never adds to it.
  • rows — one per day × client × client version × model: requests, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens and api_equivalent_usd (null for a model without a list price).
  • findings — what seatledger rates found in at least the last 90 days, as numbers and ids: client, model, the day it starts, the client version and the one before it, whether that was the first day on it, and per metric the before and after medians. The sentence you read locally is rebuilt by the service from these numbers; no text is sent. A finding sent again is the same finding.

Never sent: prompt, response, tool or file content; file paths; session or request ids; your project folder names — unless you pass --project-names, which splits rows by working-directory folder name (letters, digits, ., _, -; anything else becomes -). Every text field the service accepts is an id with no spaces and a short length limit; a field that could carry a sentence is refused.

The first push sends up to 400 days (the plan keeps what it keeps and says which days it did not store); later pushes start two days before the last one. --since 30d or --since 2026-09-01 overrides that. The key is your own (the owner can revoke it); it lives in ~/.seatledger/team.json, readable by you only, or in SEATLEDGER_KEY. The invite link's host is where your pushes go; SEATLEDGER_URL overrides it.

From your agent

MCP (npx -y seatledger mcp, stdio, read-only): seatledger_usage_summary and seatledger_rate_changes read this machine and make no request; seatledger_team_summary reads the team ledger this machine joined, with its saved key (one HTTPS request, changes nothing). Strict input schemas, errors with code, cause, fix, retryable.

sh
claude mcp add seatledger -- npx -y seatledger mcp
json
{ "mcpServers": { "seatledger": { "command": "npx", "args": ["-y", "seatledger", "mcp"] } } }

Whatever a tool returns goes to your agent's model provider like any other tool result, project folder names included.

Claude Code plugin (and Copilot CLI, which reads the same marketplace file): /plugin marketplace add agentwares/seatledger, then /plugin install seatledger@seatledger. /seatledger:usage explains the ledger and your limits; /seatledger:rates explains any step change.

Gemini CLI: gemini extensions install https://github.com/agentwares/seatledger, then /seatledger:usage and /seatledger:rates.

Privacy

  • Reads ~/.claude/projects and ~/.codex/sessions (or the directories you point it at).
  • Keeps counts, timestamps, request and session ids, model ids, client versions, working-directory folder names and the paths of the transcripts it read. It never stores or prints prompt, response, tool or file content: most transcript lines are skipped before they are parsed, and the records it keeps have no field that could hold text.
  • Writes only to ~/.seatledger (limits.json, cache-v1/, and team.json once you join a team), or $SEATLEDGER_HOME.
  • Has no runtime dependencies. Makes no network calls, except seatledger push, seatledger team and the seatledger_team_summary tool, which talk to the team ledger you joined and send what is listed under Exactly what push sends.

As a library

ts
import { load, groupRows, dailySeries, rateReport } from "seatledger";
const { requests, quota } = await load();const byModel = groupRows(requests, "model");const { findings } = rateReport(dailySeries(requests, quota));

Develop

sh
pnpm install && pnpm test   # the test script builds dist/ firstnode dist/cli.js demopnpm screenshot                # regenerate docs/screenshot.svg after changing the output

MIT © agentwares contributors.

來源:README.md,提交 7b7fa50

工具

0
工具後設資料尚未被收錄。

版本歷史

1
  1. v0.2.0最新Oct 8, 2026