SuperBased

The exact tokens your AI provider billed you — cache splits, reasoning tokens, long-context surcharges — reconciled across 29 coding tools, entirely on your own machine. Nothing you build here ever leaves your machine unless you opt a node into it.

npm License: Apache 2.0 Platforms: Linux • macOS • Windows Go 1.22+ ⭐ Star this repo

If SuperBased catches something useful in your next bill, a star helps other people looking for the same thing find it.

Try it in one command

npx @superbased/observer

On a fresh machine — no ~/.observer/observer.db, no ~/.observer/config.toml — this scans every AI coding tool's own local session files into a throwaway temp database, prints one cost table grouped by tool and model, and deletes the database again before it exits. It's local-only: zero network calls, and nothing is written outside that temp directory (foreign-mount adapter mirrors — e.g. WSL reading a Windows-side tool store — are redirected there too; pricing is embedded in the binary, not fetched at runtime).

Already have SuperBased set up (or want the explicit form)? Run observer usage. Bare observer only runs the one-shot on a machine with no local SuperBased state at all — otherwise it prints the usual welcome screen (OBSERVER_ONESHOT=off to always get the welcome screen). This is the zero-config sibling of observer cost: usage rolls up whatever session files it finds into a throwaway DB; cost queries the DB you've actually been capturing into with observer scan / observer start — including any proxy-accurate turns. Full reference: docs/one-shot-usage-report.md.


Table of contents


What it is in 30 seconds

A single local Go binary built on three things a hosted usage console can't give you, in order of how much they matter:

  1. Proxy-accurate, cross-vendor cost attribution. An optional API reverse proxy reads the token counts your provider actually billed — net input, 5m/1h cache read/write splits, reasoning tokens, long-context repricing — the same math your invoice uses, not a JSONL-derived estimate. It's accurate enough that it caught its own bug: a Codex reasoning-token double-billing regression SuperBased found and back-corrected months of history for (migration 058, shipped v1.18.0) — the kind of self-audit a vendor console has no incentive to run against itself.
  2. Local-first, by construction. The watcher, proxy, dashboard, MCP server, and CLI make zero outbound calls on your behalf — no telemetry, no analytics, no remote reporting. Everything SuperBased captures is written to your own database and stays there. Full details: PRIVACY.md.
  3. One capture layer, every tool you actually use. 33 adapters — Claude Code, Codex, Cursor, Cline + Cline CLI, GitHub Copilot + Copilot CLI, Gemini CLI, OpenCode, Google Antigravity, Cowork, Hermes Agent, Kilo Code, Aider, Goose, Devin, Qoder, Crush, Grok, Kiro CLI, Kimi Code, Qwen Code, OpenClaw, Pi, Factory Droid, Open Interpreter, Command Code, and more — parsed into one normalized schema, queryable from a local dashboard, an MCP server (so the tools themselves can query it), and a CLI. (Five more *-web adapters cover ChatGPT/Claude.ai/Gemini/Copilot/Perplexity in the browser — those need the browser-capture extension, which today only installs unpacked; every tool listed above works out of the box.) Twenty-two of those are also full CLI launchers you can run as real terminals — from the dashboard or your own shell, captured through the same pipeline — see Terminals below.

Raw token counting across tools is table stakes here — it's the substrate the accurate-cost layer above is built on, not the pitch.

One local binary. SuperBased captures, normalizes, and analyzes AI coding tool activity on your own machine: proxy-accurate cost, compression, cache tracking, and session handoff for every AI coding tool you run.

It answers questions like:

  • Where did this week's $147 Claude bill come from — which projects, models, sessions, tool calls? And is that number the same one my provider's invoice would show?
  • Did I spend more on Opus or Sonnet? Are my Sonnet sessions hitting the long-context tier and getting repriced at 2×?
  • How much did I waste re-reading files that hadn't changed since the last read in the same session?
  • Could that trivial Opus session have been done by Sonnet for 1/5 the cost?
  • Across Claude Code, Cursor, and Codex working in the same repo, what files are touched by all three? Where are they stepping on each other?
  • What will my next message roughly cost — and how much of my 5-hour and weekly subscription limit is left before I hit it?
  • Where did my own OpenTelemetry-instrumented agent spend its tokens — with the proxy's exact per-span cost where it routed through the proxy?

Install

