Quick Start
Requirements
- A reachable
CLIProxyAPImanagement gateway - The CPA management key, unless you intentionally use a local proxy that injects it
- A reachable gateway health endpoint
- Optional Codex auth files if you want direct quota sampling
For a bare CPA endpoint, create a key file containing the same plaintext value as CPA remote-management.secret-key. Recent CPA versions disable /v0/management/* with 404 when that secret is empty. If you intentionally use a local proxy that injects Authorization, point managementBaseUrl at that proxy and omit the key file.
Before pointing the monitor at real key or auth files, review the security self-audit. It explains the data flow, residual risks, and local checks for secret redaction.
If you only want to preview the UI first, run demo mode instead:
codex-quota-monitor --demo
--demo serves built-in sample data on 127.0.0.1:4516 by default, so it can
run next to a normal 127.0.0.1:4515 monitor. It does not read auth files,
management keys, SQLite history, benchmark summaries, or CPA endpoints.
The browser Privacy button defaults to showing original text; click it to mask
email addresses and token-like strings in the rendered UI. This is display-only:
/api/* and /metrics keep their original machine-readable payloads.
Typical local values:
managementBaseUrl = http://127.0.0.1:8317managementKeyFile = /path/to/management-keygatewayHealthUrl = http://127.0.0.1:8317/healthzport = 4515displayTimezone = localuiFontFamily = system UI stackmonoFontFamily = system monospace stack
Nix
After v0.2.0 is published, run directly from the release flake:
nix run github:xsyxnx/codex-quota-monitor/v0.2.0#codex-quota-monitor -- \
--management-base-url http://127.0.0.1:8317 \
--management-key-file /path/to/management-key \
--gateway-health-url http://127.0.0.1:8317/healthz \
--auth-dir /path/to/auth-files
Expose it to the local network only when you mean to:
nix run github:xsyxnx/codex-quota-monitor/v0.2.0#codex-quota-monitor -- \
--host 0.0.0.0 \
--allowed-host monitor.lan \
--port 4515 \
--management-base-url http://127.0.0.1:8317 \
--management-key-file /path/to/management-key \
--gateway-health-url http://127.0.0.1:8317/healthz \
--auth-dir /path/to/auth-files
Replace monitor.lan with the hostname or IP address browsers will use in the
Host header. The dashboard rejects unexpected Host and Origin values.
By default, total 5h capacity is capped by weekly remaining * 6.0. Use --weekly-to-five-hour-multiplier <number> to override it, or --weekly-to-five-hour-multiplier off / none to disable the cap.
Reset times use the service’s local timezone by default. Use --display-timezone UTC, --display-timezone Asia/Shanghai, or another IANA timezone when you want a fixed display zone.
The dashboard language defaults to --display-locale auto, which follows the browser and currently supports en and zh-CN; set --display-locale zh-CN or --display-locale en for a fixed service default.
Use --ui-font-family and --mono-font-family with CSS font-family lists when you want a different service default. The dashboard also has browser-local Preferences that override the service defaults for the current browser only. Fonts are not bundled; names such as "Maple Mono NF CN" work only on devices where that font is installed.
Direct nix run keeps SQLite history disabled by default. Add a writable state DB when you want Trends, ETA, Audit history, or the Stats time-series workbench; the Trends tab shows the latest 6h of stored samples, and Stats uses the same database for token/request curves and JSON/CSV export:
nix run github:xsyxnx/codex-quota-monitor/v0.2.0#codex-quota-monitor -- \
--state-db ./result/codex-quota-monitor.sqlite3 \
--management-base-url http://127.0.0.1:8317 \
--management-key-file /path/to/management-key \
--gateway-health-url http://127.0.0.1:8317/healthz \
--auth-dir /path/to/auth-files
For PyPI, Docker, Debian/Ubuntu systemd, and Windows notes, see Install.
Python
uv tool install codex-quota-monitor==0.2.0
codex-quota-monitor init --mode user
codex-quota-monitor \
--management-base-url http://127.0.0.1:8317 \
--management-key-file /path/to/management-key \
--gateway-health-url http://127.0.0.1:8317/healthz \
--auth-dir /path/to/auth-files
To preview the source before the tag is published, use the source install path:
uv tool install 'git+https://github.com/xsyxnx/codex-quota-monitor.git'
If you prefer pipx, use pipx install codex-quota-monitor==0.2.0 or the same git+https://... source URL.
After a Python install, cqm is an equivalent short alias for codex-quota-monitor.
init prints copyable config.toml, rootless systemctl --user service, and next-step smoke checks. It does not write system paths unless you pass --output-dir.
Docker
docker run --rm \
--add-host=host.docker.internal:host-gateway \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges \
--tmpfs /tmp \
-p 127.0.0.1:4515:4515 \
-e CODEX_QUOTA_MONITOR_MANAGEMENT_BASE_URL=http://host.docker.internal:8317 \
-e CODEX_QUOTA_MONITOR_MANAGEMENT_KEY_FILE=/management-key \
-e CODEX_QUOTA_MONITOR_GATEWAY_HEALTH_URL=http://host.docker.internal:8317/healthz \
-v codex-quota-monitor-data:/data \
-v /path/to/management-key:/management-key:ro \
-v /path/to/auth-files:/auth-files:ro \
-e CODEX_QUOTA_MONITOR_AUTH_DIR=/auth-files \
ghcr.io/xsyxnx/codex-quota-monitor:0.2.0
Mount only the specific management key file and auth-files directory the monitor
needs, and keep both mounts read-only. The mounted key file must match CPA
remote-management.secret-key for a bare CPA endpoint. Do not mount your whole home, .config,
or unrelated secret directories into the container.
To preview the source before the GHCR release image exists, build locally with docker build -t codex-quota-monitor:local ..
Shared Client Labels
When CPA usage details identify shared clients by apiName / api_name, add a
small JSON label file and use the Stats Client group for friend-level
request/token accounting:
{
"clients": [
{"apiName": "sk-example-from-cpa", "label": "Alice"},
{"api_name": "rotated-api-name", "label": "Alice"}
]
}
Run with --client-labels-file /path/to/client-labels.json. Keep this file as
runtime secret material; unmapped clients are shown as short fingerprints.
Smoke Test
cqm tldr
cqm print-config
cqm doctor
curl -fsS http://127.0.0.1:4515/healthz
curl -fsS http://127.0.0.1:4515/api/v1/status | jq '.summary'
curl -fsS http://127.0.0.1:4515/api/v1/recommendations | jq '.summary'
curl -fsS 'http://127.0.0.1:4515/api/v1/stats/series?range=24h&metric=tokens' | jq '.summary'
curl -fsS 'http://127.0.0.1:4515/api/v1/stats/series?range=24h&group=client' | jq '.breakdown.clients'
curl -fsS http://127.0.0.1:4515/api/v1/diagnostics | jq '.summary'
curl -fsS http://127.0.0.1:4515/api/v1/alerts | jq '.'
curl -fsS http://127.0.0.1:4515/metrics | sed -n '1,20p'
Open http://127.0.0.1:4515/ in a browser after the process starts.
Benchmarking
If you also want to benchmark fast versus baseline, or Team versus Plus quota capacity, see Benchmark guide.