{"slug": "omnicouncil-zero-api-cost-local-moa-desktop-app-for-mac", "title": "OmniCouncil – Zero-API-cost local MoA desktop app for Mac", "summary": "OmniCouncil, a local-first Mixture-of-Agents desktop app for macOS, drives the official claude, codex and agy CLIs non-interactively using the user's own subscription sign-ins, so no separate API keys or per-token billing are required. The app runs workers in parallel in Judge Mode, where a Judge model receives anonymized and shuffled answers and returns a structured verdict with a consensus score of 1.0, 0.5 or 0, and triggers a second review by a model from a different vendor on low confidence or zero consensus. A persistent warm process pool skipped cold starts and was 31–36% faster end to end in the developer's tests, and the app warns users to check each provider's terms because requests count against their plan's usage limits.", "body_md": "**A local-first Mixture-of-Agents desktop app for macOS.**\nAsk Claude, Gemini and Codex at once. They answer independently or debate, and a Judge model returns one verdict with a measured consensus score.\n\nImportant\n\nOmniCouncil drives the vendors' official CLIs (`claude`, `codex`, `agy`) non-interactively, signed in with **your own** accounts. Requests count against your plan's usage limits, and each provider's terms for this kind of use differ and can change. **Check the terms of every provider you connect before using OmniCouncil.**\n\nDifferent models get different things wrong. Asking several models and having a strong model judge the results can catch mistakes that one model alone would miss — and makes disagreement visible instead of hiding it behind one confident answer.\n\n- **🔌 No separate API keys or per-token billing.** Every model call goes through an official CLI using the subscription sign-in you already have. API keys are removed from each CLI's environment (`env_unset` ), so a call is never silently billed to an API account instead.\n- **⚖️ Two modes: Judge and Co-work**  - **Judge Mode:** workers answer in parallel without seeing each other. The Judge receives the answers**anonymized and shuffled** , and returns a structured verdict with a**consensus score** (`1.0 🟢 / 0.5 🟡 / 0 🔴` ) and a confidence level. Low confidence*or* zero consensus triggers a**second review by a model from a different vendor** .\n  - **Co-work Mode:** a multi-round discussion. Each round, every worker sees the other (anonymous) participants' answers and revises, adds to or keeps its own. If the Leader still finds a dispute, it issues guidance and the discussion gets extra rounds.\n- **🖥️ Native macOS GUI.** A dark, minimal PySide6 app: the final answer is the main body of each reply, with every agent's raw answer, timing and the Judge's analysis folded away until you open them. Saved history, follow-up questions with context, attachments and voice notes, an English/Chinese interface and a global hotkey (`⌘⇧J` ).\n\n| **Warm process pool** | Persistent CLI processes skip cold starts (31–36% faster end to end in our tests). Sessions are reset between runs, so questions never share context. | \n| **Honest consensus** | With only one usable answer, the UI says *\"Insufficient quorum · not cross-validated\"* instead of showing a perfect score. | \n| **Prompt-injection hygiene** | Worker answers and attachment text are passed to the Judge as length-capped, clearly delimited **untrusted data** . | \n| **Multimodal input** | Images, PDFs, text and voice notes. The Leader turns them into text first; workers only see plain text. | \n| **Per-worker models** | Switch any worker between fast and heavy models (e.g. Haiku ↔ Opus) from a dropdown. | \n| **Account & usage dashboard** | Sign-in status, 5-hour / 7-day usage, rate-limit alerts, and a log-in / switch-account button per provider. | \n| **Terminal CLI** | Everything also runs from the terminal ( `omnicouncil ask …` ). | \n\n|  | Three chat tabs | OmniCouncil | \n|---|---|---|\n| Ask every model | Copy-paste into each tab | One question, sent to all in parallel | \n| Compare answers | You read and judge them yourself | A Judge compares them, blind and shuffled | \n| See disagreement | Easy to miss | Measured consensus score, flagged in the UI | \n| Second opinion | Ask another model yourself | Automatic, from a different vendor, on low confidence or no consensus | \n| One model is down or rate-limited | That tab just fails | Isolated: the others continue, the failure is shown | \n| Follow-ups and history | Separate per tab | One thread, saved locally, reopened exactly | \n| Attachments | Upload to each tab | Parsed once by the Leader, shared as text | \n\n[llm-council](https://github.com/karpathy/llm-council) popularized this idea: models answer, review each other's answers anonymously, and a Chairman model writes the final answer. OmniCouncil takes a different route on a few points:\n\n|  | llm-council | OmniCouncil | \n|---|---|---|\n| Model access | OpenRouter API key, pay-per-token credits | Official CLIs with your existing subscriptions | \n| Interface | Local web app (FastAPI + React) | Native macOS desktop app + terminal CLI | \n| Review step | Every model ranks the others (anonymized) | One Judge scores consensus (anonymized, shuffled); a different-vendor reviewer on low confidence or no consensus | \n| Discussion | — | Co-work mode: multi-round debate with dispute guidance | \n| Speed | API calls | Warm pool of persistent CLI processes | \n| Also | — | Attachments, voice, history, usage dashboard, i18n, tests + CI | \n| Status | Stated by the author: \"99% vibe coded\", no support | Maintained; contributions welcome | \n\n``` php\nflowchart LR\n    U([User]) -->|question · files · voice| GUI[\"Desktop GUI<br/>omnicouncil.gui<br/>PySide6 + qasync\"]\n    T([Terminal]) --> TCLI[\"Terminal CLI<br/>omnicouncil.cli<br/>Typer + Rich\"]\n\n    GUI --> E\n    TCLI --> E\n\n    subgraph E[\"Engine (output-free, event-driven)\"]\n        direction TB\n        PRE[\"multimodal<br/>Leader reads attachments\"]\n        CTX[\"orchestrate<br/>context injection\"]\n        ORC{\"Mode\"}\n        PRE --> CTX --> ORC\n    end\n\n    ORC -->|Judge: parallel| W\n    ORC -->|Co-work: N rounds,<br/>anonymous peers| W\n\n    subgraph W[\"CLI Workers · subscription logins\"]\n        direction TB\n        W1[\"claude\"]\n        W2[\"agy · Gemini\"]\n        W3[\"codex\"]\n    end\n\n    POOL[(\"pool<br/>persistent processes\")] -.-> W1\n    W -->|answers| BL[\"blind + bounded<br/>untrusted data\"]\n    BL --> J[\"Judge / Leader<br/>JSON verdict + consensus\"]\n    J -->|low confidence<br/>or no consensus| R[\"Second review (other vendor)<br/>or extra Co-work round\"]\n    R --> V\n    J --> V[\"Final verdict\"]\n    V --> GUI\n    V --> DB[(\"SQLite<br/>data/history.sqlite\")]\n```\n\nEvery model call is a local subprocess, `argv` only (never through a shell), with its own timeout. Workers that fail (for example at a usage limit) are dropped from later rounds without blocking the others. Closing the app terminates every child process.\n\nDoes asking several models and judging the results actually help? A first **pilot** on 20 randomly sampled [MMLU-Pro](https://huggingface.co/datasets/TIGER-Lab/MMLU-Pro) questions (10-option multiple choice, graded by exact match; workers: Claude Code default model, Gemini 3.8 Flash, Codex `gpt-5.6-sol`; Judge: Claude Opus):\n\n| System | Accuracy | 95% CI | Median time / question | Model calls / question | \n|---|---|---|---|---|\n| Claude (best single worker) | 19/20 = 95% | 76–99% | 4.0 s | 1 | \n| **Claude Opus alone** (the Judge model, no council) | 18/20 = 90% | 70–97% | 4.8 s | 1 | \n| Majority vote of the three workers | 17/20 = 85% | 64–95% | 15.9 s | 3 | \n| **Judge mode** | **20/20 = 100%** | 84–100% | 26.1 s | 4.1 | \n| Co-work mode (first 10 questions) | 9/10 = 90% | 60–98% | 65.7 s | 9.9 | \n\nWhat it suggests:\n\n- **The council fixed both questions the Judge model got wrong on its own.** On one, all three workers agreed on the right answer and the Judge followed them. On the other, no worker was right and they disagreed completely (consensus 0); that triggered the different-vendor second review, which reached the correct answer on its own.\n- **The Judge beat a plain majority vote 3 times and never overturned a correct majority.** Once it sided with a correct minority answer against two agreeing workers.\n- **It costs time and calls:** ~4 model calls and ~26 s per question versus one call and a few seconds. Co-work was slower still and no more accurate here.\n\n**This is a pilot, not proof:** with 20 questions every confidence interval overlaps, and one sample is no substitute for hundreds of questions across domains. Full results: [`evals/pilot-2026-10/`](https://github.com/OmniCouncil/OmniCouncil/blob/main/evals/pilot-2026-10). Reproduce or extend it (uses your subscription quota):\n\n```\npython evals/run_eval.py --n 200 --cowork 50\npython evals/run_eval.py --augment evals/results/<run>/results.jsonl   # add a \"Judge model alone\" baseline\n```\n\n- \n**macOS** (the GUI, global hotkey and voice recording use macOS APIs; tested on macOS 15).\n- \n**Python 3.9+** (3.11+ recommended — 3.9 is past end-of-life).\n- \n**At least one of these CLIs** , installed and signed in with your subscription:Provider CLI Sign in Anthropic [Claude Code](https://claude.com/claude-code) ·`claude`` claude auth login`OpenAI [Codex CLI](https://github.com/openai/codex) ·` codex``codex login` Google [Antigravity](https://antigravity.google) CLI ·`agy` run `agy` once and follow the promptsAgents whose CLI is missing are skipped automatically. Two signed-in CLIs are enough to compare answers.\n\n**With pipx** (recommended — isolated, adds the `omnicouncil` and `omnicouncil-gui` commands):\n\n```\npipx install git+https://github.com/OmniCouncil/OmniCouncil.git\nomnicouncil-gui\n```\n\n**From a clone** (for development):\n\n```\ngit clone https://github.com/OmniCouncil/OmniCouncil.git\ncd OmniCouncil\npython3 -m venv .venv && source .venv/bin/activate\npip install -e \".[dev]\"\npython gui.py            # or: omnicouncil-gui\n```\n\n**As a macOS app** (built locally with [Briefcase](https://briefcase.readthedocs.io/)):\n\n```\npip install briefcase\nbriefcase build macOS                    # → build/omnicouncil/macos/app/OmniCouncil.app (~465 MB)\nbriefcase package macOS --adhoc-sign     # → a .dmg in dist/\n```\n\nThe app is ad-hoc signed, not notarized: the first time, right-click it and choose **Open**. Launched from Finder, it picks up your login shell's `PATH`, so it finds the CLIs just like a terminal would.\n\nOn first launch, `config.json` is created from the bundled template. Installed via pipx, OmniCouncil keeps its files in `~/Library/Application Support/OmniCouncil`; run from a clone, it uses `./config.json` and `./data`. `OMNICOUNCIL_HOME` overrides both.\n\n- Type a question and press **Enter** (Shift+Enter for a new line).\n- The **settings panel** chooses the mode, the workers, each worker's model, the Leader, and the second-review / extend-discussion option.\n- 📎 attaches files and 🎤 records a voice note; the Leader reads them before the workers start.\n- Click **Process** on any reply to see each agent's raw answer, timing, the Judge's analysis and which anonymous label was which model.\n- **⌘⇧J** brings the window to the front from anywhere.\n\n```\nomnicouncil ask \"Which is larger, 9.11 or 9.9?\"               # Judge Mode\nomnicouncil ask -m cowork -r 3 \"Is a tomato a fruit?\"          # Co-work Mode, 3 rounds\nomnicouncil ask -l \"Gemini 3.1 Pro\" \"...\"                      # pick the Leader\nomnicouncil ask --model Claude=haiku -v \"...\"                  # override a model, print commands\nomnicouncil ask -f invoice.png \"What is the total due?\"        # attachments\nomnicouncil config --show                                      # agents, models, install status\n```\n\n(From a clone without installing, use `python main.py` instead of `omnicouncil`.)\n\n1. \nEvery enabled worker answers on its own, in parallel.\n2. \nThe Judge receives the answers **anonymized (\"Assistant A/B/…\") and in random order** , each inside`<answer>` tags that the prompt declares untrusted. It returns JSON:`{\"consensus_score\": 1.0 | 0.5 | 0 | null, \"confidence\": \"...\", \"analysis\": \"...\", \"final_answer\": \"...\"}`Score Meaning `1.0` 🟢Every agent's core answer is the same `0.5` 🟡A majority agrees, but at least one answer is clearly different `0` 🔴No majority; the answers all differ — Only one answer: *insufficient quorum, not cross-validated*Malformed output is still parsed: from code fences, by matching braces, or with regex fallbacks.\n3. \nIf confidence is **Low** , or the answers show**no consensus** (score 0), a reviewer from a**different vendor** is picked automatically, and its verdict replaces the first.\n\n1. **Round 1:** independent answers.\n2. **Rounds 2–N:** each worker gets the question, its own previous answer and the other participants' answers under anonymous, per-run-stable labels, and revises, adds to or keeps its answer.\n3. **Leader summary** (blind, like the Judge). If confidence is still Low or there is no consensus, the Leader's dispute guidance becomes the focus of another round, up to`cowork_max_rounds` .\n\n`config.json` controls everything. Main fields:\n\n| Field | Description | \n|---|---|\n| `workers[].command` | The CLI argument list; `{prompt}` marks where the prompt goes | \n| `workers[].available_models` /`selected_model` /`model_flag` | Model dropdown options; the flag is inserted right before the prompt | \n| `workers[].env_unset` | Environment variables removed for this CLI only (e.g. `ANTHROPIC_API_KEY` , so Claude uses your subscription) | \n| `*.web_search` | Let the agent search the web (default on). Claude gets only the read-only `WebSearch` /`WebFetch` tools, pre-approved; Codex gets`--search` .`agy` has no safe switch (opening pages needs a permission that non-interactive runs deny) | \n| `*.is_persistent` | Run the agent in the warm pool (supported: `claude` ;`agy` optional) | \n| `leaders[].file_flag` /`file_types` | How the Leader receives attachments and which kinds it can read | \n| `mode` | `judge` or`cowork` | \n| `cowork_rounds` /`cowork_max_rounds` /`cowork_extend` | Co-work round settings | \n| `review_on_low_confidence` | Second review in Judge Mode | \n| `hotkey` | Global hotkey, e.g. `cmd+shift+j` or`option+space` | \n| `language` | `en` or`zh` | \n\n**Custom prompts:** every prompt is an editable file in [`omnicouncil/prompts/`](https://github.com/OmniCouncil/OmniCouncil/blob/main/omnicouncil/prompts) (`<name>.<lang>.md`). To change one, copy it to `<OMNICOUNCIL_HOME>/prompts/` with the same name and edit the copy; it overrides the built-in version.\n\n- **OmniCouncil has no backend and stores its own data locally** — history, attachments, recordings and the usage cache live in`data/` (or`~/Library/Application Support/OmniCouncil/data` ).\n- **Your prompts, conversation context and attachment contents are still sent to the model providers you select** , through their CLIs, under those providers' privacy terms. Local storage does not mean the data never leaves your machine.\n- No credential files are read: account status comes from each CLI's own status command.\n- Claude-based workers and Leaders get no file or memory tools — only the read-only web tools when web search is on. Only attachment pre-processing enables the `Read` tool, limited to the attachment folder.\n- With web search on, search queries are sent to the provider's search service as well.\n\nSee [SECURITY.md](https://github.com/OmniCouncil/OmniCouncil/blob/main/SECURITY.md) for the threat model and how to report a vulnerability.\n\n- **Microphone** (voice notes): the first recording asks for permission for the app you launch OmniCouncil from (Terminal, iTerm, VS Code…). If it doesn't ask, or recordings are silent:*System Settings → Privacy & Security → Microphone* , enable that app, and restart it.\n- **Global hotkey:** uses Carbon`RegisterEventHotKey` , which needs no Accessibility permission. If the combination is taken, choose another in`config.json` .\n\n```\npip install -e \".[dev]\"\npytest                    # ~100 tests, all with fake CLIs — no model calls, no quota\npython -m pyflakes omnicouncil tests\nomnicouncil/\n  orchestrate.py   Judge mode, blind answer formatting, context injection, reviewer choice\n  cowork.py        Co-work mode\n  multimodal.py    attachment pre-processing\n  pool.py          warm pool (stream-json persistent processes)\n  runner.py        one model call: pool or one-shot subprocess, structured-output adapters\n  parsing.py       verdict parsing with fallbacks\n  prompts.py       prompt loading (prompts/*.md, user overrides)\n  config.py        config loading, validation, migration\n  storage.py       SQLite history (schema v2)\n  accounts.py      account status, usage limits, login helpers\n  cli.py           terminal CLI · cli_render.py  rich rendering\n  gui.py           desktop app · hotkey.py  global hotkey · i18n.py  UI strings\nevals/run_eval.py  accuracy / latency / cost evaluation\ntests/             pytest suite\n```\n\nSee [CONTRIBUTING.md](https://github.com/OmniCouncil/OmniCouncil/blob/main/CONTRIBUTING.md) before opening a pull request.\n\n- **Depends on the CLIs:** their flags and output formats can change between versions; usage counts against your plan's limits. Respect each provider's terms of service.\n- **Uneven pool support:**`codex` has no stable persistent mode, so it always runs one-shot.\n- **macOS only** for now.\n\n[MIT](https://github.com/OmniCouncil/OmniCouncil/blob/main/LICENSE) © 2026 OmniCouncil", "url": "https://wpnews.pro/news/omnicouncil-zero-api-cost-local-moa-desktop-app-for-mac", "canonical_source": "https://github.com/OmniCouncil/OmniCouncil", "published_at": "2026-10-04 22:59:09+00:00", "updated_at": "2026-10-04 23:13:00.576704+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "large-language-models", "developer-tools", "ai-products"], "entities": ["OmniCouncil", "Anthropic Claude", "Google Gemini", "OpenAI Codex", "PySide6", "Andrej Karpathy", "llm-council", "macOS"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/omnicouncil-zero-api-cost-local-moa-desktop-app-for-mac", "markdown": "https://wpnews.pro/news/omnicouncil-zero-api-cost-local-moa-desktop-app-for-mac.md", "text": "https://wpnews.pro/news/omnicouncil-zero-api-cost-local-moa-desktop-app-for-mac.txt", "jsonld": "https://wpnews.pro/news/omnicouncil-zero-api-cost-local-moa-desktop-app-for-mac.jsonld"}}