Pick whichever package manager fits your environment — npm and PyPI ship the same prebuilt binary from the same v* tag, version numbers kept in lock-step.

Via VS Code (Marketplace or Open VSX)

code --install-extension superbased.superbased-observer

The VS Code extension bundles the observer binary, lifts the dashboard / sidebar / status bar / file decorations into the editor, and contributes a terminal profile that pre-exports the proxy env vars so AI CLIs launched from it route through observer automatically. Cursor, VSCodium, and Windsurf install the same VSIX via Open VSX.

After install, VS Code's Get Started page surfaces an in-editor walkthrough; the long-form user guide lives at docs/vscode-extension-user-guide.md and the command + settings reference is at docs/vscode-extension.md.

Via npm (recommended for Node users)

npm install -g @superbased/observer
observer --version

Via pip / uv / pipx (recommended for Python users)

pip install superbased-observer            # plain pip
uv tool install superbased-observer        # uv (isolated env, fastest)
pipx install superbased-observer           # pipx (isolated env)
observer --version

Wheels ship for manylinux2014_{x86_64,aarch64}, macosx_*_{x86_64,arm64}, and win_amd64. uv tool and pipx keep the install isolated from your project's Python env — generally what you want for a CLI tool.

Via go install (latest main, builds locally)

go install github.com/marmutapp/superbased-observer/cmd/observer@latest
observer --version

Via direct download (pre-built per-platform archive)

Each tagged release attaches per-platform archives to the Releases page, verifiable against the published SHA256SUMS:

Asset Platform Contents
observer-vX.Y.Z-linux-x64.tar.gz Linux x86_64 observer + antigravity-bridge.exe (for WSL2)
observer-vX.Y.Z-linux-arm64.tar.gz Linux arm64 observer + antigravity-bridge.exe (for WSL2)
observer-vX.Y.Z-darwin-x64.tar.gz macOS Intel observer
observer-vX.Y.Z-darwin-arm64.tar.gz macOS Apple Silicon observer
observer-vX.Y.Z-win32-x64.zip Windows x86_64 observer.exe
SHA256SUMS sha256 of all five archives
# Linux x64 example — substitute your platform + version.
VERSION=v1.6.21
PLAT=linux-x64
curl -L -O https://github.com/superbasedapp/observer/releases/download/$VERSION/observer-$VERSION-$PLAT.tar.gz
curl -L -O https://github.com/superbasedapp/observer/releases/download/$VERSION/SHA256SUMS
shasum -a 256 -c SHA256SUMS --ignore-missing
tar -xzf observer-$VERSION-$PLAT.tar.gz
./observer --version

The binary is pure Go — no CGO, no external runtime dependencies. SQLite storage is pure-Go via modernc.org/sqlite. Single static binary; scp it anywhere it runs. Same artifacts ship to npm and to the Releases page (build-once-ship-everywhere CI), so the npm and direct-download paths produce byte-identical binaries.


First-run walkthrough

# 1. Start everything: proxy + watcher + dashboard in one foreground
#    process (ctrl-c to stop). Hooks auto-register for every detected
#    AI tool, and the dashboard opens in your browser
#    (http://localhost:8081; suppress with --no-open).
observer start

# 2. (another shell) Backfill from existing session logs so the
#    dashboard has history immediately rather than starting empty.
observer scan

From here the dashboard drives. On an empty database the Overview tab leads with a three-step onboarding checklist — and a demo mode offer if you'd rather look around first: one click seeds a temporary synthetic dataset so every chart renders with realistic data (your real observer.db is never read or written; a persistent banner marks demo state and one click clears it). The two checklist steps that matter:

  1. Route your AI tool through the proxy — accurate token counts and conversation compression both need it. On the Compression tab's Proxy banner, click your tool's status pill, then Route through the observer proxy…: the button previews the exact file change (Claude Code: an env.ANTHROPIC_BASE_URL entry in ~/.claude/settings.json; Codex: an observer model provider in ~/.codex/config.toml) and writes only on confirm. Durable — every later session routes automatically. The same section of the Settings → Connected tools panel offers a per-tool setup wizard (hooks / MCP / routing, one consent click per write) and a Launch button. Prefer the terminal? The same routing ships as observer init, as session-scoped wrappers (observer claude / observer codex — no config writes), or as a plain export ANTHROPIC_BASE_URL=http://localhost:8820 / OPENAI_BASE_URL=http://localhost:8820/v1.
  2. Use your AI tool as normal. The checklist tracks the first captured session; cost, compression, and cache numbers populate within minutes of real activity.

