A native macOS menu bar app that shows live rate-limit and health status for your AI API keys — Claude, ChatGPT, Gemini, Grok, and Perplexity, all in one glance.
AIBar sits in your macOS menu bar and polls each AI service's rate-limit headers in the background. Click the tray icon to see a live dashboard of:
API keys are stored in your OS keychain — never on disk or in a remote server.
| Service | Provider | Notes |
|---|---|---|
| Claude | Anthropic | Reads anthropic-ratelimit-* response headers |
| ChatGPT | OpenAI | Reads x-ratelimit-* response headers |
| Gemini | Key validity check via free /v1beta/models endpoint |
|
| Grok | xAI | OpenAI-compatible endpoint |
| Perplexity | Perplexity AI | Chat completions endpoint |
How it works: For services that expose rate-limit headers (Claude, ChatGPT, Grok, Perplexity), AIBar makes a minimal 1-token completion request every 10 minutes — costing roughly $0.000001 per check — and reads the headers off the response. No billing API access required, just your standard API key.
xcode-select --install)# Clone the repo
git clone https://github.com/jishangiras/aibar.git
cd aibar
# Install JS dependencies
npm install
# Run in development mode (opens the tray app with hot reload)
npm run tauri dev
# Build a production .app bundle
npm run tauri build
# Output: src-tauri/target/release/bundle/macos/AIBar.app
The built .app can be dragged to /Applications like any other Mac app.
AIBar refreshes automatically every 10 minutes with a small random jitter. Hit ↻ in the header to force an immediate refresh.
| Layer | Technology |
|---|---|
| Desktop shell | Tauri 2.0 |
| Frontend | Svelte 5 + SvelteKit 2 (adapter-static) |
| Styling | Tailwind CSS 3 — dark-first, adapts to system theme |
| Backend | Rust — tokio, reqwest, keyring |
| State bridge | Tauri commands + events (invoke / emit) |
aibar/
├── src/ Svelte frontend
│ ├── routes/
│ │ ├── +page.svelte Main popup (service grid + settings view)
│ │ └── settings/ (legacy route, kept for deep-link compat)
│ └── lib/
│ ├── components/ ServiceCard, StatusDot, ProgressBar, DetailPanel
│ ├── stores/ Svelte 5 rune store — listens to service-updated events
│ ├── api/tauri.ts Typed invoke() wrappers
│ └── types.ts Shared types mirroring Rust structs
│
└── src-tauri/ Rust backend
└── src/
├── lib.rs Tauri builder + plugin registration
├── state.rs AppState (Arc<RwLock<_>> fields)
├── commands.rs Tauri commands exposed to the frontend
├── polling.rs Background refresh loop with ±10% jitter
├── tray.rs Menu bar icon + click handler
└── services/ One module per AI provider
src-tauri/src/services/myservice.rs implementing the AiService trait (use claude.rs as a template).pub mod myservice; to src-tauri/src/services/mod.rs.all_services() in lib.rs.refresh_service / refresh_all_services in commands.rs.SERVICES array in +page.svelte.docker compose -f docker-compose.build.yml up --build
# .deb and .AppImage appear in ./dist/
macOS and Windows builds require their native environments or GitHub Actions runners.
Pull requests are welcome. For larger changes, open an issue first to discuss the approach.
npm run check # TypeScript + Svelte type-check
cargo check # Rust type-check (from src-tauri/)
npm run tauri dev # Full dev loop
MIT — see LICENSE.