aimonitor

module
v1.1.54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT

README

aimonitor

Multi-account Claude Code usage monitor & silent account switcher for macOS & Linux.

CI Latest release

English | 简体中文 | 繁體中文 | Tiếng Việt

Features

  • 🔍 Live 5h + 7d usage bars per account — polled from Anthropic's /api/oauth/usage (no tokens consumed), with a trend line (↗ +21% in 45m).
  • 🔀 Silent switchingaimonitor switch <label> refreshes the OAuth token and swaps the live credential. No claude /login, no terminal hop.
  • 🤖 Auto-swap at the 5h or 7d threshold (default 80 %) — picks the account with the most overall headroom, skips exhausted/rate-limited ones, and rescues immediately if the active account hits 100 %. Running claude sessions follow automatically.
  • 🔔 Threshold notifications as an account nears its limit (when auto-swap is off).
  • 💾 Export / import settings, or migrate accounts to another machine — credentials optional and passphrase-encrypted (Argon2id + AES-256-GCM).
  • 🔌 MCP server — Slack, ClickUp & Sentry tools for Claude Code over stdio, with per-service read-only mode.
  • 🔐 OS-keyring storage (macOS Keychain, Linux libsecret). SQLite holds references; tokens never leave the keyring. No telemetry.

Install

# macOS (Sonoma 14+) — one command: taps, trusts, installs, clears Gatekeeper
curl -fsSL https://raw.githubusercontent.com/japananh/aimonitor/main/packaging/macos/install.sh | bash

# Linux (Ubuntu 22.04+) — CLI only
curl -fsSL https://raw.githubusercontent.com/japananh/aimonitor/main/packaging/linux/install.sh | sh

# Any platform, CLI only
go install github.com/japananh/aimonitor/cmd/aimonitor@latest

Prefer Homebrew directly? brew trust japananh/tap && brew install --cask japananh/tap/aimonitor, then clear Gatekeeper on first launch: xattr -dr com.apple.quarantine /Applications/AIMonitor.app (or right-click → Open). The one-line installer above does both for you. See docs/unsigned-app.md.

Upgrade
brew upgrade --cask aimonitor   # macOS
aimonitor update check          # CLI: is a newer release out?
aimonitor update install        # CLI: upgrade in the background

⚠️ macOS: brew upgrade --cask re-quarantines the app. Each upgrade lays down a fresh unsigned .app, so if it won't open afterward, re-clear Gatekeeper with xattr -dr com.apple.quarantine /Applications/AIMonitor.app (re-running the one-line installer does it for you). This is expected — not a broken install, so don't reinstall or --purge. The CLI keeps working regardless.

The menu-bar app also checks GitHub on launch and offers the update under Preferences → Check for updates. Pre-releases are never auto-served — brew upgrade keeps you on the latest stable.

Quick start

aimonitor add --adopt-current --label personal   # register your current Claude login
aimonitor add --label work                        # add another (drives claude /login, polls keychain)
aimonitor switch work                             # switch silently
aimonitor list                                    # live 5h / 7d usage per account
aimonitor doctor                                  # health check

Already on another switcher? aimonitor import pulls its accounts in one step. Auto-swap is on by default at 80 % — nothing else to configure for the common case.

Configuration

aimonitor config set auto_swap.enabled true        # default true
aimonitor config set auto_swap.threshold_pct 80    # 5h threshold
aimonitor config set auto_swap.threshold_7d_pct 80 # 7d threshold
aimonitor config set autostart true                # daemon at login

Back up or move to another machine:

aimonitor config export --out backup.json                                          # settings only (no secrets)
AIMONITOR_PASSPHRASE=… aimonitor config export --include-tokens --out full.json     # + encrypted credentials
AIMONITOR_PASSPHRASE=… aimonitor config import full.json                            # restore elsewhere

--include-tokens bundles your logins encrypted under the passphrase — restoring it means claude works on the other machine without re-login, so treat that file like a password. Same actions live in Preferences → Backup.

