CodexMeter
CodexMeter is a native macOS menu bar app that keeps your Codex account limits visible at a glance.
[!NOTE]
CodexMeter is an unofficial community project. It is not affiliated with or
endorsed by OpenAI.
Preview
Menu Bar Popover
Usage History
Interactive Token Activity
Customizable Popover
Features
- Shows a selected Codex quota directly in the macOS menu bar, with automatic
- Uses two concentric progress rings:
- Highlights normal, over-pace, and low-quota states without relying on color
- Displays the standard 5-hour and weekly Codex quota windows by default, with
- Shows available banked Codex rate-limit resets as one compact lifetime
- Compares remaining quota with remaining time to indicate whether consumption
- Refreshes quota on launch, every 10 seconds while the menu is open, every
- Detects Codex account changes and switches quota data without requiring an app
- Supports standalone and npm-installed Codex CLI launchers by supplying common
- Preserves the last successful result and marks it as stale when refresh fails.
- Supports optional low-quota and over-pace notifications.
- Supports push notifications to Bark and Gotify servers when 5-hour or weekly quota resets, with custom icon URL support for Bark.
- Supports launch at login.
- Includes English, Simplified Chinese, and Traditional Chinese.
- Lets the app interface follow the system appearance or stay in Light or Dark
- Offers ring, horizontal-bar, stacked-bar, percentage-only, and progress-only
- Lets users independently show, hide, and reorder quota details, reset
- Includes developer options with presets, custom quota/time sliders, live
- Records local quota history as changes plus 15-minute anchors. The full chart
- Shows a compact view of the current weekly quota cycle plus the last 30 days
k, M, and B units
instead of scientific notation.
- Keeps the menu-bar popover compact with divider-separated quota and token
- Provides a resizable, full-screen-capable history window with an integrated
- Shows optional daily and summary token activity from
account/usage/read
- Accumulates returned daily token buckets locally, clears them on an explicit
- Uses native Liquid Glass cards and controls on macOS 26, with the same modern
- Includes an About window and Sparkle-based signed updates. It checks daily,
How It Works
Changed digits in the menu bar percentage briefly turn red when quota decreases, hold red for half a second, then smoothly fade back over two seconds; the percent sign keeps its normal color.
CodexMeter launches the locally installed Codex CLI as:
codex app-server --listen stdio://
It then communicates with App Server using newline-delimited JSON-RPC messages:
- Initialize the local App Server connection.
- Read account metadata with
account/read. - Read ChatGPT rate-limit windows with
account/rateLimits/read. - Read optional banked-reset availability from the same rate-limit response.
- Optionally read token activity with
account/usage/readwhen supported. - Record successful quota snapshots and token summaries in account-separated
- Refresh when
account/updatedoraccount/rateLimits/updatedis received. - Recover a stale authentication session by restarting only the local App
- Calculate remaining quota, remaining time, consumption pace, and eligible
CodexMeter does not scrape ChatGPT pages, read Codex authentication files, or store access tokens. Authentication and token refresh remain owned by Codex.
Codex App Server is currently an experimental interface intended for local development and debugging, so future Codex releases may require compatibility updates. See the official Codex App Server documentation.
Requirements
- macOS 13 or later.
- Xcode 27 beta or later when building the current project from source.
- A locally installed Codex CLI.
- A working Codex login.
npm install -g @openai/codex
codex login
CodexMeter currently discovers codex in these locations:
~/.local/bin/codex
/opt/homebrew/bin/codex
/usr/local/bin/codex
~/.npm-global/bin/codex
~/.nvm/versions/node/*/bin/codex
Build and Run
Clone the repository:
git clone [email protected]:raycalrui/CodexMeter.git
cd CodexMeter
open CodexMeter.xcodeproj
In Xcode:
- Select the
CodexMeterscheme. - Select My Mac as the destination.
- Press Run.
Download and Install
Download CodexMeter-1.7.0.dmg from the GitHub Releases page, open it, and drag
CodexMeter into the Applications folder.
The downloadable build uses an ad-hoc signature and is not notarized. On first launch, macOS may block it. Control-click CodexMeter in Applications, choose Open, and confirm once. A Developer ID certificate and Apple notarization are planned for a future distribution build.
Automatic Updates
Starting with version 1.3.0, CodexMeter uses Sparkle to download, verify, replace, and relaunch the app. Every update archive is signed with a separate EdDSA key, so this works with the existing ad-hoc app signature and does not require a paid Apple Developer account. The private EdDSA key remains in the maintainer's login Keychain and is never stored in the repository or bundled in the app.
Version 1.2.1 does not contain Sparkle, so upgrading from 1.2.1 to 1.3.0 still requires downloading the DMG manually. Once 1.3.0 is installed, later signed updates can be installed inside CodexMeter. Because the app is not notarized, macOS may still show Gatekeeper warnings on a new installation or after an update; Sparkle does not replace Apple notarization.
Development
Build from Terminal:
xcodebuild \
-project CodexMeter.xcodeproj \
-scheme CodexMeter \
-configuration Debug \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO \
build
Run the core unit tests:
swift test
If Command Line Tools is selected instead of the full Xcode installation, set
DEVELOPER_DIR before running either command.
Pure quota, time, pacing, history, migration, and semantic-version logic lives
under CodexMeter/Core. Package.swift exposes only that directory to Swift
Package Manager so the core logic can be tested independently of the macOS UI.
Publishing a Sparkle update
After building the unsigned Release app, re-sign the embedded Sparkle framework and then the outer app bundle. This order is required because Xcode removes development headers while embedding the framework:
Scripts/sign_ad_hoc_release.sh /path/to/CodexMeter.app
Create the release DMG from that verified app. Then use Sparkle's bundled
generate_appcast utility. The helper below reads the private EdDSA key from
the login Keychain, signs the archive metadata, and updates the repository's
appcast.xml:
Scripts/prepare_sparkle_update.sh \
v1.7.0 \
/path/to/CodexMeter-1.7.0.dmg \
/path/to/Sparkle/bin
For a prerelease, pass beta as the fourth argument. Upload the exact signed
DMG to the matching GitHub Release, commit and push the generated
appcast.xml, then verify its download URL before announcing the release.
See AGENTS.md for the project architecture, product rules, verification checklist, and planned developer customization options.
Privacy and Security
- CodexMeter communicates with a local Codex process over stdio.
- It does not copy or persist Codex access tokens.
- It does not read Codex authentication files directly.
- It does not log account email addresses or raw authentication responses.
- App Server errors use locally authored messages instead of displaying raw
- App Server output is read in bounded chunks. A response line over 1 MiB stops
- In-app updates require Sparkle 2.9.6 or later and retain HTTPS transport and
- It separates ChatGPT account history with a salted SHA-256 key derived
- It does not add its own analytics or tracking.
- Usage history is stored only in
~/Library/Application Support/CodexMeter/UsageHistory.sqlite and can be
exported or cleared by the user.
App Sandbox is currently disabled because CodexMeter must launch the user's local Codex executable. This should be reviewed deliberately before any future Mac App Store distribution.
Full history backup and restore
The menu-bar Settings entry opens one resizable window with four categories: General, Menu Bar & Popover, History & Backup, and Developer, followed by About. Existing preferences are preserved. About/update information opens in the same settings window; Usage History remains a separate window.
Open Settings → History & Backup → Backup & Restore to export a .codexmeterbackup file.
It includes all retained quota and token history across accounts, database
metadata, and the local identity salt needed to match accounts on another Mac.
It does not contain login credentials, email addresses, or app preferences.
Keep this file private. Previously deleted or retention-pruned records cannot
be recovered. CSV remains a separate readable export format.
Restore replaces all local history after confirmation. CodexMeter validates the
archive version, SHA-256 checksum, database integrity, schema, and row counts,
then saves the existing history in ~/Library/Application Support/CodexMeter/Backups.
Quit and reopen the app after restoring; history writes pause until then.
Your existing retention preference applies after reopening. An interrupted
restore is rolled back before account activation at the next launch.
Backups larger than 512 MiB are currently unsupported.
Known Limitations
- Codex App Server is experimental and may change without notice.
- Codex executable discovery uses common stable install locations and installed
PATH.
- Notification and launch-at-login behavior must be tested with a signed build.
- Token activity is optional and may be unavailable for API-key, Bedrock, or
- Banked-reset availability is account-dependent. Older App Server versions or
- Codex currently provides no stable identifier for API-key and Bedrock
- The downloadable DMG is ad-hoc signed, not notarized, and not prepared for
Contributing
Issues and pull requests are welcome.
Before submitting a change:
swift test
git diff --check
For menu bar or popover changes, also launch exactly one signed app instance and perform a UI smoke test.
License
CodexMeter is available under the MIT License.
Disclaimer
Codex and OpenAI are trademarks of OpenAI. This project is provided as an independent utility and may stop working when upstream experimental interfaces change.