Installation
July 24, 2026 · View on GitHub
Distribution channels
cctally ships through three channels. They land identical functionality; pick the one that matches your environment.
Every release ships to an opt-in beta channel first and is promoted to stable once it proves out (Homebrew tracks stable only). To follow the newest builds as they land, opt in with cctally config set update.channel beta, and flip back with cctally config set update.channel stable. See Beta channel for the full behavior.
Homebrew tap
brew install omrikais/cctally/cctally
The formula installs python@3.13 if it's not already present and pins cctally's shebang to that keg, so the tool keeps working even if your system Python changes. Symlinks cctally and the user-facing wrappers (cctally-tui, cctally-dashboard, cctally-forecast, …) into /opt/homebrew/bin/ (Apple Silicon) or /usr/local/bin/ (Intel/Linuxbrew).
After brew install, run cctally setup once to register Claude Code hooks and bootstrap the local SQLite cache.
npm
npm install -g cctally
The package bundles bin/cctally (the Python script) and the dashboard static assets. The cctally command on PATH is a ~30-line Node shim that resolves python3 and execs the bundled script. Windows is not supported — use WSL or a native Linux/macOS environment.
If you have a custom Python install, set CCTALLY_PYTHON:
export CCTALLY_PYTHON=/opt/homebrew/bin/python3.13
The Node shim needs a python3 on your PATH. If cctally setup reports python3 not found, install Python (brew install python on macOS) and re-run, or point CCTALLY_PYTHON at your interpreter.
From source
git clone https://github.com/omrikais/cctally
cd cctally
./bin/cctally setup
Useful when you want to run unreleased commits or iterate on contributions. setup symlinks bin/cctally* into ~/.local/bin/.
Migrating from the status-line snippet
If you already wired cctally record-usage into ~/.claude/statusline-command.sh,
you don't have to do anything; it keeps working. To switch to the new
hook-based path, run cctally setup. The legacy snippet will be detected
and you'll be told it's safe to remove (we don't touch your file).
Migrating from an earlier install pattern
If you previously wired cctally into Claude Code via hand-installed scripts
under ~/.claude/hooks/ (e.g. record-usage-stop.py,
usage-poller-{start,stop}.py, usage-poller.py), cctally setup will
detect them and offer to migrate: unwire the matching settings.json
entries, move the files to a timestamped backup directory under
~/.claude/, and best-effort stop any active background daemon. See
Migrating from a prior install pattern
for the details and the new --migrate-legacy-hooks /
--no-migrate-legacy-hooks flags.
Requirements
- Python 3.11+ (stdlib only, no
pip installneeded). - macOS or Linux. Tested primarily on macOS (zsh).
- Claude Code installed and run at least once (
~/.claude/must exist).
Install
git clone https://github.com/omrikais/cctally
cd cctally
./bin/cctally setup
cctally setup will:
- Symlink the user-facing binaries into
~/.local/bin/ - Add three hook entries (
PostToolBatch,Stop,SubagentStop) to~/.claude/settings.json(additive: it never modifies your existing entries) - Bootstrap the local SQLite cache and (if you've authenticated with Claude) fetch the first usage snapshot
If ~/.local/bin isn't on your PATH yet, setup will print the line to add to
your shell rc.
Using cctally before (or without) setup
You don't have to run cctally setup to get value from cctally. The reporting commands read your ~/.claude session logs (and the local cache) directly, so they work immediately after an npm/npx or source install:
npx cctally daily # cost-by-day, no setup required
npx cctally dashboard # live web dashboard
npx cctally tui # terminal dashboard
(After a global npm install — or a source checkout whose bin/ is on your PATH — drop the npx and just run cctally daily.)
What setup adds is auto-recording: the live status-line quota percentage and the three hooks that keep data flowing as you work, plus the first-run cache bootstrap. Run it once you want continuous tracking rather than on-demand reports. On a large session history that first-run cache sync now streams live progress to the terminal, so a multi-second cold sync no longer looks hung.
Verify
cctally setup --status
cctally daily
cctally dashboard
Uninstall
cctally setup --uninstall # remove hooks + symlinks; keep history
cctally setup --uninstall --purge # also wipe ~/.local/share/cctally/
Optional: opt-in status-line integration (no OAuth API calls)
If you'd rather have your existing status line feed cctally directly (and avoid
the OAuth API roundtrips that the hook path makes once per ~30s), see
docs/commands/record-usage.md. The two paths are
not mutually exclusive; both go through the same record-usage funnel and
dedupe correctly.