Optional — MCP registration. observer init additionally writes MCP server entries (and hook entries) into each AI tool's own config files (~/.claude/settings.json, ~/.claude.json, ~/.cursor/mcp.json, ~/.codex/config.toml, …). Hooks default ON, MCP defaults ON; opt out per-side with --skip-hooks / --skip-mcp. Idempotent. observer start alone never registers the MCP server — MCP wiring is explicit-only, because it costs ~1,800 schema tokens per AI-client turn.

If you route Claude Code while MCP servers are registered, set ENABLE_TOOL_SEARCH=true in the same environment. Claude Code's SDK disables ToolSearch:optimistic deferred MCP loading whenever ANTHROPIC_BASE_URL is set, eagerly inlining all 17 observer MCP tool schemas (plus any Google MCPs) into every request prefix — ~+21K tokens/turn. The override re-enables lazy loading; observer's proxy forwards tool_reference blocks byte-identically, satisfying the SDK's documented safety condition. Empirical: with the override + v1.7.23 defaults, the proxy is −6.9% mean cost vs no-proxy on Claude Code's reference rig (n=8 lumen refactor task, V7-22 binary). Without it, ~+9% per-turn overhead. See superbased.app/docs/connect/claude-code for the full picture.

The proxy logs every turn with the exact token counts the provider returned, including cache-tier breakdowns (5m vs 1h ephemeral) and 1h surcharges that JSONL adapters can't always disambiguate.

Verifying the install

observer doctor          # health checks: DB integrity, hook
                         # registration, MCP entries, pid bridge
observer status          # row counts + recent activity
observer tail            # live-stream captured actions

Dashboard tour

observer start opens the dashboard automatically on interactive launches (suppress with --no-open; default URL http://localhost:8081). Twenty-one tabs in four nav groups (Monitor / Analyze / Optimize / Configure), each designed around one question — the tour below covers the core surfaces; Live (recent sessions with a real-time action feed), Search (full-text over captured tool outputs), Privacy (capture map + scrub tester), and the opt-in Terminals page (covered in Terminals below) and Remote page (covered under Remote & mobile access below) are self-explanatory once you're in, and the Suggestions tab's advisor nudges and the Patterns tab's derived habits are covered in their own docs. Evaluating without data? Start demo mode from the empty Overview — synthetic dataset in a temp DB, real observer.db untouched, one click to clear.

Overview — what's been happening?

Four headline KPI tiles (sessions, API turns, token rows, stale re-reads — each filterable by the global Window / Tool / Project chips), cost-over-time stacked area split by billable token bucket, actions-over-time stacked by tool, top models by token volume, top tools by action count.

Sessions — what did each run actually do?

One row per session with cost, token totals (input / cache R / cache W / output), elapsed time, action count, and a model badge. Quality / Errors / Redundancy scoring columns light up once observer score has run. Click a row to open the per-session slide-over (shown below in Session detail).

Actions — the firehose, filtered

Every recorded tool call, normalized across adapters. Filter by action type (28 categories), tool, effort, permission. Each row exposes its target + status + raw-tool source + truncated content preview; click to expand to the full event with error context.

Cost — per-model breakdown with the right math

Eight KPI tiles across the billable token buckets (Net Input, Cache Read, Cache Write 5m, Cache Write 1h, Output, Reasoning, plus total USD and turn count). Per-model table shows the full breakdown including reasoning tokens (billed at output rate) and long-context surcharges (Sonnet 1M, gpt-5 >272K, Gemini 2.5 Pro >200K). Hover any column header for its definition + formula.

Analysis — spending insights & efficiency signals

Twelve KPI tiles comparing this period to prior: spend Δ%, MTD vs budget with projection bar, $/M output rate, cache savings + cache efficacy %, high-context turn count, $/turn, burn rate ($/active hour), top model concentration %, Discovery waste $, sessions total. Daily-spend stacked bars with Model / Project / Tool dimension toggle, hour-of-day heatmap, period-over-period movers (top increases / decreases / new entrants), and model right-sizing hints (trivial Opus sessions that could have used Sonnet).

Tools — per-AI-client breakdown

Four KPIs (total actions, distinct tools, overall success rate, busiest tool), activity-over-time stacked area, and per-tool action-type-mix horizontal bars (100% normalized, colored by action category). Surfaces which AI client owned which kind of work.

Compression — what the proxy saved

Five KPIs: total $ saved (priced at your input rate), tokens saved, bytes trimmed, turns compressed. Savings-per-day stacked bar by mechanism (drop, trim, summary), savings-by-mechanism donut, recent events table with original→compressed→saved + dollar impact per event.

Cache — prompt-cache observation & forecasting

Headline cache-ratio hero (cache_read ÷ cache_write tokens) and three sibling KPIs: Cache read, Cache write, and Avoidable spend / Event count. Avoidable spend renders in warn tone — it's the dollar overhead of rewrites that wouldn't have happened on a perfectly cache-friendly session. By-model and By-project tables with R%/W% mix bars + absolute Read/Write/Events + cache Ratio + Avoidable $. Proportional Top causes histogram (suffix_growth + hit dominate a healthy session; real invalidations render in warn tone; tools_changed on MCP toggles renders neutral). Worst sessions table sorted by rewrite count; click-through opens the per-turn Cache panel.

How it's captured. Two paths feed the same engine, both writing to NODE-LOCAL cache_segments / cache_entries / cache_events tables (migrations 036+037, node-local only, never leaving the machine):

  • Tier-1 (proxy) — point your AI client at 127.0.0.1:8820 and the cachetrack engine reads each turn's cache_read_input_tokens + cache_creation_input_tokens envelope live. Default capture path for Claude Code.
  • Tier-2 (transcript watcher) — feeds the same engine from on-disk claude-code JSONL transcripts for sessions that didn't route through the proxy. Run observer backfill --cache-rescan to retrofit history.

Enable / disable. Default-on per spec §11 (the loader merges [cachetrack].enabled = true if the section is absent). To turn off: [cachetrack].enabled = false in ~/.observer/config.toml, then restart observer start. Inspect engine health with observer cache-health --json. Operator reference: superbased.app/docs/guides/cache-tracking (or docs/cache-tracking.md in the repo).

Suggestions — the advisor's quantified nudges

Default-on, fully local suggestions engine (zero LLM cost, zero network): 19 detectors turn the window's captured activity into ranked, dollar- or minute-quantified recommendations — session balloons, idle re-cache, long-context tier crossings, trivial sessions on expensive models, cache hit-rate / cache-write waste / prefix thrash, read-heavy expensive-model sessions, effort overprovisioning, fast-tier premium, unrecovered failures, quality regressions, MCP schema overhead, compression off, capture without proxy routing, cross-session stale reads, web-search spend, spend spikes, plus a posture nudge (guard observing idle, pointing at the surface that owns the workflow). Every card carries its arithmetic ("show math"), a confidence score, snooze/dismiss with a 7-day cooldown, and — where a dashboard control can fix the finding — a one-click action that navigates to the right surface (writes stay behind that surface's own consent flow). CLI twin: observer advise. Config: Settings → Advisor ([advisor] — evidence window, confidence/savings floors, opt-in ≤400-token session-start digest).

Discovery — the waste detector

Waste $ hero (stale-read tokens × your blended input rate). Four KPIs: stale re-reads count, tokens wasted, affected files, repeated commands. Top files re-read table with cross-thread highlighting (when the same file was re-read from a subagent that didn't see the parent's read). Repeated-commands table with no-change-rerun detection.

Security — the guard, operable end to end

Posture tiles + a filterable verdict timeline (rule IDs resolve to their full definitions), then the routine workflows: a consent-gated mode control that shows the simulate evidence before you flip enforce, the enforce-readiness replay over your real history, the approvals register (scoped, expiring — live immediately), a lint-gated user-policy editor with .bak undo, budget guardrails suggested from your own observed spend with a daily burn-down meter, MCP pin approvals, and one-click compliance evidence downloads.

Settings — every config knob, editable

Schema-driven forms for every config section — Watcher, Freshness, Retention, Hooks, Proxy, Compression, Intelligence, Advisor, Cache tracking, Secrets scrubbing, MCP, Profiles, Org share, OTel — with honest reload semantics per section: pricing and profile changes apply hot, MCP applies to the next AI session, restart-gated sections raise a persistent restart-pending banner that names the exact command and clears only when the daemon actually restarts. Alongside the forms: a Connected tools panel (per-tool status matrix, consent-gated setup wizard, Launch button), a Health panel (the observer doctor checks + recent failures), the Backfill panel (every mode click-to-run with streamed output + full rescan), a Storage panel (per-table DB size breakdown with index/FTS bytes folded in, vacuum + online backup as click-to-run jobs, documented manual restore — CLI twin observer db stats|vacuum|backup), and a config-file card with one-click .bak restore. 182 baked-in default models; pricing "Override" prompts auto-fill from the default.

Live — what's running right now

Every session with activity in the last 15 minutes, refreshing on a 5-second tick: lifetime cost, tokens, turns, and a streaming action feed per session. The fastest way to confirm the proxy is capturing while you work.

Session detail — drill into one session

Click any session row → slide-over with an action-type breakdown donut, a token-bucket bar (net input / cache R / cache W / output), and the models used. It also carries the next-message cost predictor (a low / typical / high band over the session's likely turn fan-out) and, for proxied subscription sessions, the 5-hour / weekly limit gauge read from the provider's own rate-limit headers.

Scroll down for the full per-message timeline — every upstream API turn with its model, token buckets, per-turn cost, and the tool calls nested inside it, each row expandable. The same panel surfaces from Actions when you click a session pill.

Remote & mobile access

The dashboard reads fine from a phone (the layout adapts to small screens), and you can drive a node from another device over your tailnet — nothing is exposed to the public internet. Pair a second device from the Remote tab, then view sessions, cost, and the live feed from anywhere on your tailnet. Bind the dashboard to a tailnet interface with [dashboard].addr (or the OBSERVER_DASHBOARD_ADDR env override) instead of the default loopback.

The same tailnet pairing is also what lets a remote device join a live terminal, not just view charts — the launch dock, joinable sessions, Session Cockpit, and the execute-is-gated posture (default off, [remote].allow_terminal) are covered in Terminals below. Full remote setup: docs/remote-access.md.


Terminals — launch, join, and track your AI CLIs

The dashboard doesn't just watch your AI tools after the fact — it can launch them, and any paired device can join a session that's already running.

  • Launch from the dashboard or any shell. All 22 CLI launchers (claude, codex, opencode, cursor, copilot-cli, kilo, cline-cli, hermes, gemini, openclaw, pi, antigravity, qwen, kiro, grok, kimi, devin, qoder, goose, droid, open-interpreter, command-code) launch as real PTY terminals from the dashboard ("Launch here") or via observer <verb>; Linux/macOS + native Windows (ConPTY, Win10 1809+). Guided one-click install when the tool binary isn't found.
  • Attach-by-default (v1.25.0). observer <verb> runs daemon-owned so the dashboard can join; the native terminal stays fully interactive as seat #1. --no-attach for a bare run; scripted/piped invocations never attach. The attach client also forwards your shell's values for each tool's registry-documented credential env keys (claude-code, codex, hermes, pi, copilot-cli, gemini-cli, grok, and others with registry-documented key envs) via [terminal.attach].forward_auth_env (default true), so a shell-exported API key works exactly as it would bare. Honest caveat: tools without a registry-documented credential env, and dashboard-launched terminals, still see only the daemon's env (config-file/OAuth auth is unaffected; export where observer start runs, or use --no-attach).
  • Jump in from anywhere. Every live daemon-owned terminal is joinable from any dashboard tab — local or paired remote — as an extra seat. Many read-only viewers (cap 8), exactly one writer; control moves seamlessly native → local dashboard → remote dashboard by taking the writer lease (type in the native terminal to reclaim it; remote takeover is available only to fully-authenticated paired tailnet devices, and the seat that loses the lease stays read-only with take-back available). Fresh runs link to their observer session in roughly 10–30 seconds.
  • Per-terminal Files & Git panels. Read-only file tree + viewer rooted at the terminal's project root; a Git panel with branch/upstream/ahead-behind/status plus a 100-commit log; copy path / paste into the terminal. Read-only v1 — no edits and no git mutations from the panel.
  • Session Cockpit. A draggable live panel on any AI-tool terminal: tokens/sec (measured vs estimated badge), cost with AI/tool split, the next-message cost band, context fill vs the model's budget, the 5h/7d rate-limit gauge (proxy-routed sessions), prompt-cache expiry countdowns, CPU/mem/disk plus the spawned process tree, and the last five turns deep-linked to session detail.
  • Workspace grid. Up to 9 live terminal tiles at once, drag to resize, layouts persist server-side; read-only when viewed from a remote device.
  • Restarts & continuity. On a daemon restart, 21 of the 22 launchers auto-resume the same transcript (native resume) — openclaw is the sole holdout, because its resume is picker-only. Fork any tool's session forward with observer <verb> --continue-from <id> — a new session id seeded with a distilled handover as the first prompt.
  • Remote posture. Remote access is opt-in, tailnet-only (Tailscale serve), off by default; viewing and execute are separate tiers, and execute is default-off. See Remote & mobile access above, plus docs/remote-access.md and docs/session-handoff.md.

MCP server — 25 cross-tool intelligence calls

Opt-in. The MCP server is not active until you run observer init (or observer init --claude-code / --cursor / --codex). That command writes entries pointing at the observer binary into each AI tool's own MCP config file (~/.claude.json, ~/.cursor/mcp.json, ~/.codex/config.toml). The MCP server then runs as a stdio subprocess spawned by your AI tool — its lifecycle matches the AI tool's, and it never opens a network port. observer start alone does NOT register or launch the MCP server; it can be skipped entirely via observer init --skip-mcp if you want hooks-only capture.

Once registered, every connected AI tool can query the observer over MCP/stdio: 21 tools are always registered, and 4 more register conditionally (only when the capability they depend on — the proxy stash, or the codeintel index — is actually configured):

MCP tool What it answers
check_file_freshness Has this file changed since I last read it?
check_command_freshness Did this exact command already run? With what result?
get_file_history Every read/edit of this file across every tool + session (with codeintel enrichment when available).
get_session_summary What did session X actually do? AI-generated 2–4 sentence summaries.
get_session_recovery_context For resuming an interrupted session.
get_project_patterns Derived behaviours: hot files, co-changes, edit→test pairs.
get_last_test_result Without re-running.
get_failure_context Error correlation + retry detection.
get_action_details The raw row, scrubbed of secrets.
get_cost_summary Per-window spend rollup.
get_redundancy_report What would Discovery flag for this project?
search_symbols Fuzzy symbol search across the project's codeintel index (Tier-C).
list_actions_around Chronological ±N actions around an action_id.
search_past_outputs Full-text search of past tool-call outputs (FTS5 over excerpts).
get_output_composition Code vs. explanation split of a session's output, by bytes, with the code:explanation ratio and languages used.
get_suggestions Top dollar/time-quantified cost & quality suggestions from the local advisor.
cache_status Live prompt-cache health: which caches are warm, expiring, or cold, with value-at-risk.
get_model_recommendation Evidence-backed model suggestion per turn-kind, from the local Model Value Report.
get_routing_status Model-routing layer state: phase, available policy templates, tier-table size, decision-log counters.
continue_session A distilled, scrubbed handover of a session from another AI tool, so you can continue its work here.
get_session_message One full, un-excerpted message from a session's transcript — pulls the complete body a handover excerpt truncated.
get_file (conditional) The file's current bytes (or at a given commit), with path-safety gate + audit.
get_symbols (conditional) Resolve symbol name + range to file path + body (codeintel-backed).
get_relations (conditional) Codeintel BFS — who calls / is called by this symbol.
retrieve_stashed (conditional) Pulls original bytes of a tool_result the proxy stashed (only registered when CCR is enabled).

Operator note for Claude Code via observer's proxy. When you set ANTHROPIC_BASE_URL=http://localhost:8820, Claude Code's SDK disables ToolSearch:optimistic deferred MCP loading — observer's tool schemas (plus any Google MCPs you've registered) end up eagerly inlined into every request prefix, ~+21K tokens/turn. Set ENABLE_TOOL_SEARCH=true in the same shell to recover lazy loading; observer's proxy forwards tool_reference blocks byte-identically, satisfying the SDK's documented safety condition for the override. See superbased.app/docs/connect/claude-code for the full picture.

