Skip to main content

ai-limits

See how much of your AI subscriptions is left — Claude and Codex, any number of accounts — right in the GNOME top bar.

                                   ✳ 42%   ◎ 19%   Oct 27 15:49
 Claude Max
   Session (5h)   ████░░░░░░  42%   ↻ 18:30 (in 2h10m)
   Week           ██░░░░░░░░  18%   ↻ Sun 19:00 (in 5d3h)
 Codex · personal                         ★ most headroom
   Week           ██░░░░░░░░  19%   ↻ Thu 12:00 (in 2d21h)
 Codex · work                             updated 8h ago
   Week           █████████░  91%   ↻ 18:00 (in 2h)

Offline by default. ai-limits reads only what Claude Code and Codex already saved on your machine. It sends no requests and does not read your tokens unless you turn on network mode, and network mode refuses to send anything unless the route goes through the VPN interface you name.

Unofficial. Not affiliated with Anthropic or OpenAI. The local formats and the usage endpoint it reads are undocumented and may change.

Install

uv tool install ai-limits        # or: pipx install ai-limits
ai-limits                       # check it sees your accounts

For the optional GNOME Shell 45–49 extension, install from a checkout (it is not in the wheel):

git clone https://github.com/jointsome0-lgtm/ai-limits.git
cd ai-limits
./gnome-extension/install.sh

Platforms

Python 3.11–3.14, with no runtime dependencies. On distributions with an older system Python (e.g. Ubuntu 22.04 ships 3.10), use uv tool install ai-limits: uv fetches a suitable Python itself. Linux supports the offline CLI, Claude tap, and VPN-guarded network mode (ip from iproute2 is required for network mode). macOS and Windows support the offline CLI and Claude tap; network mode refuses to run there, before reading credentials or looking up the host. The GNOME extension is Linux-only.

Config and cache use ~/.config/ai-limits and ~/.cache/ai-limits on all platforms, unless XDG_CONFIG_HOME / XDG_CACHE_HOME override them. On Windows, ~ is the user profile directory and cache privacy relies on Windows ACLs; on POSIX, directories/files use 0700/0600. Files and CLI streams use UTF-8. Reset times display in the local timezone; timestamps without an explicit timezone are interpreted as UTC.

Where the numbers come from

Provider Offline source Network source (opt-in)
Codex rate-limit snapshots in ~/.codex/sessions/**/rollout-*.jsonl, updated whenever you use Codex —
Claude rate_limits Claude Code passes to its status line; saved by ai-limits tap claude api.anthropic.com/api/oauth/usage (adds per-model weekly limits)

When a window's reset time has passed, the limit is shown as ~0% until fresh data arrives.

Claude: add the tap to your status line

In ~/.claude/settings.json:

"statusLine": { "type": "command", "command": "ai-limits tap claude --print" }
// already have a status line? pass stdin through to it:
"statusLine": { "type": "command", "command": "ai-limits tap claude | bash ~/.claude/statusline.sh" }

Several accounts

Both CLIs keep each login in its own directory (CLAUDE_CONFIG_DIR=…, CODEX_HOME=…). List them in ~/.config/ai-limits/config.toml:

[[account]]
provider = "claude"
label    = "Claude Max"
home     = "~/.claude"

[[account]]
provider = "codex"
label    = "Codex · personal"
home     = "~/.codex"

[[account]]
provider = "codex"
label    = "Codex · work"
home     = "~/.codex-work"

Without a config file, ~/.claude and ~/.codex are picked up automatically. With two or more accounts of one provider, the one with the most headroom gets a ★ and is the one shown in the panel.

Network mode (Linux only, behind a VPN)

[network]
enabled = true
require_interface = "tun0"     # mandatory: no interface, no network
min_interval_seconds = 300

Before every request ai-limits:

  1. checks the interface exists — if not, it stops before even a DNS lookup;
  2. resolves the host and asks the kernel which interface the packet would leave by (ip route get, which honours policy routing as used by sing-box / xray / WireGuard);
  3. sends an anonymous probe (no token, no cookies) to the same host and IP, e.g. api.anthropic.com/v1/models. Being the same domain, it takes the same routing rule in your VPN client, so a direct rule or a dead tunnel shows up here. Only the exact answer an allowed region gets for a missing token (401 authentication_error) passes; a region block (403), a timeout or anything unexpected stops here;
  4. only then sends the real request, to exactly that IP, ignoring proxy environment variables.

Every socket is also bound to the interface (SO_BINDTODEVICE), so if the VPN drops between the checks and the request, the kernel refuses to send it another way. Any failure means no request with your token, and the panel shows ⏸ next to the last known numbers. Tokens are only read, never refreshed, never put on a command line, and never written anywhere.

What this cannot see: what your VPN client does inside the tunnel. If its rules send anthropic.com to a direct outbound (or fall back to direct when the proxy is down), traffic enters tun0 and still leaves from your real IP. The probe catches a region block, but the only real guarantee is in your VPN config: route these domains to the proxy with no direct fallback, or block them when the proxy is down (a kill switch).

CLI

ai-limits               summary
ai-limits --version     installed version
ai-limits json          state for UIs (docs/state-schema.md), also written to ~/.cache/ai-limits/state.json
ai-limits accounts      configured / detected accounts
ai-limits tap claude    status line helper (see above)

Development

python3 -m unittest discover tests
python3 -m ai_limits json

Releases go to PyPI through Trusted Publishing: run the Build or publish to PyPI workflow (publish.yml) on main with mode publish; build-only just builds and checks the packages. The PyPI publisher is owner jointsome0-lgtm, repository ai-limits, workflow publish.yml, environment pypi. No API token is needed.

The GNOME extension only runs ai-limits json and draws the result; adding a provider means one module in ai_limits/providers/.

License

MIT

Metadata

Release files for ai-limits 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ai-limits 0.1.0
File Size Uploaded Provenance Actions
ai_limits-0.1.0.tar.gz 41.1 kB With provenance Details for ai_limits-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ai-limits 0.1.0
File Interpreter ABI Platform Actions
ai_limits-0.1.0-py3-none-any.whl Python 3 none any Details for ai_limits-0.1.0-py3-none-any.whl

Total release size: 62.9 kB

Release files / ai_limits-0.1.0.tar.gz

Download URL ai_limits-0.1.0.tar.gz
Size 41.1 kB
Tags Source
SHA-256 checksum
How to use checksums
3708ee221fe6663d5e4868e97648546efb5600c9a5fd5d779af70601e1834fbb
BLAKE2b-256 checksum
How to use checksums
b723e791d946c725b9d3997a65be66e3655d1e8674461e70703c71f5892684ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Release files / ai_limits-0.1.0-py3-none-any.whl

Download URL ai_limits-0.1.0-py3-none-any.whl
Size 21.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9aced086535813f2babbbd020fbdb40684d8218916ca19dc17e43e01b7628859
BLAKE2b-256 checksum
How to use checksums
95bd1449b7d234fc589a107037f72e6888b027c7b5f8bf0d06d4346244d45d07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Security for ai-limits 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ai_limits-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page