# pi-meter

> Know what your coding agents cost — and stay on budget.

**pi-meter** tracks every LLM call your AI coding agent makes, aggregates spend across sessions,
days, and models, and keeps you on budget with three escalating responses: it **warns** as you
approach a limit, **auto-downshifts** to a cheaper model when you go over, and can **hard cut
off** — refusing prompts and blocking tools — when you blow a hard cap.

One core engine, four ways to run it: a **CLI**, an **MCP server**, a **Claude/Cursor skill**,
and a **[pi](https://pi.dev) extension**.

[![npm](https://img.shields.io/npm/v/pi-meter?color=cb3837&logo=npm)](https://www.npmjs.com/package/pi-meter)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
![node](https://img.shields.io/badge/node-%3E%3D20-brightgreen)

---

## Why

LLM coding agents burn money quietly — a long session on a frontier model can run into real
dollars before you notice. pi-meter gives you:

- a portable **ledger** of every call (model, tokens, cost) you can grep,
- **budgets** with three responses — warn → downshift → cut off,
- and zero lock-in: plain JSONL + a JSON config file. No account, no daemon, no telemetry.

## Features

- **Spend tracking** — per call, per day, per month, all-time, per model, and per session.
- **Cost estimates** — a built-in price table for Claude / GPT / Gemini, fully overridable; uses
  the harness's own reported cost when it's available.
- **Soft budgets → auto-downshift** — over budget, pi-meter switches the agent to a cheaper model
  you choose.
- **Hard limits → cutoff** — past a hard cap, pi-meter refuses new prompts and blocks tool calls,
  with a one-command override.
- **Four surfaces** — CLI, MCP server, Claude/Cursor skill, and pi extension, all on one core.
- **Just files** — the ledger is JSONL at `~/.pi-meter/usage.jsonl`; config is a `pi-meter.json`.

## Install

```bash
# CLI (global) — installs the `pimeter` command
npm install -g pi-meter

# or run without installing
npx pi-meter report
```

For the **pi** harness (installs the extension + skill):

```bash
pi install npm:pi-meter
# or from the repo:
pi install git:github.com/vaibhav-patel/pi-meter
```

## Quick start

```bash
# record a call (the pi extension / MCP server usually does this for you)
pimeter record --model claude-opus-4-8 --input 12000 --output 3000 --label "refactor"

# where's the money going?
pimeter report

# am I within budget?
pimeter status

# set a soft budget (warn + downshift) and a hard cap (cutoff)
pimeter budget    --daily 5  --monthly 100
pimeter hardlimit --daily 10 --total 500
```

## How it works

pi-meter has one dependency-free core behind every surface:

1. **Record** — each model call is priced and appended to the ledger.
2. **Aggregate** — spend is summed by day / month / total / model / session.
3. **Enforce** — spend is compared to your `budget` (soft) and `hardLimit` (hard):
   - **soft budget exceeded** → warn and **auto-downshift** to a cheaper model;
   - **hard limit exceeded** → **cut off**: refuse new prompts and block tool calls.

### The ledger

One JSONL line per call at `~/.pi-meter/usage.jsonl` (override with `storePath`):

```json
{"ts":"2026-06-18T09:30:00Z","model":"claude-opus-4-8","provider":"anthropic","inputTokens":12000,"outputTokens":3000,"costUsd":0.225,"sessionId":"a1b2","label":"refactor"}
```

Greppable, portable, and yours — delete lines to forget, copy it elsewhere to analyze.

## Configuration — `pi-meter.json`

Drop a `pi-meter.json` in your project root (the folder you run the agent from):

```jsonc
{
  "budget":    { "daily": 5, "monthly": 100, "session": 2 },   // soft  -> auto-downshift
  "hardLimit": { "monthly": 150, "total": 500 },               // hard  -> cut off
  "downshift": { "claude-opus-4-8": "claude-sonnet-4-6" },     // expensive -> cheaper
  "prices":    [ { "id": "my-model", "inputPerMTok": 1.0, "outputPerMTok": 4.0 } ],
  "storePath": "~/.pi-meter/usage.jsonl"
}
```

| Field | What it does |
|-------|--------------|
| `budget` | Soft limits (USD). pi-meter warns at 80%, and at 100% **auto-downshifts** via `downshift`. |
| `hardLimit` | Hard caps (USD). Once over, the pi extension **refuses prompts and blocks tools**. |
| `downshift` | Expensive-model → cheaper-model map, used when over the soft budget. |
| `prices` | Add or override model prices (USD per 1M tokens). Wins over the built-in defaults. |
| `storePath` | Ledger location (supports a leading `~`). Defaults to `~/.pi-meter/usage.jsonl`. |

**Scopes** for both `budget` and `hardLimit`: `daily`, `monthly`, `session`, and `total` (all-time).

## CLI reference

| Command | Description |
|---------|-------------|
| `pimeter record --model <id> --input <n> --output <n>` | Record a call. Optional: `--cache-read`, `--cache-write`, `--label`, `--session`. |
| `pimeter report [--json]` | Spend: today / month / total / by model. |
| `pimeter status [--session <id>]` | Budget + hard-limit usage per scope (exits 1 if over). |
| `pimeter budget [--daily N --monthly N --session N --total N]` | Show or set the soft budget. |
| `pimeter hardlimit [--daily N --monthly N --session N --total N]` | Show or set the hard limit. |
| `pimeter models` | List known model prices. |
| `pimeter mcp` | Start the MCP server (stdio). |

## pi extension

Once installed in pi, pi-meter runs on its own:

- **Meters every turn** — reads the harness's own token usage + cost and records it.
- **Footer gauge** — shows `daily $1.20/$5.00 · monthly …` live as you work.
- **Auto-downshift** — over the soft budget, switches to your `downshift` model (once per turn).
- **Cutoff** — over the `hardLimit`, refuses new prompts and blocks tool calls.
- **Commands** — `/pimeter` shows spend + budget; `/pimeter override` lifts a hard-limit block for
  the current session.

## MCP server

`npx pi-meter mcp` starts a stdio MCP server with three tools, usable from Claude Desktop, Cursor,
or any MCP client:

| Tool | Description |
|------|-------------|
| `record_usage` | Record a model call; returns its computed cost. |
| `get_spend` | Today / month / total / by-model spend. |
| `check_budget` | Budget status per scope, whether to downshift, and a suggested cheaper model. |

Example client config:

```json
{ "mcpServers": { "pi-meter": { "command": "npx", "args": ["-y", "pi-meter", "mcp"] } } }
```

## Claude / Cursor skill

The package ships a skill at [`skills/pimeter/SKILL.md`](skills/pimeter/SKILL.md). Drop it into your
agent's skills directory (or it loads automatically when pi-meter is installed as a pi package) to
teach the agent to record usage, report cost, and decide when to switch models for cost reasons.

## Pricing note

The built-in price table is **approximate public list pricing** and **will drift** — verify and
override anything you depend on via `prices` in `pi-meter.json` (`pimeter models` prints the
defaults). When the harness reports its own cost (as pi does), pi-meter uses that instead of the
table.

## Development

```bash
npm install
npm run build      # tsc -> dist/
npm test           # node --test suite
npm run typecheck
```

## License

MIT — see [LICENSE](LICENSE).
