Track Claude Code Spend
@marginfront/code-cost-clarity is a small command-line tool. One command wires Claude Code’s usage telemetry through a local collector and into MarginFront — priced per engineer, per model, with accurate prompt-cache pricing by default.
This is internal cost visibility, not billing and not a spending cap. Your company watches its own AI coding spend (per engineer, per model). It does not charge engineers and it does not cut anyone off.
What this does (one sentence)
Every time an engineer runs Claude Code, this tool captures the token usage and sends it to MarginFront as a usage event — so you can see who used what, on which model, and how much it cost.The mental model (read this first)
Think of it like a cash-register receipt system:- Claude Code is the register. As it works, it broadcasts receipts: how many tokens, which model, which engineer.
- The collector (
otelcol-contrib, open source) is the catcher. It runs in the background, catches the receipts, and writes them to a file. - The forwarder (the glue inside this tool) reads those receipts and sends each one to MarginFront.
- MarginFront records the event, prices it, and shows it under the engineer’s email.
OTEL_METRIC_EXPORT_INTERVAL) plus a final flush when the session ends. Set the interval high (for example, 10 minutes) and you effectively get one event per turn, recorded when the turn finishes. Set it low (for example, 5 seconds) and you get a live drip as you work. Either way the collector keeps repeated reports from double-counting.
Quick start
run terminal to stop; it shuts the collector down too.
The commands
| Command | What it does |
|---|---|
init | Creates ~/.marginfront-ccc/, writes your settings and the collector config, and downloads the collector binary. Safe to re-run — it never overwrites your saved API key. |
preview <capture.json> | Prints the exact record it would send for one captured snapshot. Needs no API key — great for a dry run. |
run | Starts the collector in the background and streams your live spend to MarginFront. Ctrl-C stops both. Add --fold-cache only for an unpriced model (see below). |
stop | Stops a collector that was left running in the background. |
uninstall | Stops everything and deletes the collector binary and runtime files (reclaims the ~360 MB). Keeps your settings. Add --purge to also delete your settings and API key. |
help, version | The usual. |
Per-engineer attribution is automatic
What makes “who spent what” work is the engineer’s email, and Claude Code puts it in the telemetry on its own — it’s the engineer’s logged-in Claude account email. There is no manual email setup. Each engineer just loads the telemetry settings and runs Claude Code normally. Works under an API key or an interactive login. On org-managed Claude seats the email is stamped for free. If an engineer’s login mode doesn’t surface an email, the tool doesn’t drop the usage — it attributes it to a clearly labeled placeholder customer (claude-code-no-identity) and prints how to fix it (sign in with an org-managed seat, or attach a customer mapping). You’ll see the placeholder in preview or run output if it ever kicks in.
Your MarginFront API key is separate from the engineer’s identity: it’s the tool’s own credential for posting to MarginFront.runneeds it;previewdoes not.
The one honest caveat: cache pricing
Claude Code reports four kinds of tokens — fresh input, output, cache-read, and cache-creation — and Anthropic charges three different prices for them. MarginFront prices all of them, so by default this tool sends the cache-read and cache-creation tokens in their own fields and the dollar figure is accurate.- Default (recommended): accurate. Cache tokens go in the
cacheReadTokensandcacheWriteTokensfields; MarginFront prices each at its real cache rate. --fold-cache(emergency round-up only): for a model MarginFront can’t price yet, this rolls the cache tokens into billed input at the fresh-input rate, pushing the number up toward reality so it’s never silently low — a conservative ceiling. Use it only when a model has no cache price; otherwise the default is more accurate.
metadata, and Claude Code’s own cache-accurate dollar cost is stored in metadata.claudeCodeCostUsd as ground truth to reconcile against.
Heads up: a long-context model id likeclaude-opus-4-8[1m]is normalized toclaude-opus-4.8to match MarginFront’s pricing table. The raw id is kept inmetadata.rawModel.
Confirm it landed (independent read-back)
Pull the most recent events for one engineer straight from the API:Maintain / shut off
- Bump the collector version: the install pins a known-good collector release. To use a different one for a run, set
CCC_OTELCOL_VERSIONbeforeinit. - Stop temporarily: Ctrl-C the
runterminal, orstopif it’s in the background. Re-runrunto resume. - Remove it:
uninstallfrees the ~360 MB and stops everything but keeps your key.uninstall --purgedeletes your settings too. If you added the telemetry exports to your~/.zshrc, remove them there by hand.
Troubleshooting
- “No MARGINFRONT_API_KEY found” — paste your key into
~/.marginfront-ccc/.env, orexport MARGINFRONT_API_KEY=...in therunshell.previewworks without one. - HTTP 401 / 403 — wrong or expired key; pull a fresh one from your MarginFront dashboard.
- HTTP 422 / validation error — body-shape mismatch. Run
preview <capture.json>and compare the record. - Collector file stays empty — you’re probably on gRPC/4317. The settings default to http/protobuf/4318, which is the transport that actually works with Claude Code; make sure you
sourced the env file. usageCostis null — the normalized model id didn’t match the pricing table. Tokens are still recorded; the cache-accurate cost is inmetadata.claudeCodeCostUsd.- Numbers ballooning — the collector’s delta conversion isn’t running. Re-run
initto rewrite the collector config. - Seeing
claude-code-no-identity? — your login didn’t surface an email. Use an org-managed Claude seat, or attach a customer mapping.
Security
- Your API key never lives in the package. It’s saved only in
~/.marginfront-ccc/.env(mode 600) on your machine. The forwarder reads it from the environment only — never hardcoded, never logged. - The published package contains only the built code and its README. Captured telemetry, the collector binary, and your
.envare all kept off the machine that runs this tool and out of the package.
For engineers (technical appendix)
Input shape: OTLP/JSON —resourceMetrics[].scopeMetrics[].metrics[]. Two metrics matter: claude_code.token.usage (one datapoint per type in input/output/cacheRead/cacheCreation) and claude_code.cost.usage (USD).
Grouping key: (user.email, model, session.id) → one MarginFront record per group.
Token mapping: input→inputTokens, output→outputTokens, cacheRead→cacheReadTokens, cacheCreation→cacheWriteTokens (Anthropic’s cache_creation_input_tokens). With --fold-cache, cache tokens are added into inputTokens instead and the typed fields are omitted (no double count).
Temporality: Claude Code emits cumulative counters. The collector converts them to deltas; the forwarder trusts each line is already an increment.
Ingest: POST https://api.marginfront.com/v1/sdk/usage/record, headers Content-Type: application/json and x-api-key: <key> (not Bearer). Body envelope { records: [...] }. The endpoint auto-creates the customer (by customerExternalId) and agent (by agentCode) on first POST, and resolves your org from the API key (the body can’t override it).
