mm_ccusage
v0.7.0
Published
Multi-Instance ccusage TUI Dashboard
Readme
mm_ccusage
Terminal dashboard for aggregated Claude Code usage across multiple machines.
It combines local and SSH-host data, stores history in SQLite, and renders an interactive TUI with Ink/React.
What it does
- Aggregates usage from
localplus remote hosts. - Auto-discovers SSH hosts from
~/.ssh/config(wildcard hosts are ignored). - Shows 5 tabs:
Daily,Monthly,Sessions,Blocks,Charts. - Supports date/instance filtering, keyboard navigation, and manual refresh.
- Auto-refreshes on a timer and displays per-host fetch progress.
- Persists usage history in
${dataDir}/history.dband falls back to cached rows when a host is unavailable. - Shows threshold alerts (warning at 80%, critical at 100%).
- Optionally merges Codex usage (
@ccusage/codex) into the same views (enabled by default).
Requirements
- Node.js 18+
ccusageavailable locally and on remote hosts (the app also falls back tonpx -y ccusage)- SSH access to remote machines (key-based auth recommended)
Install
git clone <repo-url>
cd multi_instance
npm install
npm run buildRun
# Directly from build output
node dist/cli.js
# Optional: expose package bin (mm_ccusage)
npm link
mm_ccusageCLI
node dist/cli.js [options]| Flag | Description | Default |
|------|-------------|---------|
| --hosts <list> | Comma-separated SSH host names to include (for example labpc,gpu1). local is always included. | All discovered/configured SSH hosts |
| --since <YYYYMMDD> | Start date passed through to upstream usage commands. | unset |
| --until <YYYYMMDD> | End date passed through to upstream usage commands. | unset |
| --interval <seconds> | Auto-refresh interval in seconds. | 300 |
Examples:
node dist/cli.js --hosts local,labpc,gpu-server
node dist/cli.js --interval 60
node dist/cli.js --since 20260201 --until 20260229Configuration
Config file lookup order:
~/.ccusage-dashboard.json~/.config/ccusage-dashboard/config.json
Example:
{
"refreshInterval": 300,
"timezone": "America/New_York",
"dataDir": "/Users/you/.ccusage-dashboard",
"codex": true,
"thresholds": {
"global": {
"dailyLimit": 10,
"monthlyLimit": 100
},
"perInstance": {
"labpc": { "dailyLimit": 5 },
"gpu1": { "monthlyLimit": 50 }
}
},
"hosts": [
{
"name": "labpc",
"hostname": "192.168.1.10",
"port": 22,
"user": "alice",
"identityFile": "~/.ssh/id_ed25519"
}
]
}Notes:
hostsfrom config are merged with parsed SSH hosts (deduplicated byname; config wins on conflict).- Set
"codex": falseto disable Codex fetches. dataDircontrols where SQLite cache is stored (history.db).
Keyboard Shortcuts
| Key | Action |
|-----|--------|
| 1-5 | Switch tabs |
| j / Down | Next row |
| k / Up | Previous row |
| Enter | Expand/collapse selected row |
| r | Refresh now |
| f | Open filter dialog |
| ? | Toggle help overlay |
| q | Quit |
Data Flow
- Load cached rows from SQLite (if present).
- Fetch each host in parallel (
local+ SSH hosts). - For each host, run
daily,monthly,session, andblocksin a multiplexed batch. - If enabled, run Codex fetches in parallel and merge results.
- Upsert fresh rows into SQLite and update UI incrementally as hosts finish.
- If a host fails, use cached rows for that host and show an error banner.
Development
npm run dev # TypeScript watch build
npm run typecheck # Strict type check
npm test # Vitest test suite
npm run build # Production build to dist/Project Layout
src/
cli.tsx # CLI entrypoint
app.tsx # Main TUI app shell and keybindings
config.ts # Config loading/validation
resolve-config.ts # Merge CLI options with file/SSH config
ssh-config-parser.ts # Parse ~/.ssh/config hosts
fetchers/ # Local/SSH command executors + orchestrator
db/ # SQLite setup and repository functions
hooks/ # Data, refresh, and table navigation hooks
components/ # Tabs, views, dialogs, status, summary
utils/ # Alerts and color helpersLicense
ISC
