The local capacity control plane for people who run coding agents all day.
Know whether each subscription will last until reset — and how much paid capacity will be left unused.
Download · Why Vibe Bar · Build from source · Agents (MCP) · Acknowledgements · 中文
Vibe Bar is a native macOS menu-bar app for subscription-powered coding agents. It connects provider-reported quota with the evidence already on your Mac: per-request tokens and cost, completed reset cycles, local sessions, models, working hours and remote-machine activity.
A quota monitor tells you what is left. A token dashboard tells you what happened. A session browser finds an old conversation. Vibe Bar keeps that chain intact, so the same local source of truth can help you plan the next run, explain the last one and recover its context.
| The question | Vibe Bar's connected answer |
|---|---|
| Will this quota survive the reset window? | A personal forecast blends provider quota observations, recent burn, completed reset cycles and your real weekday/hour pattern. It reports Learning, Enough, Watch, At risk or Surplus, with a confidence band instead of false precision. |
| Who actually used it? | Billing capacity and execution are separate axes: Claude Code and Claude Cowork may share one Claude quota, while the per-request ledger still attributes their tokens and cost to the harness that produced them. |
| Where did the work go? | The Workbench pairs a per-request ledger of harnesses, models, tokens and cost with a separate full-text session index that opens transcripts and hands a selected session back to its owning CLI. |
| Can my agents use this context? | The same quota, forecast, usage, cost, session, status and pricing data is available through a typed MCP server over a local Unix socket — no TCP port and no credential projection. |
Remote Linux probes can join the same cost and activity model without opening an inbound port; facts are encrypted to this Mac before they pass through the Relay.
Under the menu bar sits a Workbench: a per-request usage ledger across every harness, a searchable index of every local agent session with one-click resume, and a skills manager that reconciles one library across eight agent CLIs. All of it is read from files already on your Mac, and an MCP server lets your agents ask the same questions.
Every quota bar carries a verdict — Learning, Enough, Watch,
At risk or Surplus — plus a projected run-out time and the forecast's
confidence. Consumption is inferred only from provider quota observations;
token history shapes the calendar of when you tend to work, never a made-up
token-to-quota conversion. Recent slope, comparable completed cycles and the
working-hour profile are blended, while observation coverage and freshness
decide how confident the result may be.
The forecast shown at each refresh is retained as history. Provider pages can therefore compare what Vibe Bar predicted then with what actually happened, instead of recomputing the past with today's knowledge. They also show reset history as one bar per cycle, the fill curve against a time-only pace line, and local cost, model ranking, yearly activity and working-hour pattern in the same layout for every core provider.
The verdict is only as good as its history, so a freshly added provider says
Learning until enough reset cycles have been observed to trust a
projection; the forecast never claims a confidence it does not have.
Every active quota as a gauge that stays above your work — on a second display, beside a full-screen terminal, wherever you put it. Open as many mini windows as you like; each has its own display mode, its own field selection, and its own drag-arranged order. Double-click a window to cycle through the seven modes: ring gauges, compact bars, a ledger list, a one-line strip, a tile grid, a single-provider focus view, and a seven-day reset-timeline rail. Quota buckets a provider ships after this build are discovered at runtime and become selectable without an update. The surface is Liquid Glass and follows whatever is behind it.
The Misc page keeps provider-specific quota semantics simple and scannable. Supported integrations include Copilot, OpenCode Go, Ollama Cloud, OpenRouter, Kilo, Kiro, Zhipu GLM, Xiaomi MiMo, Kimi, MiniMax, iFlytek Spark, Alibaba Bailian, Volcengine Coding and Agent Plans, Tencent Hunyuan, Baidu Qianfan and Warp. Sign in through the app's own WebView, import a browser cookie, or paste a key — whatever the provider's console offers.
The popover is for a glance. The Workbench is a window you leave open. It also keeps two questions deliberately separate: which subscription owns the quota and which harness produced the request. That distinction is why shared billing pools stay readable without flattening Claude Code, Claude Cowork, Codex, ChatGPT Work and the other clients into one misleading total.
A per-request ledger across every harness on the Mac — Claude Code, Claude Cowork, Codex, ChatGPT Work, Cursor, Grok Build, AntiGravity, Gemini CLI — with real token counts split into input, output, cache write and cache read, priced from the same catalog the popover uses. Filter by harness, model and range; drag the navigator to focus the chart while five simultaneous donut cards explain Token Flow, Harness, Provider, Project and Model distribution. The tables keep the full window and include a project ranking.
Every local agent session, indexed with full-text search over prompts,
replies and tool calls, grouped by project, filtered by company, harness or
time. Open one and the transcript is beside it, with a find bar and page
controls that stay fast on transcripts with tens of thousands of lines;
Open hands the session back to its own CLI (claude --resume,
codex resume, grok --resume, agy --conversation).
Deleting a session from here is the one change Vibe Bar ever makes to a harness's session files, and only at your explicit request — see Privacy and local data.
One shared library at ~/.agents/skills/, reconciled across Codex, Claude
Code, Gemini CLI, AntiGravity, Grok Build, Cursor and Muse Code. Each row separates the
harness's effective state from Vibe Bar's symlink/copy: native-disabled skills
show a pause badge, while a skill still visible through another compatibility
root shows a link badge instead of a false “off”. Right-click a harness dot to
choose native enable/disable or projection removal. Install from a ZIP, adopt
skills a CLI already has, discover more from a repository, and back up before
anything is replaced.
Everything is one two-column window. Three panes are worth a picture:
Layout arranges the cards of every popover page — which cards are shown, which column, which order — with an explicit Visibility menu, per-card eyes, presets and a live preview, so the Overview can be the four quotas you watch and nothing else.
Menu Bar chooses what the menu bar item itself says — icon only, one line, two rows or compact — which quota windows it shows, and whether the colour follows the forecast or the raw percentage.
Menu Bar Health shows what AppKit requested versus what macOS actually placed, the status-item/window/menu-bar heights, the Control Center allow-list audit, and whether alerts were suppressed. It can re-enable monitoring, copy the narrow repair command, or repair and re-register the status item without terminating the app's MCP connections. An explicit opt-in can run that same narrow repair automatically after three consecutive blocked probes.
MCP Server is the agent side of the app, covered next.
Vibe Bar can answer your coding agent's questions about your own usage. While the app runs it exposes a read-only MCP server on a Unix domain socket in your home directory — no network port, no API key — so Claude Code, Codex CLI, Cursor or any stdio MCP client can ask "how much Claude do I have left?", "who burned the most tokens this month?" or "find my session about the parser". The tool surface covers live cached quota and forecasts, usage summary/trend/request rows, cost history, session search, provider status and effective model pricing.
Set it up by pasting this into any agent that can fetch a URL:
Fetch and execute the appropriate instructions to set me up for Vibe Bar from https://raw.githubusercontent.com/AstroQore/vibe-bar/main/docs/agent-setup/prompt.md
Or configure it by hand — every client runs the same command:
claude mcp add --scope user vibebar -- "/Applications/Vibe Bar.app/Contents/MacOS/VibeBar" --mcp-stdioEverything agents can reach is read-only except an opt-in "refresh my quota"
tool and an opt-in skill installer; credentials are never exposed and emails
are masked. The socket is created 0600 inside the 0700 ~/.vibebar/,
is never bound to a network interface, and is removed when Vibe Bar quits.
The separate VibeBar Probe watches supported CLI logs on a systemd Linux machine without opening an inbound port. Facts are buffered locally, encrypted to this Mac's Core, and routed through an opaque Relay that never sees plaintext. Each machine stays out of your totals until you switch Include in totals on; then its usage joins this Mac's in the Overview and the cost pages.
See the Remote Probe guide for installation, enrollment, updates, rollback and the end-to-end encryption model.
Vibe Bar can draw your quota and usage on a Dot. Quote/0 panel and keep it up to date on a schedule. It is the same data the popover shows, laid out for a 296 × 152 electrophoretic display you read across a desk: eight presets — Ledger, Rings, Rail for quota; Usage Tiles, Split, Table, Dual, Trend for usage — each in any of the four orientations, shown as a single slide or as a carousel that rotates through several. A carousel runs either way round: Device loop lets the panel do the rotating between slides Vibe Bar keeps filled, and App timer keeps one slot and swaps what is in it on a schedule of your choosing. Settings previews every slide at 1:1 before anything is sent, and only pushes when the panel's content has actually changed, so a panel showing the same numbers is not woken to redraw them.
Alerts appear as an extra carousel card and disappear when the condition clears. Device groups run two or more panels as a single display: they share one row in the display list, one set of settings and one page list, and each page chooses whether the screens draw one template combined across them or a separate template each. Quota selections automatically continue onto additional pages instead of stopping at five items. See device group setup and timing limits.
Two things have to exist in the Dot. app first, and neither can be created from here:
- An API key, from the Dot. app's developer settings.
- At least one "Canvas API" item in the device's LOOP task. The API writes into a slot that already exists; it cannot add one, and a fixed task will not work — it has to be the LOOP task. How many you need depends on the mode: a single slide and an App timer carousel use one, because the app decides what goes in that one slot; a Device loop carousel needs one per slide, since the panel is rotating between real slots. Spare slots are not wasted but they are not free either — Vibe Bar claims each one and marks it unused, so it cannot sit there showing yesterday's numbers. Vibe Bar scans the loop and says how many it found, so you can add what is missing and re-scan.
The key goes straight into the macOS Keychain and nowhere else: the
settings file records only that a key exists. Vibe Bar's own state for the
feature is one file, ~/.vibebar/eink_state.json, which holds what was last
pushed and the panel's last reported status — never the key, never the key's
prefix.
Your quota and usage numbers go through Dot.'s servers. The panel has no
local API: the rendered slide — its quota percentages, reset times and token
or cost figures, as JSON — is posted to dot.mindreset.tech with your Dot.
API key, and the service draws it onto your device. None of that happens until
you add a key and switch the feature on, and no other Vibe Bar feature sends
your quota or usage anywhere (the privacy list below has the app's other
outbound paths). If the trade is not one you want, leave it off; every other
surface works exactly the same without it.
Cadence follows the panel's own power. On USB power it refreshes every 15 minutes; as soon as the device reports it is running on its battery, the interval stretches to 60 minutes, because a panel that redraws four times an hour on a cell does not last the week. Both numbers are yours to change, and Push now ignores the schedule entirely.
Text on the panel is English and written out in full — "5 Hours", not "5h". The device has no language setting, and a word you have to decode from across the room costs more than the pixels it saves.
| Surface | Quota and status | Cost and activity |
|---|---|---|
| ChatGPT / Codex | Codex subscription windows, Spark, OpenAI status | ~/.codex/sessions/**/*.jsonl |
| ChatGPT Chat | Image Generation, Deep Research and estimated Chat-model counts; setup | Saved cloud Chat history (Work excluded) |
| Claude Code / Cowork | 5 Hours, Weekly, per-model weekly, Anthropic status | ~/.claude/projects/**/*.jsonl, Claude.app's Cowork transcripts |
| Gemini + AntiGravity | Gemini Web quotas, local AntiGravity language-server quotas | Local Gemini / AntiGravity usage records |
| Grok + Cursor | Grok quota, Cursor Models and Other Models, Grok Bot weekly, SpaceXAI + Cursor status | Local Grok records, Cursor account usage events; Grok Bot is quota-only |
| Devin | Cognition's Daily and Weekly windows from the devin CLI's plan cache; Devin status |
~/.local/share/devin/cli/sessions.db (CLI and Devin app), costed by model |
| Mistral Vibe | Mistral AI's Monthly window from a console.mistral.ai browser session; Mistral status | ~/.vibe/logs/session/*/meta.json, costed at Mistral's API rates |
| Muse Code | Meta AI's 5 Hours and Weekly windows, read with the muse CLI's login once macOS allows it; Meta Model API status |
~/.local/share/muse/sessions/**/session.jsonl — tokens, costed at Meta's API rates (a subscription has no per-token bill) |
| Muse | Meta AI's Weekly window and plan from a muse.ai browser session, through the web app's own subscription request (its per-deployment id is found in muse.ai's public scripts and cached); no public status page | Muse.app's cached main chat (~/Library/Caches/ConversationCache/hatch-*.json) as read-only sessions — no model or token counts, so no cost |
| Misc providers | Each provider's own coding- or token-plan endpoint | Quota-only unless an adapter exposes local usage |
Provider contracts change without notice. Vibe Bar keeps refresh errors visible, keeps the last known good snapshot, and never presents stale data as a successful update.
Every picture on this page is the real app, launched in its demo mode:
the same binary, pointed at a home directory built by
Scripts/demo_home.py. The quota, forecast, cost and
ledger numbers are one maintainer's real usage, copied; everything that would
identify a person — account ids, machine names, paths, sessions, cookies,
Keychain items — is replaced or fabricated, and every refresh that would
leave that directory is switched off. The agent sessions and skills are
written for the occasion. Scripts/capture_demo_screenshots.sh
opens each surface in both appearances and captures it over a flat backdrop;
DemoMode.swift is the switch.
Vibe Bar is a macOS-native app and intends to stay one: the menu bar, the Liquid Glass Mini Window, and the Workbench are built directly on AppKit and SwiftUI, not approximated through a web view.
For Windows and Linux there is a second client,
Vibe Bar Desktop — Tauri
and Rust, same product, same data. On a Mac where both are installed it reads
the same ~/.vibebar data root — one set of provider accounts, one set of
settings, no second copy to maintain — and it runs standalone on a machine
that has never had the native app.
Desktop writes only inside its own client/desktop/ namespace today, so it
never edits what this app owns. Both clients holding the shared root open for
writing is a separate piece of work: this app loads settings.json once at
launch and rewrites it whole, so it would neither see nor merge another
client's edit.
Desktop is still being built up to this app and carries its own 0.x version
until it gets there. At parity the two adopt one shared MAJOR.MINOR, and
every feature release ships from both repositories together; patch versions
stay independent so either client can fix its own bugs without waiting for
the other. Nothing about that client changes this one: this repository is the
complete implementation and the reference for what parity means.
One product, two clients. The binding rule is the minor version: the same
MAJOR.MINOR means the same features. Patch versions diverge freely — each
client fixes its own bugs at its own pace — and build numbers are always
independent.
Two things are exempt from parity, and only these two:
- Bug fixes.
- Features with no equivalent on another platform at all. Needing a
different implementation is not an exemption: Keychain becomes DPAPI or
libsecret, Sparkle becomes the Tauri updater,
SMAppServicebecomes each platform's autostart. Those are the same feature, built differently.
This table lists only where the two differ. Anything not here is at parity — the quota hierarchy, tray percentages with your own fields and labels, session search and transcripts, mini-window geometry, and so on. A new feature on either side must appear here until it lands on both.
Until then. Desktop is 0.x and this contract is not yet in force: the
native app ships feature minors freely while Desktop closes the table below.
When Desktop reaches parity with the native minor of the day, both ship the
next minor together as the first joint release — and from that point neither
client ships a feature minor the other cannot.
Legend: ● full · ◐ partial · ○ not yet · — exempt
| Feature | macOS native | Desktop | Note |
|---|---|---|---|
| Quota | |||
| Live provider fetch | ● 25 | ◐ 10 | Desktop reads the rest from the shared cache, labelled as such |
| Browser-cookie providers | ● | ○ | Windows blocks third-party cookie reads; explicit import there |
| Observation and forecast history | ● | ◐ | Desktop records observations and draws the reset-history strip; the quota history chart with its brush is not ported |
| Service status sources | ● 5 | ● 4 | |
| Menu bar / tray | |||
| Rich-text and two-row title | ● | — | Windows and Linux trays have no title at all, only an icon |
| Field editor with style scopes | ● | ○ | |
| Control Center allow-list watchdog | ● | — | macOS 26 platform behaviour |
| Main window | |||
| Provider detail pages | ● 4 | ◐ | Desktop has a page per company with its quota and status. This app's pages also carry that provider's cost cards and history charts |
| Arrangeable module waterfall | ● 11 | ○ | |
| Layout editor with presets | ● | ○ | |
| Mini window | |||
| Layouts | ● 7 | ◐ 1 | ring, compact, ledger, strip, tile, focus, rail. Desktop has the ring |
| Multiple independent windows | ● | ○ | |
| Translucent surface | ● Liquid Glass | ○ | Planned as a platform blur, deliberately not a copy. The window is currently opaque and undecorated |
| Workbench | |||
| Usage charts, donuts, breakdown tables | ● | ○ | Desktop draws the reset-history strip but no usage charts |
| Session deletion | ● | ○ | |
| Resets: risk view | ● | ◐ | Desktop lists resets with each one's forecast; the calendar and the risk grouping are not ported |
| Skills: install, import, discover, backups | ● | ◐ | Desktop is a read-only inventory |
| Cost and usage | |||
| Local usage scan | ● 10 harnesses | ◐ 3 | Codex, Claude Code, Gemini CLI. Counts harnesses with a local scanner: Cursor's usage comes from dashboard events and Grok Bot has no usage source at all, so neither is a local scan on either side |
| Per-request ledger, multi-source pricing, history | ● | ○ | Desktop keeps an in-memory aggregate |
| Settings | |||
| Writable | ● | ○ | Shared writes need the cross-client storage contract |
| Provider credential panes | ● 27 | ○ | |
| Platform | |||
| MCP tools | ● 12 | ◐ 5 | Read-only subset |
| Remote probe sync | ● | ○ | |
| E-ink displays (Dot. Quote/0) | ● | ○ | Pushes quota and usage to a paired panel on a schedule |
| Launch at login | ● | ○ | |
| In-app updates | ● Sparkle | ○ | Planned on the Tauri updater |
| App Sandbox | ○ by design | ○ for now | Neither ships sandboxed. Native cannot: reading browser cookies, probing AntiGravity with ps/lsof, and driving Terminal by Apple events are all blocked inside it, and the release script refuses a sandboxed bundle. Desktop needs none of that while it stays read-only, so it is the one that could — an option that closes as soon as it grows cookie providers |
| Windows and Linux | — | ◐ | Core is tested on all three; the GUI has only had a macOS pass |
Vibe Bar is one app built from two SwiftPM targets plus one package of its own that lives in a separate repository.
| Piece | What it is | Where it lives |
|---|---|---|
VibeBarApp |
The menu-bar item, the popover, the Mini Window, the Workbench, Settings. AppKit + SwiftUI. | This repository |
VibeBarCore |
Quota, usage, cost, pricing, forecasting, provider adapters, remote sync — everything testable without a window. | This repository |
agent-session-kit |
Reading what the coding agents left on disk: session discovery and parsing per harness, the full-text session index, deletion planning, harness naming, and the local MCP Unix-socket / stdio transport. | Separate public repository |
The kit was extracted from this repository so that the "what did my agents
actually do" half is usable — and auditable — on its own. It knows nothing
about quotas, plans or prices; that vocabulary stays in VibeBarCore. It has
no third-party dependencies and is AGPL-3.0-only, same as Vibe Bar.
The kit now ships two implementation lanes: the Swift package this app links,
and a Rust crate that Vibe Bar Desktop links. They are peers rather than a
port — anything both must agree on, such as the session index schema, lives in
the kit's contracts/ directory with a test on each side, so the two clients
cannot drift into reading the same file differently.
How a kit release reaches you. Package.swift pins the kit to an exact
tag and SwiftPM links it statically — it is compiled into the executable, not
shipped as a framework you could swap. A new kit release changes nothing on
your Mac until Vibe Bar bumps that pin and ships a build. Settings › System
› Components shows the kit version compiled into the build you are running,
with a Check for kit updates button; nothing checks at launch or on a
timer.
Vibe Bar has no telemetry pipeline and no hosted plaintext analytics backend. Local and remote-Probe usage analysis stays on this Mac. The optional hosted account/control service stores workspace, enrollment, Relay directory and audit metadata only. Derived state stays under:
~/.vibebar/
├── settings.json
├── quotas/
├── cost_snapshots/
├── scan_cache/
├── pricing_sources/
├── pricing_cache.json
├── quota_limits.json
├── service_status.json
├── usage_events.sqlite3
├── session_index.sqlite3
├── remote_core.json
├── remote_usage.sqlite3
├── cost_history.json
├── eink_state.json
└── mcp.sock (only while the app runs, mode 0600)
- CLI credential and session files are read-only inputs. The one exception is whole-session deletion from the Workbench's Sessions page, performed only at your explicit request and never editing a session file's contents.
- The Skills manager writes to
~/.agents/skills/, six managed harness skill roots, and the narrow native skill fields in Codex/Claude/Gemini/Grok/Muse Code/Mistral Vibe user config. Every config patch is backed up under~/.vibebar/skill_backups/. - Vibe Bar-owned cookies and provider secrets live inside one versioned Keychain Vault, not one prompt-generating item per secret.
- E-ink displays are the only feature that sends your quota or usage figures
anywhere, and only once you add a key and switch it on. The panel has no
local API, so each rendered slide is posted to
dot.mindreset.techwith your Dot. API key and drawn onto the device there. The key lives in the Keychain Vault;eink_state.jsonholds a hash of what was last drawn and the panel's last reported status. - The other things Vibe Bar sends out are narrow and each is yours to start:
a Skills search sends your query to
skills.sh; enrolling a remote machine posts its name and public keys; remote sync posts acknowledgement cursors to the Relay, which cannot read the payloads it carries. Provider refreshes send your own credentials to the providers you configured, and nothing else. - Privacy Mode clears derived cost data and keeps cost history off disk while enabled. Retention is configurable, and Cost Data can be cleared manually.
Vibe Bar intentionally runs without the App Sandbox: browser-cookie
import and the local AntiGravity language-server probe require capabilities
the sandbox blocks. The app is open source and reads only the provider inputs
it needs; local writes stay under ~/.vibebar/, the Keychain Vault and the
explicit Skills allowlist above, and what it sends out is the short, itemized
list above. See
AGENTS.md for the
full trade-off.
- Download the Apple-silicon ZIP from GitHub Releases.
- Move
Vibe Bar.appto/Applications. - Launch it from Applications or Spotlight.
Release builds are ad-hoc signed and not notarized. If Gatekeeper blocks the first launch, right-click the app and choose Open. No Apple Developer account is required to build or run Vibe Bar locally.
Installed builds check the signed update feed once a day and always ask before installing. Settings › System chooses between the stable Main channel and the preview Dev channel; Dev also receives every Main release. Check for Updates… is in the menu-bar item's context menu and in Settings.
Requirements: macOS 26+, Xcode 26, Swift 6.2+.
git clone https://github.com/AstroQore/vibe-bar.git
cd vibe-bar
swift test
./Scripts/build_app.sh release
open ".build/Vibe Bar.app"The package contains the VibeBar executable and the testable VibeBarCore
library. The packaging script assembles .build/Vibe Bar.app, copies its
resources and the Sparkle framework, and ad-hoc signs the bundle.
- CONTRIBUTING.md — concise human contributor guide.
- AGENTS.md — complete repository rules for coding agents.
- AGENT-PR.md — branch, verify, push, and open a PR.
- AGENT-DEPLOY.md — build, package, verify, and optionally install on a Mac.
- SECURITY.md — report vulnerabilities without exposing secrets.
Provider APIs and quota contracts move quickly; focused adapters, fixtures and UI refinements are welcome.
Vibe Bar is an independent project, but it stands on work shared by the wider coding-agent community:
- CodexBar is the primary technical reference for the macOS menu-bar quota experience. Several browser-cookie and Keychain utilities, selected provider behaviors, and the AntiGravity local-probe flow were adapted from or reimplemented with reference to it.
- CC Switch informed the unified Skills workflow and remains an interoperability reference for existing cross-agent skill layouts.
- CodexBar compatibility notes record the provider migration boundary, the read-only bridge, and what its CLI does.
- CLIProxyAPI and its ecosystem informed our understanding of multi-provider CLI account and quota workflows. Vibe Bar does not embed, launch, or require CLIProxyAPI.
- ccusage informed local session-cost parsing and pricing semantics.
- LiteLLM, models.dev, and Portkey Models maintain the public model-pricing catalogs Vibe Bar refreshes and merges for cost attribution. AstroQore VibeBar Model Pricing carries the small Vibe Bar-specific supplement layer, plus the few corrections that outrank a wrong public price, and AstroQore VibeBar Quota Limits the published per-plan allowances no provider reports itself (ChatGPT Chat's Pro-model limits), refreshed on the same schedule.
Vibe Bar also directly uses SweetCookieKit for local browser cookie access and Sparkle for signed app updates. See THIRD_PARTY_NOTICES.md for the relationship and license details; complete applicable license texts live under Resources/ThirdPartyLicenses and are included in packaged app bundles. These projects are independent from Vibe Bar; acknowledgement does not imply affiliation or endorsement.
Vibe Bar is licensed under the GNU Affero General Public License v3.0 only.
