All config keys
Key Default Description
auto_swap.enabled true Master toggle for auto-swap
auto_swap.threshold_pct 80 5h utilization (%) to auto-swap
auto_swap.threshold_7d_pct 80 7d utilization (%) to auto-swap
auto_swap.grace_sec 60 Delay between the "pending" notification and the swap (0 = immediate)
notify.enabled true Warn as the active account nears its limit (only when auto-swap is off)
notify.warn_pct / notify.crit_pct 80 / 95 Warning / critical notification levels
daily_summary.enabled true Once-a-day notification recapping yesterday's token usage across accounts
auto_update.enabled true Check GitHub for releases on launch (never auto-installs)
autostart false Start the daemon at login
mcp.slack.enabled / mcp.clickup.enabled / mcp.sentry.enabled true Expose that service's MCP tools
mcp.slack.read_only / mcp.clickup.read_only / mcp.sentry.read_only false Hide the service's write tools
mcp.sentry.org (empty) Sentry organization slug the tools query
mcp.sentry.base_url https://sentry.io Sentry API host (set to your self-hosted host)
mcp.disabled_tools (empty) Comma-separated tool names to hide

How it works

The daemon polls /api/oauth/usage (~5 min ± jitter, no tokens consumed). When the active account crosses its 5h or 7d threshold, it picks the account with the most overall headroom, refreshes that account's OAuth token (POST .../v1/oauth/token), and writes it to the live Keychain slot. Running and new claude sessions adopt the new account — no /login, no restart.

See docs/architecture.md and docs/thresholds.md for the full picture.

MCP server (Slack, ClickUp & Sentry for Claude Code)

One stdio process serving Slack, ClickUp & Sentry tools — no extra runtimes.

aimonitor mcp connect slack     # store a Slack user token (xoxp-…)
aimonitor mcp connect clickup   # store a ClickUp token (pk_…)
aimonitor mcp connect sentry    # store a Sentry auth token (set mcp.sentry.org first)
aimonitor mcp register          # add the server to Claude Code
  • Slack: post to channels/threads (mrkdwn, code blocks), upload files (from a local path or inline text), search, history, permalinks, and read attachments — including images, returned as viewable pixels (or saved to a local path).
  • ClickUp: workspace hierarchy, tasks, comments, attachments both ways — upload from a local path/inline text and read them back, images included — Docs (read & write).
  • Sentry: triage digests (projects, issue search, detail), root-cause (latest event stacktrace, tag/value distributions), and actions (resolve/ignore/assign, comment). Org-scoped and self-hosted-aware (mcp.sentry.org, mcp.sentry.base_url).
  • Safety: Claude Code's per-tool prompts are the approval layer; per-service Enabled / Read-only switches and a per-tool disable list refine it. Tokens are verified live, then stored in the OS keyring — never in SQLite or logs.

Slack token scopes. The Slack token is a user token (xoxp-…). Grant these User Token Scopes on your Slack app (api.slack.com → OAuth & Permissions), reinstall, then connect — a missing one surfaces as slack: missing scope "…" on the affected tool: search:read, users:read, users:read.email, channels:history, groups:history, im:history, mpim:history, channels:read, groups:read, im:read, mpim:read, chat:write, files:read, files:write.

Sentry token scopes. A Sentry auth token (User Auth Token, or an Internal Integration). Set mcp.sentry.org — and mcp.sentry.base_url for self-hosted — before connect. Scopes: org:read, project:read, event:read for the read/triage tools; add event:write + member:read to resolve/assign/comment; event:admin to delete comments.

Privacy & security

  • No telemetry, no phone-home. OAuth tokens live only in the OS keyring; SQLite holds references. Token bytes are never logged.
  • Outbound traffic is limited to: GET /api/oauth/usage (introspection, no tokens consumed), POST /v1/oauth/token (silent token refresh), and the GitHub release check. Nothing about you is sent.

See docs/security.md for the threat model.

Troubleshooting

aimonitor doctor   # health check: config, SQLite, keyring, accounts
  • "Daemon not running" / usage looks stale. Start or restart the background daemon with aimonitor config set autostart true, or click Start daemon in the popover — it registers a LaunchAgent that relaunches at login.
  • App won't open — "damaged", "can't be opened", or "unidentified developer" (macOS Gatekeeper on the unsigned app). Happens on first launch and after every brew upgrade/reinstall — each lays down a fresh unsigned .app. Clear the quarantine flag, then reopen: xattr -dr com.apple.quarantine /Applications/AIMonitor.app. This is not a broken install, so don't uninstall or aimonitor uninstall --purge to "reset" it — --purge wipes your saved account logins. The CLI (aimonitor …) is unaffected. Details: docs/unsigned-app.md.
  • Logs. The daemon writes to ~/Library/Logs/aimonitor/aimonitor.daemon.log (INFO/WARN/ERROR — never token bytes); background upgrades log to update.log beside it.
  • Recent switches. aimonitor log prints the switch audit trail.