Knowledge captured from one tool benefits all the others working on the same project — data is organized by git root, not by tool. A read by Claude Code becomes a freshness signal for Codex; a Cursor compaction is visible from Cline.


Integrations — the stable contract to build against

The MCP server is the supported integration surface for third-party tooling — the one place observer publishes a stability promise you can build against: three published tiers (stable / conditional / experimental), a tier for every one of the 25 tools, and five server-level invariants (a single pretty-JSON text block per call, in-band isError, silent limit clamping, alphabetical tools/list, and the pinned server name observer).

The contract: docs/mcp-contract.md — what each tier promises under semver, and what is explicitly out of contract (the dashboard HTTP API and the SQLite schema are both internal and unversioned; integrate over MCP instead).

Machine-readable, diffable in CI:

observer contract --json   # {"contract_version":1,"mcp":{…},"adapters":[…]}

The tiers come from one Go table shared by the doc and the emitter, and conformance tests fail the build if a stable tool is renamed or if a newly registered tool ships unlisted — so the contract can't silently drift from the binary.

Wiring the MCP server by hand

observer init --claude-code (or --cursor / --codex, or bare observer init) writes the entry for you. For a client observer doesn't know about, register it yourself — it's a plain stdio subprocess with no network port:

{
  "mcpServers": {
    "observer": {
      "command": "/absolute/path/to/observer",
      "args": ["serve"]
    }
  }
}

Then call it like any MCP server:

// tools/call
{ "name": "get_cost_summary", "arguments": { "group_by": "model", "days": 7 } }

The server reads ~/.observer/config.toml unless you pass --config <path>. Its lifecycle matches the AI tool that spawned it.

Community integrations

None listed yet — this list is PR-curated and starts empty rather than seeded with aspirational entries.

To add yours, open a PR appending one row to the table below. Criteria:

  • Verifiable artifact. A public repo, package, or extension anyone can install and run. Not a blog post, not a screenshot, not a waitlist.
  • Actually uses the contract. It talks to the MCP server (or consumes observer contract --json). An integration built on the dashboard HTTP API or by reading observer.db directly can't be listed — those surfaces are internal and will break you.
  • Honesty rules apply, the same ones this repo holds itself to: claims in your description must be things a reader can check. No unmeasured savings percentages, no capability the artifact doesn't have today, and "planned" is not "does".
  • One row, plain description. Name, link, one sentence on what it does. Maintenance status is welcome; marketing copy isn't.
Integration What it does Maintainer
(none yet — open a PR)

API proxy — accurate tokens, compression, stash

The proxy is the home of three features that only exist when your AI client routes through it. None of them run on the watcher / observer start ingestion path — compression and stash live in the request path because that's the only place where bytes can be rewritten before they reach the upstream provider.

When you point your AI tool at http://localhost:8820, the proxy:

  1. Forwards your request to your chosen upstream (Anthropic or OpenAI). The destination is the same provider URL your AI client would have called directly; no data leaves your machine that wasn't already going to that provider. Your API key is yours — the proxy reads it from the inflight headers, never stores it.
  2. Records the exact token counts the provider returned (cache 5m vs 1h split, long-context tier triggers, reasoning tokens) into the api_turns table — more accurate than parsing the JSONL the AI tool wrote.
  3. Compresses the conversation before forwarding (importance-scored, prefix-stable for cache alignment) — the biggest lever for keeping long sessions inside rate-limit windows. Opt-in: flip [compression.conversation].enabled = true (or the Settings → Compression toggle); once enabled, tuned per-tool profiles apply automatically (see below), with the safe per-type set (compress_types = ["json","logs","code"]) on Anthropic traffic. Compressed events land in the compression_events table and surface on the Compression dashboard tab. Empirical on Claude Code lumen rig (n=8, V7-22): −6.9% mean cost vs no-proxy, CV 7.6%, zero tail outliers.
  4. Stashes large tool outputs the compressor hides, so the originals stay retrievable via the retrieve_stashed MCP tool (only registered when stash is configured). Off by default — stash markers break Anthropic's prefix cache (V7-25 n=1 measurement: +25% cost, cache_creation_input_tokens doubled). Operators who want stash on a workload should A/B before committing.

Three compression layers, each independently toggleable:

  • Shell output filters — RTK-style truncation of large bash / git / go test / docker / kubectl / cargo / pytest outputs inline before they hit the LLM context. Runs on hook / observer run paths; does not require the proxy.
  • Tool output indexing — every tool call's output indexed into FTS5; large outputs trimmed to a 2KB exc