Local, privacy-first mission control for Claude Code
See your live agents, replay any session trace, and know exactly what every token costs β across every workspace, all on your own machine.
A self-hosted observability & cost dashboard for the Claude Code CLI β token usage, spend, budgets, live agent monitoring, and full transcript replay.
Claude Code writes a detailed JSONL transcript for every session under ~/.claude/projects. Observatory reads those files locally and turns them into a real-time dashboard: which agents are running right now, what they're doing, what they've cost, and where your tokens go. Nothing is uploaded β your code and prompts never leave the machine.
Why? Once you run Claude Code across many repos, worktrees, and parallel agents, the terminal can't tell you the whole story: Is something stuck? Which session is burning money? How much did this month cost? Which model and which workspace dominate my spend? Observatory answers all of that from data you already have on disk.
- Features
- Screenshots
- Quick start
- Try it with demo data
- Privacy
- Configuration
- How "live" is detected
- Notes on the data model
- Architecture
- Contributing
- License
- π’ Now β a global live view of every workspace: active sessions as glowing agent cards (current activity, live token/cost counters, elapsed time), a Needs you lane (waiting on you Β· permission prompt Β· stalled tool Β· API error), a KPI strip (active agents, spend today/month, total tokens, cache savings), a recent-activity feed, and a spend sparkline.
- ποΈ Workspaces β switch between projects (
βK), with git worktrees grouped under their parent. Per-workspace totals, a sessions table, worktree breakdown, and monthly budget bars. - π¬ Session replay β open any session for the full transcript (user / thinking / tool calls + results / nested subagents) with per-turn token + cost chips, a files-touched panel, and a replay scrubber (play/pause, 0.5Γβ4Γ) that reveals the run over time with a cumulative burn readout.
- πΈ Tokenomics β cost over time, cost by model (donut) and by workspace (bars), token-mix area chart, cache-savings, cost-per-session, and your most expensive sessions. Export to CSV.
- π Timeline β a concurrency Gantt of session lifespans: peak parallelism, overlaps, and how your day actually unfolded.
- π©Ί Anomaly detection β automatic flags for runaway tool loops, context-compaction storms, and tool-error spikes.
- ποΈ Storage β disk usage per workspace/session, with safe cleanup of old transcripts.
- βοΈ Settings β editable model pricing and per-workspace monthly budgets.
| Workspaces | Tokenomics |
|---|---|
![]() |
![]() |
| Session replay | Timeline |
|---|---|
![]() |
![]() |
Requirements: Node.js 18+ and pnpm. You'll want some existing Claude Code history in ~/.claude/projects (or generate a demo dataset).
git clone https://github.com/vladsawyer/claude-code-observatory.git
cd claude-code-observatory
pnpm install
pnpm dev # server on :5274, web on :5273Open http://localhost:5273.
Other scripts:
pnpm build # production web bundle
pnpm test # server unit tests (parser + cost engine)No Claude Code history yet β or want clean data for a screenshot? Generate a realistic synthetic ~/.claude/projects tree (fictional English projects, ~6 weeks of activity, live agents, subagents, and anomalies β all deterministic):
node scripts/seed-demo.mjs # writes ./.demo
OBSERVATORY_CONFIG="$PWD/.demo/observatory.config.json" pnpm devThe seed never touches your real ~/.claude/projects.
Observatory is local-first by design:
- It only ever reads
~/.claude/projects/**/*.jsonlfrom your own disk. - There is no network egress, no telemetry, no account β your code, prompts, and transcripts never leave the machine.
- The server and web app run entirely on
localhost.
Pricing, budgets, and the live-detection threshold live in observatory.config.json (created on first save, gitignored) and are editable from the Settings screen.
- Pricing is matched by longest model-id prefix (USD per million tokens). Cache multipliers: write-5m = 1.25Γ input, write-1h = 2Γ input, read = 0.1Γ input. Opus 4.x defaults to $5/$25 (the Opus 4.5+ tier); edit it if your runs were billed at the older $15/$75 tier.
OBSERVATORY_PROJECTS_DIRoverrides the transcripts directory.OBSERVATORY_SERVER_PORToverrides the API port (default5274).OBSERVATORY_CONFIGpoints the server at an alternate config file (used by the demo seed).
A session's status comes from its file mtime + the tail of its events:
running (fresh + generating/awaiting a tool) Β· idle (just finished, awaiting you) Β·
stalled (a tool call never returned) Β· error (last event was an API error) Β·
done (completed and quiet). The watcher pushes updates over SSE; time-based
transitions (running β idle β done) are re-evaluated on a heartbeat.
- Token usage is deduplicated by
message.idβ one API message is split across several JSONL lines with identical usage, so naive summing triple-counts. - Subagents (the
Agent/Tasktool) are stored as separate files under<session>/subagents/and are nested under their parent in the transcript. <synthetic>model turns are counted in tokens but cost $0.- Malformed / truncated trailing lines (common while a session is being written) are skipped and surfaced as a count.
A small pnpm monorepo:
| Package | Stack | Responsibility |
|---|---|---|
server/ |
Node Β· Express Β· chokidar | Streams & parses .jsonl transcripts, caches aggregates by mtime+size, computes cost, and pushes live updates over SSE. |
web/ |
Vite Β· React Β· TypeScript Β· Tailwind v4 Β· shadcn/ui Β· Recharts | The dashboard UI. |
shared/ |
TypeScript | The contract (types) shared by both. |
Contributions are welcome! See CONTRIBUTING.md for setup, tests, and the PR workflow. Found a bug or have an idea? Open an issue.
MIT Β© Vlad Sawyer