Uninstall

# Remove the app + daemon, KEEP your saved accounts
brew uninstall --cask aimonitor

# Full wipe — ALSO deletes every account login aimonitor saved in your Keychain.
# Purge runs first: it needs the binary still installed to reach the stashes.
aimonitor uninstall --purge && brew uninstall --cask aimonitor

🔴 --purge is destructive and irreversible. It permanently deletes aimonitor's saved copies of all your accounts (the aimonitor-<uuid> Keychain stashes) — you'll have to aimonitor add and complete /login for every account again. Plain brew uninstall --cask aimonitor (no --purge) keeps them all.

App won't open? That's Gatekeeper, not a broken install — don't --purge to "reset" it. Run the xattr fix in Troubleshooting instead.

--purge never touches Claude's own Claude Code-credentials slot, so the account you're currently signed into keeps working in claude with no re-login — only aimonitor's saved copies of your other accounts are dropped (and those you must re-add).

Build from source

Requires Go 1.25+. Pure Go (CGO_ENABLED=0 works on macOS; keychain access shells out to /usr/bin/security).

make build              # CLI binary
make test               # unit tests
make widget             # AIMonitor.app (macOS; needs the Swift toolchain)
make release-snapshot   # goreleaser dry-run

License

MIT © @japananh

Directories

Path Synopsis
cmd
aimonitor command
Command aimonitor is the CLI entry point.
Command aimonitor is the CLI entry point.
internal
claudeconfig
Package claudeconfig reads and writes ~/.claude.json — the file Claude Code uses to record which OAuth account is active (the `oauthAccount` object) alongside many unrelated settings.
Package claudeconfig reads and writes ~/.claude.json — the file Claude Code uses to record which OAuth account is active (the `oauthAccount` object) alongside many unrelated settings.
cli
Package cli implements the aimonitor CLI subcommands.
Package cli implements the aimonitor CLI subcommands.
config
Package config holds aimonitor's user-facing configuration: thresholds for the auto-switch tripwires, autoswitch on/off, cool-down, etc.
Package config holds aimonitor's user-facing configuration: thresholds for the auto-switch tripwires, autoswitch on/off, cool-down, etc.
daemon
Package daemon hosts aimonitor's long-running background components: the Unix-socket JSON-RPC server, the JSONL filesystem watcher, the auto-switch engine.
Package daemon hosts aimonitor's long-running background components: the Unix-socket JSON-RPC server, the JSONL filesystem watcher, the auto-switch engine.
install
Package install wires platform-specific autostart helpers.
Package install wires platform-specific autostart helpers.
mcpserver
Package mcpserver implements `aimonitor mcp serve` — a stdio MCP server exposing Slack and ClickUp tools to Claude Code — plus the credential plumbing (`aimonitor mcp connect/disconnect/status`) behind it.
Package mcpserver implements `aimonitor mcp serve` — a stdio MCP server exposing Slack and ClickUp tools to Claude Code — plus the credential plumbing (`aimonitor mcp connect/disconnect/status`) behind it.
provider
Package provider defines the abstraction every AI-provider integration must implement.
Package provider defines the abstraction every AI-provider integration must implement.
provider/claude
Package claude implements the Provider interface for Anthropic's Claude Code OAuth ecosystem.
Package claude implements the Provider interface for Anthropic's Claude Code OAuth ecosystem.
secret
Package secret bridges aimonitor to the OS-native secret store: macOS Keychain on darwin, libsecret (Secret Service DBus) on linux.
Package secret bridges aimonitor to the OS-native secret store: macOS Keychain on darwin, libsecret (Secret Service DBus) on linux.
store
Package store wraps the SQLite database that aimonitor uses for everything that is NOT a secret: account references, per-file JSONL resume offsets, usage samples, audit log, settings.
Package store wraps the SQLite database that aimonitor uses for everything that is NOT a secret: account references, per-file JSONL resume offsets, usage samples, audit log, settings.
updater
Package updater checks GitHub Releases for a newer aimonitor build and describes how to install it.
Package updater checks GitHub Releases for a newer aimonitor build and describes how to install it.
util/filelock
Package filelock provides a minimal Unix flock(2) wrapper for serializing access to multi-step operations like account switching.
Package filelock provides a minimal Unix flock(2) wrapper for serializing access to multi-step operations like account switching.
version
Package version holds the build-time version string for aimonitor.
Package version holds the build-time version string for aimonitor.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL