Drive four external coding CLIs — Google's Antigravity (Gemini 3.6 Flash), OpenAI Codex, the GitHub Copilot CLI, and Cursor — as sub-agents inside Claude Code. Text answers, image generation, real repo work, and parallel swarms, on quota you already pay for. One MCP server, four backends. It exposes Google Antigravity, OpenAI Codex, the GitHub Copilot CLI, and Cursor to Claude Code as clean MCP to
npx mdskills install SinanTufekci/agent-intern@SinanTufekci? Sign in with GitHub to claim this listing.Bridges four major AI coding CLIs as MCP tools with robust multi-backend orchestration and parallel execution
1<div align="center">23# Claude Code × Antigravity + Codex + Copilot + Cursor — MCP Bridge45<img src="assets/bridge-animation.svg" width="100%" alt="Claude Code bridging Google Antigravity, OpenAI Codex, GitHub Copilot, and Cursor" />67**Drive four external coding CLIs — Google's [Antigravity](https://antigravity.google/) (Gemini 3.6 Flash), [OpenAI Codex](https://developers.openai.com/codex/), the [GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/copilot-cli), and [Cursor](https://cursor.com/cli) — as sub-agents inside [Claude Code](https://claude.com/claude-code). Text answers, image generation, real repo work, and parallel swarms, on quota you already pay for.**89[](https://github.com/SinanTufekci/agent-intern/actions/workflows/ci.yml)10[](https://pypi.org/project/agent-intern/)11[](https://pepy.tech/projects/agent-intern)12[](LICENSE)13[](https://www.python.org/)14[](https://modelcontextprotocol.io/)15[](https://glama.ai/mcp/servers/SinanTufekci/agent-intern)16[](https://antigravity.google/)17[](https://developers.openai.com/codex/)18[](https://docs.github.com/en/copilot/how-tos/copilot-cli)19[](https://cursor.com/cli)20[](#requirements)21[](https://github.com/sponsors/SinanTufekci)2223</div>2425---2627One MCP server, **four backends**. It exposes Google Antigravity, OpenAI Codex, the GitHub28Copilot CLI, and Cursor to Claude Code as clean MCP tools so you can delegate work to a different model29family mid-task — without leaving your terminal, and on the subscriptions you already have. Each backend30is independent: install one, two, three, or all four.3132- **🛰️ Antigravity (`agy`, Gemini 3.6 Flash High).** Fast, cheap tool-calling — and the **only**33 backend with an image model. Its headless print mode (`agy -p`) historically had a **stdout bug**:34 it wrote the answer to the *controlling terminal* instead of its stdout, so anything capturing35 stdout got nothing (and, under a TUI, agy's text leaked into the host's prompt). **agy 1.0.15 fixed36 this on Windows** — `-p` now writes the clean answer to stdout — so the bridge **prefers stdout** and37 falls back to reading agy's *own* transcript files only when stdout is empty (older agy, non-Windows,38 or `--sandbox` runs). It still **detaches agy from the terminal** so older versions can't leak.39- **🤖 Codex (`codex exec`, OpenAI).** A strong reasoner for real code/repo work. It writes its final40 message straight to a file the bridge asks for (no scraping), supports **model selection**, and has41 a **real, enforced sandbox**.42- **🐙 Copilot (`copilot -p`, GitHub).** GitHub's agentic coder. Stdout-native like Codex (`-s`43 prints just the answer), with **model selection** (`--model`), a **best-effort** tool/path44 permission knob, and a deterministic resume mechanism (the bridge sets each session's UUID itself).45- **✳️ Cursor (`cursor-agent -p`, Cursor).** Cursor's agentic coder, with the **widest model menu** —46 GPT, Claude, Grok, and Composer via `--model` (validated against `cursor-agent models`). Stdout-native47 like Codex/Copilot (`--output-format text` prints just the answer), an **agent-enforced** sandbox48 (read-only via `--mode ask`), and a deterministic resume mechanism (the bridge mints each chat's id49 itself via `create-chat`). No image model.5051All four share the same niceties: a `*_continue` to resume a thread, a [live "watch" window](#watch-mode)52to see the agent work, a unified [`agent_swarm`](#swarm) that runs many tasks in parallel **across53all backends at once**, and `*_status` diagnostics that spend no quota.5455> [!WARNING]56> **This runs unsandboxed code with your privileges.** `agy -p` auto-executes its tools57> (read/write files, run shell commands, reach the network) with **no usable approval gate** — its58> `--sandbox` blocks only *shell commands*, leaving file writes and network egress wide open.59> `codex exec` also runs autonomously, but its `sandbox` flag (default `read-only`) **is** a real,60> enforced boundary. `copilot -p` runs headless with `--allow-all-tools`; its `sandbox` maps to61> **best-effort** tool/path permissions (read-only denies the local write/shell tools) — safer than62> agy, but **not** an OS sandbox like Codex's. `cursor-agent -p` runs headless with `--trust` (and63> `--force` for writes); its `sandbox` is **agent-enforced** (read-only = `--mode ask`, which makes the64> write/shell tools unavailable) — best-effort like Copilot, **not** an OS sandbox. In all four cases65> the `workspace` argument is a *starting context*, **not** a security boundary. Only use these with **trusted prompts on trusted66> content**; for real isolation, run the bridge inside a container or VM. **[Full details →](#security)**6768## Why you'd want this6970| | |71|---|---|72| 🧠 **Second opinion** | Ask a different model family — Gemini *or* GPT — mid-task without switching tools. |73| 🎨 **Image generation** | Have Gemini draw an image and get the saved file back — no extra API key or image tool. |74| 🛠️ **Real coding sub-agent** | Hand a focused repo task to Codex with a real `workspace-write` sandbox. |75| 💸 **Cheap delegation** | Burn Antigravity / Codex quota on grunt work instead of Claude tokens. |76| 🐝 **Parallel fan-out** | Run N tasks at once, mixing Gemini and Codex workers in a single swarm. |77| 📁 **Cross-repo reads** | Point a worker at another project directory and let it read/answer there. |78| 🔌 **Zero new auth** | Piggybacks the logins you already did — no keys for the bridge to manage. |7980## The four backends at a glance8182The bridge normalizes all four CLIs into the same shape, but they differ where it matters. Pick per task:8384| | 🛰️ **Antigravity** (`agy`) | 🤖 **Codex** (`codex exec`) | 🐙 **Copilot** (`copilot -p`) | ✳️ **Cursor** (`cursor-agent -p`) |85|---|---|---|---|---|86| **Model** | Selectable via `model` (agy's `--model`); Gemini 3.6 Flash (High) default (see [Model & auth](#model--auth)) | Selectable via `model` (codex's `-m`) | Selectable via `model` (`--model`) | Selectable via `model` (`--model`), validated against `cursor-agent models` |87| **Best at** | Fast, cheap tool-calling; quick answers | Heavier reasoning; real code/repo work | Agentic coding; real code/repo work | Agentic coding; wide model menu (GPT/Claude/Grok/Composer) |88| **Image generation** | ✅ `antigravity_image` (+ `antigravity_image_swarm`) | ❌ no image model | ❌ no image model | ❌ no image model |89| **Sandbox** | ❌ no real boundary (`--sandbox` blocks only shell) | ✅ real, enforced: `read-only` / `workspace-write` / `danger-full-access` | ⚠️ best-effort: tool/path permissions (`read-only` denies write/shell) — **not** an OS sandbox | ⚠️ agent-enforced: mode/force (`read-only` = `--mode ask`, write/shell tools unavailable) — **not** an OS sandbox |90| **How the answer is read** | `--output-format json` on agy 1.1.8+ (`stream-json` when watching); else stdout, else scraped from `transcript.jsonl` | Written to a file via `-o/--output-last-message` | stdout (`-s` silent mode) | stdout (`--output-format text`) |91| **Continue mechanism** | Pins the workspace's conversation id (`--conversation`) | Resumes the session id (`codex exec resume <id>`) | Resumes a self-set session UUID (`--session-id`) | Mints a chat id (`create-chat`) and resumes it (`--resume <id>`) |92| **Auth** | OS credential store (AI Pro session) | `codex login` (ChatGPT account or API key) | OS credential store (`copilot login`) or a GitHub token env | `cursor-agent login` (OS credential store) or `CURSOR_API_KEY` |93| **In a swarm** | Runs with an isolated `HOME` to avoid state races | Fresh one-shot — needs no isolation | Fresh one-shot — needs no isolation | Fresh one-shot — needs no isolation |9495## How it works9697All four backends run **headless** and one-shot per call; the bridge's job is to get a clean answer98out of each and hand it to Claude Code as a plain string.99100```mermaid101flowchart LR102 A([Claude Code]) -- "MCP tool call" --> B["bridge<br/>(server.py)"]103 B -- "antigravity_*" --> C[agy -p]104 B -- "codex_*" --> D[codex exec]105 B -- "copilot_*" --> E[copilot -p]106 B -- "cursor_*" --> F[cursor-agent -p]107 C -- "json / stream-json (1.1.8+)<br/>else stdout or transcript.jsonl / .db" --> B108 D -- "output-last-message file" --> B109 E -- "stdout (-s silent)" --> B110 F -- "stdout (--output-format text)" --> B111 B -- "plain text" --> A112```113114**Antigravity.** On agy **1.1.8+** the bridge asks for structured output and reads a contractual115field instead of guessing: plain calls use `--output-format json` and return its `response`, while116[watch mode](#watch-mode) uses `--output-format stream-json` and rebuilds the answer from the stream's117terminal `result` event (the same shape the [Cursor bridge](#cursor) already used). Both also carry a118`conversation_id`, which the bridge records so `antigravity_continue` pins **exactly** the thread it119last ran in that workspace.120121Older agy has no such flag, so the original path stays: on **1.0.15+** (Windows) `agy -p` writes its122clean answer to stdout and the bridge returns that; on older agy — or non-Windows, or a `--sandbox`123run — stdout is empty and the bridge falls back to agy's own transcript at:124125```126~/.gemini/antigravity-cli/brain/<conv-id>/.system_generated/logs/transcript.jsonl127```128129For that fallback it locates the conversation via `cache/last_conversations.json` (falling back to the130newest `brain/` directory touched since launch), streams the transcript, and returns the final131`source=MODEL, status=DONE, type=PLANNER_RESPONSE` entry — the answer, minus the intermediate132tool-calling steps (or the SQLite `.db` agy dual-writes, when no JSONL exists). This fallback still133runs on 1.1.8+ whenever a run yields no `result`, so nothing depends on the structured path alone.134135**Codex.** `codex exec` is well-behaved: the bridge passes `-o/--output-last-message <file>` and136codex writes its final message straight there — no scraping. Continue works by capturing the session137id from codex's own rollout files (`~/.codex/sessions/.../rollout-*.jsonl`) and resuming with138`codex exec resume <id>`, falling back to the newest on-disk session for that cwd after a server139restart.140141**Copilot.** `copilot -p "<prompt>" -s` runs a prompt non-interactively and prints the clean final142answer to stdout — the bridge reads it there, no scraping. It runs headless with `--allow-all-tools143--no-ask-user --no-auto-update` (so it never blocks on a prompt), and disables copilot's flaky144builtin GitHub-API MCP by default for predictable latency (`COPILOT_GITHUB_MCP=1` re-enables it).145Continue is **deterministic**: copilot's `--session-id <uuid>` both *sets* a new session's id and146*resumes* an existing one, so the bridge generates the UUID itself, pins it to the workspace, and147resumes that exact session — falling back after a restart to the newest on-disk session148(`~/.copilot/session-state/<id>/workspace.yaml`) whose recorded `cwd` matches.149150**Cursor.** `cursor-agent -p --output-format text --trust "<prompt>"` runs a prompt non-interactively151and writes the clean final answer straight to stdout — the bridge reads it there, no scraping152(`--trust` trusts the workspace so it never blocks on a prompt). Continue is **deterministic and153race-free**: `cursor-agent create-chat` mints a fresh chat and prints its id, so the bridge mints the154id itself, pins it to the workspace, and resumes that exact chat with `-p --resume <chatId>` — no155rollout-scraping. After a restart it falls back to the newest on-disk chat under156`~/.cursor/chats/<md5(workspace)>/<chat-id>/` whose `meta.json` `cwd` matches (the chat-dir hash is157itself md5 of the workspace path).158159## Set up in 60 seconds160161**Prerequisites — install whichever backend(s) you want, and sign in once each:**162163- **Antigravity:** install `agy` and sign in to Antigravity once (via the IDE or `agy -i`).164- **Codex:** install `codex` and run `codex login` once (ChatGPT account or API key).165- **Copilot:** install `copilot` (`npm i -g @github/copilot`, or `winget install GitHub.Copilot`)166 and run `copilot` then `/login` once (or set a `COPILOT_GITHUB_TOKEN`/`GH_TOKEN` env var).167- **Cursor:** install `cursor-agent` (`curl https://cursor.com/install -fsSL | bash`) and run168 `cursor-agent login` once (or set a `CURSOR_API_KEY` env var).169170You don't need all four — the tools for a missing CLI simply report "not found" via their `*_status`171tool.172173### Recommended — no clone, you control updates174175With [`uv`](https://docs.astral.sh/uv/) installed, register the bridge straight from176[PyPI](https://pypi.org/project/agent-intern/) under `mcpServers` in `~/.claude.json` — no177path to hardcode, no `git pull` to remember:178179```json180"agent-intern": {181 "command": "uvx",182 "args": ["agent-intern"]183}184```185186uvx pins to the version it first caches and does **not** auto-upgrade, so you never run an update you187didn't choose — important, since the bridge runs [unsandboxed code](#security): a surprise (or188compromised) release can't execute until you opt in. When the startup check warns that a newer189release is out, upgrade deliberately and restart Claude Code:190191```bash192uvx agent-intern@latest # fetch + run the newest release (refreshes uv's cache)193```194195> [!TIP]196> Prefer hands-off auto-updates? Put `"args": ["agent-intern@latest"]` in the config instead —197> every launch runs the newest release. Convenient, but it pulls new code without asking each time.198199### From source200201Clone it instead if you want to hack on the bridge or pin a local copy:202203```bash204git clone https://github.com/SinanTufekci/agent-intern.git205cd agent-intern206pip install fastmcp207python test_smoke.py # 4 real round-trips (ask, continue, image, swarm) — prints four PASS lines208```209210> [!NOTE]211> The smoke test costs a tiny bit of quota and takes ~30–60 s. It exercises the Antigravity path.212213Then point Claude Code at the absolute path to `server.py` under `mcpServers` in `~/.claude.json`:214215<table>216<tr><th>Windows</th><th>macOS / Linux</th></tr>217<tr><td>218219```json220"agent-intern": {221 "command": "python",222 "args": ["C:\\path\\to\\server.py"]223}224```225226</td><td>227228```json229"agent-intern": {230 "command": "python3",231 "args": ["/path/to/server.py"]232}233```234235</td></tr>236</table>237238Restart Claude Code. **Fifteen tools** appear, each prefixed `mcp__agent-intern__`:239240- **Antigravity (5):** `antigravity_ask`, `antigravity_continue`, `antigravity_image`,241 `antigravity_image_swarm`, `antigravity_status`242- **Codex (3):** `codex_ask`, `codex_continue`, `codex_status`243- **Copilot (3):** `copilot_ask`, `copilot_continue`, `copilot_status`244- **Cursor (3):** `cursor_ask`, `cursor_continue`, `cursor_status`245- **Shared (1):** `agent_swarm` — fans a list of tasks out across **all four** backends in one run246247The single-prompt tools — Antigravity, Codex, Copilot, **and** Cursor — take a **`watch=true`** flag248for the live browser view ([Watch mode](#watch-mode)).249250> [!NOTE]251> **Your client learns how to use the bridge on its own.** The server ships MCP *instructions* — a252> short routing guide (when to reach for each tool, which backend to pick, and to pass `workspace` so253> the sub-agent has repo context) that a client like Claude Code injects into the model's context on254> connect, as an "MCP Server Instructions" block. So the host model knows how and when to drive these255> tools without you explaining them — you can just ask for the result.256257> *"Use antigravity_ask to summarize the README of this repo in three bullets."* → Claude routes the258> prompt through the bridge, agy reads the file under the workspace root, and the answer comes back259> as a plain string. Swap in `codex_ask`, `copilot_ask`, or `cursor_ask` to have GPT, Copilot, or Cursor260do the same.261262## Tools263264### 🛰️ Antigravity265266| Tool | Purpose |267|---|---|268| `antigravity_ask(prompt, workspace?, model?, timeout_s?=180, watch?=false)` | Start a **new** Antigravity conversation. `model` selects the model (agy's `--model`, e.g. `"claude-sonnet-4-6"`); validated against `agy models`, defaults to your `settings.json` model. `watch=true` opens the live browser view ([Watch mode](#watch-mode)). |269| `antigravity_continue(prompt, workspace?, model?, timeout_s?=180, watch?=false)` | Continue the conversation **rooted at `workspace`** (pinned by id). agy's model is per-invocation, so `model` can differ from the original ask. `watch=true` opens the live view. |270| `antigravity_image(prompt, output_path?, workspace?, timeout_s?=240, watch?=false)` | Generate an image; saves the file (extension corrected to the real bytes) and returns its path + format/size. `watch=true` streams progress and **shows the image** inline. |271| `antigravity_image_swarm(prompts, output_paths?, workspaces?, max_concurrency?=4, timeout_s?=240, watch?=false)` | Generate **several images in parallel** (one worker per prompt). |272| `antigravity_status()` | Setup diagnostics: **the bridge's own version + whether a newer release is available**, plus agy version/compat, state dirs, and newest-transcript readability. Spends no quota. |273274### 🤖 Codex275276| Tool | Purpose |277|---|---|278| `codex_ask(prompt, workspace?, sandbox?="read-only", model?, timeout_s?=180, watch?=false)` | Start a **new** Codex session. `sandbox` is a **real** boundary (see [Codex bridge](#codex-bridge)); `model` selects the model (`-m`). `watch=true` opens the live view, streaming codex's steps from its `--json` event stream. |279| `codex_continue(prompt, workspace?, timeout_s?=180, watch?=false)` | Continue the Codex session **rooted at `workspace`** — resumes the exact session id, falling back to the newest on-disk session for that cwd after a server restart. The resumed session keeps its original sandbox and model. `watch=true` opens the live view. |280| `codex_status()` | Setup diagnostics: codex version, login status (`codex login status`), sessions dir. Spends no quota. |281282### 🐙 Copilot283284| Tool | Purpose |285|---|---|286| `copilot_ask(prompt, workspace?, sandbox?="read-only", model?, timeout_s?=180, watch?=false)` | Start a **new** Copilot session. `sandbox` maps to copilot's tool/path permissions (**best-effort**, not an OS sandbox — see [Copilot bridge](#copilot-bridge)); `model` selects the model (`--model`). `watch=true` opens the live view, streaming copilot's steps from its `--output-format json` event stream. |287| `copilot_continue(prompt, workspace?, sandbox?="read-only", timeout_s?=180, watch?=false)` | Continue the Copilot session **rooted at `workspace`** — resumes the exact self-set session id, falling back to the newest on-disk session for that cwd after a restart. Unlike Codex, `sandbox` applies here too (copilot re-applies permissions each turn). `watch=true` opens the live view. |288| `copilot_status()` | Setup diagnostics: copilot version, an auth hint (no `login status` command exists, so best-effort), session-state dir. Spends no quota. |289290### ✳️ Cursor291292| Tool | Purpose |293|---|---|294| `cursor_ask(prompt, workspace?, sandbox?="read-only", model?, timeout_s?=180, watch?=false)` | Start a **new** Cursor chat. `sandbox` maps to cursor's mode/force flags (**agent-enforced**, not an OS sandbox — see [Cursor bridge](#cursor-bridge)); `model` selects the model (`--model`, validated against `cursor-agent models`). `watch=true` opens the live view, streaming cursor's steps from its `--output-format stream-json` event stream. |295| `cursor_continue(prompt, workspace?, sandbox?="read-only", timeout_s?=180, watch?=false)` | Continue the Cursor chat **rooted at `workspace`** — resumes the exact chat id the bridge minted (`create-chat` + `--resume`), falling back to the newest on-disk chat for that cwd after a restart. `watch=true` opens the live view. |296| `cursor_status()` | Setup diagnostics: **the bridge's own version + whether a newer release is available**, plus cursor version and login status (`cursor-agent status`). Spends no quota. |297298### 🐝 Shared299300| Tool | Purpose |301|---|---|302| `agent_swarm(tasks, max_concurrency?=4, timeout_s?=180, watch?=false)` | Run **several tasks in parallel across all four backends** — each task names its `backend` (`antigravity`, `codex`, `copilot`, or `cursor`) plus a `prompt` (an optional `model` for any backend, and `sandbox` for Codex/Copilot/Cursor). Every answer comes back in one block; `watch=true` opens the live dashboard ([Swarm](#swarm)). |303304`workspace` defaults to the MCP server's current working directory. Point it at a real project dir305for context-aware answers — every backend gives the model access to files under that root (Codex,306Copilot, and Cursor honoring their `sandbox`).307308`antigravity_image` forces agy to save to an explicit absolute path — without one, agy309falls back to its own scratch dir (`~/.gemini/antigravity-cli/scratch/`). It then310corrects the file extension to match the real bytes: agy's image model picks the311format itself (JPEG for photo-like images, PNG for flat graphics), so a requested312`out.png` may come back as `out.jpg`. The returned path always reflects the true313format.314315<a id="codex-bridge"></a>316317## 🤖 Codex bridge — the well-behaved sibling318319`codex exec` writes its final message to a file the bridge asks for via `-o/--output-last-message`,320so the answer comes back without any scraping (where agy needed a transcript workaround before 1.0.15321fixed its stdout). Three things make Codex worth reaching for over Antigravity:322323- **Real sandbox.** `sandbox` accepts `read-only` (default — reads and answers, writes nothing),324 `workspace-write` (may edit files under the workspace), or `danger-full-access` (no sandbox —325 avoid). Unlike agy's no-op `--sandbox`, codex's `-s` actually enforces this. `codex exec` has no326 interactive approval gate, so this flag **is** your safety boundary — opt into write access327 deliberately.328- **Model selection works.** `model` maps to codex's `-m`. (agy's `--model` works in print mode too329 as of 1.0.16; all four backends now expose the same `model` knob.)330- **Stronger reasoning.** Codex is a coding agent, not an image model — there's no `codex_image`. Its331 strength is reasoning and real code/repo work; hand it the jobs that need a heavier model.332333**Auth.** Uses your existing Codex login (ChatGPT account or API key). Run `codex login` once; check334with `codex_status`. No new keys for the bridge to manage.335336> [!WARNING]337> `codex exec` runs the model as an **autonomous agent with no interactive approval gate**. The338> `sandbox` flag (default `read-only`) is the real boundary, but `workspace-write` /339> `danger-full-access` let it modify files — and a swarm runs N agents at once. Only use it with340> **trusted prompts on trusted content**.341342<a id="copilot-bridge"></a>343344## 🐙 Copilot bridge — GitHub's agentic coder345346The GitHub Copilot CLI (`copilot`, from `@github/copilot`) is stdout-native like Codex:347`copilot -p "<prompt>" -s` runs a prompt non-interactively and prints just the final answer to348stdout, so the bridge reads it there — no scraping. What makes it worth reaching for:349350- **Model selection.** `model` maps to copilot's `--model`; `auto` lets Copilot pick. Unlike the agy351 and cursor tools, the bridge **can't validate this** — copilot exposes no non-interactive model352 list — and the working set is **account-dependent**: on a Copilot Pro account here, `auto` worked353 while `gpt-5.3-codex`, `claude-sonnet-4.6`, and even GitHub's own `--help` example `gpt-5.4` were all354 rejected as "not available". So omit `model` (account default) or pass `auto` unless you know your355 plan's ids; an unavailable one errors immediately with copilot's message, costing a call.356- **Deterministic, race-free continue.** copilot's `--session-id <uuid>` both **sets** a new session's357 id and **resumes** an existing one, so the bridge generates the UUID itself and pins it to the358 workspace — no rollout-scraping. After a restart it falls back to the newest on-disk session359 (`~/.copilot/session-state/<id>/workspace.yaml`) whose recorded `cwd` matches.360- **Fast by default.** Runs with `--allow-all-tools --no-ask-user --no-auto-update`, and disables361 copilot's builtin GitHub-API MCP (`--disable-builtin-mcps`) because its flaky HTTP connect can stall362 a call up to ~60 s. Set **`COPILOT_GITHUB_MCP=1`** to keep it (for Copilot's issue/PR/repo tools).363364**Sandbox is best-effort, not enforced.** Unlike Codex's OS sandbox, copilot's boundary is365tool/path permissions. The `sandbox` knob maps to copilot flags for a uniform cross-backend field:366367- **`read-only`** (default) — auto-approves tools so it runs headless, then **denies** the local368 `write` and `shell` tools (`--deny-tool`). Best-effort: it is **not** an OS sandbox, and network/MCP369 tools can still act. For a **hard** read-only boundary, use `codex_ask` instead.370- **`workspace-write`** — writes allowed, but file access stays confined to the workspace (no371 `--allow-all-paths`).372- **`danger-full-access`** — `--allow-all` (tools + all paths + all URLs). Avoid.373374**Auth.** Uses your existing Copilot login — run `copilot` then `/login` once (stored in the OS375credential store), or set `COPILOT_GITHUB_TOKEN`/`GH_TOKEN`/`GITHUB_TOKEN` for headless use. Check376with `copilot_status`. If `copilot` isn't on `PATH` (the winget install can land off a stale `PATH`),377set **`COPILOT_BIN`** to its full path — e.g.378`%LOCALAPPDATA%\Microsoft\WinGet\Packages\GitHub.Copilot_*\copilot.exe`.379380> [!WARNING]381> `copilot -p` runs the model as an **autonomous agent** with `--allow-all-tools` (required to run382> headless). Its `sandbox` is **best-effort tool/path permissions**, not an OS sandbox — safer than383> agy, weaker than Codex's `read-only`. Only use it with **trusted prompts on trusted content**.384385<a id="cursor-bridge"></a>386387## ✳️ Cursor bridge — the widest model menu388389Cursor's agent CLI (`cursor-agent`, from [cursor.com/cli](https://cursor.com/cli)) is stdout-native390like Codex and Copilot: `cursor-agent -p --output-format text --trust "<prompt>"` runs a prompt391non-interactively and writes just the final answer to stdout, so the bridge reads it there — no392scraping (`--trust` trusts the workspace so it won't block on a prompt). What makes it worth reaching393for:394395- **The widest model menu.** `model` maps to cursor's `--model` (e.g. `auto`, `gpt-5.2`,396 `claude-opus-4-8-high`, `composer-2.5`, `cursor-grok-4.5-high`) — GPT, Claude, Grok, and Composer in397 one place, ~190 ids at the time of writing. cursor bakes the **effort and speed axes into the id**398 (`…-low` / `-high` / `-xhigh` / `-max`, each with a `-fast` twin), and also accepts a bracket form on399 the family base, e.g. `claude-opus-4-8[context=1m,effort=high]`. The bridge validates against400 `cursor-agent models` and rejects a typo up front (like agy), accepting either an exact id or a401 family base. Omit `model` to use your Cursor account default. **cursor reshuffles this list often** —402 run `cursor-agent models` (or `cursor_status`) rather than trusting an example here.403- **Deterministic, race-free continue.** `cursor-agent create-chat` mints a fresh chat and prints its404 id, and `-p --resume <chatId>` resumes that exact chat — so the bridge mints the id itself, pins it405 to the workspace, and resumes deterministically (no rollout-scraping, same idea as Copilot's406 self-set session id). After a restart it falls back to the newest on-disk chat under407 `~/.cursor/chats/<md5(workspace)>/<chat-id>/` whose `meta.json` `cwd` matches (the chat-dir hash is408 itself md5 of the workspace path).409410**Sandbox is agent-enforced, not an OS sandbox.** Like Copilot, cursor's boundary is which tools the411agent can reach, not an OS jail. The `sandbox` knob maps to cursor's mode/force flags for a uniform412cross-backend field:413414- **`read-only`** (default) — `--mode ask`: the `write` and `shell` tools are **unavailable**, so415 cursor analyzes and answers but makes no edits (verified: it refuses to write files). Agent-enforced416 and best-effort — it is **not** an OS sandbox. For a **hard** read-only boundary, use `codex_ask`417 instead.418- **`workspace-write`** — `--force`: edits and commands allowed, file access rooted at `--workspace`.419- **`danger-full-access`** — `--force --sandbox disabled` (OS sandbox off). Avoid.420421(Cursor also exposes an OS-level `--sandbox enabled/disabled`; the bridge drives the uniform field via422mode/force.)423424**Auth.** Uses your existing Cursor login — run `cursor-agent login` once (OS credential store), or425set `CURSOR_API_KEY` for headless use. Check with `cursor_status`. If `cursor-agent` isn't reliably on426`PATH` (the installer drops a `cursor-agent.CMD` shim a bare name can't launch on Windows), set427**`CURSOR_BIN`** to its full path — mirrors the `AGY_BIN`/`CODEX_BIN`/`COPILOT_BIN` overrides.428429> [!WARNING]430> `cursor-agent -p` runs the model as an **autonomous agent** with `--trust` (and `--force` when431> writes are allowed). Its `sandbox` is **agent-enforced** (read-only makes the write/shell tools432> unavailable), not an OS sandbox — safer than agy, weaker than Codex's `read-only`. Only use it with433> **trusted prompts on trusted content**.434435<a id="watch-mode"></a>436437## 👁️ Watch mode — Agent Intern (experimental)438439Pass **`watch=true`** to **any single-prompt tool** — `antigravity_ask`, `antigravity_continue`,440`antigravity_image`, `codex_ask`, `codex_continue`, `copilot_ask`, `copilot_continue`, `cursor_ask`,441or `cursor_continue` — to **watch442the agent work live in a little chat-style browser window** called **Agent Intern**. The agent443still runs headless; alongside it the bridge serves a tiny page on `127.0.0.1` and opens it in a444small, chromeless app window that renders the exchange as a **conversation**: your prompt shows as a445chat bubble, the agent's live steps stream in a collapsible "thinking" trace — its planner narration446(▸), the **real commands** it runs (`$`), and completions (✓), read live (from agy's447`--output-format stream-json` on 1.1.8+ — its transcript on older agy — or codex's / copilot's JSON448event stream, or cursor's `--output-format stream-json`) — and the final449answer arrives as a Markdown card (and, for450`antigravity_image` with `watch=true`, the generated image shown inline). A **`*_continue`** run451opens with the **prior turns of the conversation shown as history**, so it reads as one ongoing452thread rather than a blank new window. (A watched `cursor_continue` is the exception — Cursor stores453its transcript in an opaque SQLite blob, so its window opens without visible prior-turn history.)454455<div align="center">456<table>457<tr>458<td width="50%" align="center"><b>text ask / continue (agy, codex, copilot, <i>or</i> cursor)</b></td>459<td width="50%" align="center"><b><code>antigravity_image</code> — image inline</b></td>460</tr>461<tr>462<td><img src="assets/watch-ask.gif" width="100%" alt="Agent Intern chat window for a text ask: the prompt as a CLAUDE chat bubble, the agent's live steps (narration, the real commands it runs, completions) in a collapsible trace, then the final Markdown answer card"></td>463<td><img src="assets/watch-image.gif" width="100%" alt="Agent Intern chat window generating an image: the prompt bubble, the live step trace, then the finished image shown inline"></td>464</tr>465</table>466<sub>Real captures — the agent runs headless while the <b>Agent Intern</b> window renders the exchange as a chat conversation: your prompt as a <b>CLAUDE</b> bubble, live steps (▸ narration · <code>$</code> commands · ✓ completions) in a collapsible trace, then the final Markdown answer or inline image.</sub>467</div>468469- **Cross-platform & best-effort.** Prefers a Chromium browser (`--app` mode) for the470 windowed look; falls back to a normal browser window. If nothing can open, the run471 still completes and returns normally.472- **Window size.** Set **`AGY_WATCH_WINDOW_SIZE`** (e.g. `AGY_WATCH_WINDOW_SIZE=480,700`)473 to resize the window; default is `560,760`. Press **Enter / Esc** in the window to474 close it.475- **One window, reused — but concurrent runs stay separate.** Repeated *sequential*476 watch calls **reuse the already-open window** instead of stacking a new one (the open477 page resets itself for the new run; the swarm dashboard rebuilds for the new fan-out).478 A run that starts while another watched run is **still working** gets its **own479 window** instead — so two concurrent single-worker runs (e.g. a `codex_ask` and a480 `copilot_ask` at once) each stream into their own view and never clobber each other.481 If you closed the window, the next run opens a fresh one. Set **`AGY_WATCH_ALWAYS_NEW=1`**482 to force a new window every time.483- **Chat layout & history.** Prompts render as chat bubbles (labelled **CLAUDE**, since the MCP484 client writes them) — long ones clamp to a few lines with a **show more / show less** toggle — and485 answers as Markdown cards tagged with the backend (**AGY** / **CODEX** / **COPILOT** / **CURSOR**). A486 **`*_continue`** run seeds the window with487 the conversation's **prior turns**, read from each backend's own session store (agy's488 transcript, codex's rollout, copilot's `events.jsonl`; Cursor's store is opaque, so a watched489 `cursor_continue` opens without visible history). The swarm's per-worker detail490 window uses the same chat design for its one task.491- **Progress, keyboard & copy.** Each panel shows a time progress bar (elapsed /492 timeout). The swarm dashboard adds an overall done/total bar and per-row time bars;493 use **↑/↓** to select a worker and **↵** to open its detail window. Answers render494 as Markdown with a **copy** button, and a "jump to latest" badge appears if you495 scroll up.496- **Coarse, not token-level.** The backends flush their step stream in chunks, so you497 get a handful of live steps, not character streaming. The returned value is identical498 to the non-watch call. Nothing is sent anywhere but your own machine.499500<a id="swarm"></a>501502## 🐝 Swarm — run agents in parallel503504`agent_swarm` fans a list of **tasks** out to workers that run **truly505concurrently** (capped at `max_concurrency`, default 4), then returns every506worker's result in one block. Each task names its own `backend`, so a **single507swarm can mix Antigravity (Gemini), Codex, Copilot, and Cursor** workers — hand the508reasoning-heavy jobs to Codex, Copilot, or Cursor and the quick ones to Gemini, all at509once. Good for independent sub-tasks: summarise N files, ask the same question510about N repos, fix N bugs. (`antigravity_image_swarm` stays separate — it511generates N images, and only agy has an image model.)512513```514agent_swarm(tasks=[515 {"backend": "antigravity", "prompt": "Summarise src/auth.py in 2 bullets."},516 {"backend": "codex", "prompt": "Find and fix the failing test in tests/",517 "sandbox": "workspace-write", "workspace": "./repo"},518 {"backend": "copilot", "prompt": "Explain what src/api.py exposes.",519 "sandbox": "read-only", "workspace": "./repo"},520 {"backend": "cursor", "prompt": "Draft a docstring for src/utils.py.",521 "model": "auto", "workspace": "./repo"},522])523```524525<div align="center">526<img src="assets/watch-swarm.gif" width="62%" alt="Agent Swarm dashboard: workers running in parallel, each row showing its backend badge, repo, prompt, latest step and a per-worker time bar, while the overall done/total counter climbs">527<br>528<sub><code>agent_swarm(..., watch=true)</code> — one row per worker (with a backend badge); the done/total bar climbs as workers finish. Click a row (or <b>↑/↓</b> then <b>↵</b>) to pop that agent into its own window.</sub>529</div>530531**How it stays correct under concurrency.** The single-agent agy tools serialize532through a lock because agy rewrites `last_conversations.json` on every call, so533concurrent runs sharing one state dir would race. The swarm sidesteps this: each534**agy** worker runs with its **own isolated `HOME`/`USERPROFILE`**, so agy's535`brain/`, `cache/`, and `last_conversations.json` never collide — no lock needed.536Auth still works because agy reads it from the **OS credential store**, not from537`~/.gemini` (verified on agy 1.0.9). **Codex**, **Copilot**, and **Cursor** workers need no such538isolation — each is a fresh one-shot (`codex exec` with its own `-o` file; `copilot539-p` with its own self-set session id; `cursor-agent -p` with its own minted chat id). Each worker's `cwd` is its real `workspace`,540so file access is unchanged. Measured ~**2.8× speedup at 3 agy workers** (the AI Pro541backend does not serialize per-account); higher `max_concurrency` trades542quota/rate-limit pressure for wall-clock.543544- **Per-task fields** — `backend` (`antigravity`/`codex`/`copilot`/`cursor`) and `prompt`545 are required; `workspace` defaults to the server cwd; `sandbox` and `model` apply546 to **Codex, Copilot, and Cursor** (ignored for Antigravity). Swarm workers are547 **one-shot** — there is no `*_continue` for a swarm worker's session.548- **Error isolation** — a worker that fails is reported in place; the others still549 return.550- **`watch=true`** — opens a thin live **Agent Swarm** dashboard (one row per551 worker, with a **backend badge**, repo, prompt, and latest step). **Click a row**552 to pop that agent into its own window streaming its full step log.553554> [!WARNING]555> A swarm launches **N unsandboxed agents at once** — N× the prompt-injection556> "lethal trifecta" surface of a single call (see [Security](#security)). Only use557> it with **trusted prompts on trusted content**. Codex workers honor their558> enforced `sandbox`; Copilot and Cursor workers honor their best-effort `sandbox`;559> Antigravity workers have no real boundary.560561## Model & auth562563| | 🛰️ **Antigravity** | 🤖 **Codex** | 🐙 **Copilot** | ✳️ **Cursor** |564|---|---|---|---|---|565| **Model** | **Selectable** via the `model` argument (agy's `--model`, e.g. `"gemini-3.1-pro-high"`, `"claude-sonnet-4-6"`); omit to use the `"model"` field in agy's `settings.json` (**`gemini-3.6-flash-high`** by default as of 1.1.6). **agy 1.1.5 replaced the old human labels with these slugs** — the old `"Gemini 3.1 Pro (High)"` form no longer works. Switching model in `-p` used to hang (through ~1.0.14) but is **fixed as of 1.0.16**. An unknown model was silently ignored through 1.1.1 and hard-fails in `-p` as of **1.1.2**; either way the bridge validates it against `agy models` and rejects a typo up front. Flash High is speed-optimized for cheap tool-calling; pick a bigger model for heavier work. | **Selectable** via the `model` argument (codex's `-m`). codex does not hang on a switch, so model choice is a first-class knob. | **Selectable** via the `model` argument (`--model`, e.g. `gpt-5.3-codex`, `claude-sonnet-4.6`, `auto`); omit for your account default. An unavailable model errors immediately. | **Selectable** via the `model` argument (`--model`, e.g. `gpt-5.2`, `sonnet-4-thinking`, `auto`, or parameterized ids like `claude-opus-4-8[context=1m]`); a wide GPT/Claude/Grok/Composer menu, validated against `cursor-agent models` (a typo is rejected up front). Omit for your Cursor account default. |566| **Auth** | Piggybacks whatever credential store `agy` uses on your OS (Windows Credential Manager, macOS Keychain, libsecret on Linux — the bridge never touches it directly). Log in once; every call silent-auths on the **same AI Pro quota** you already pay for. | Uses your existing **Codex login** — ChatGPT account or API key. Run `codex login` once; verify with `codex_status`. | Uses your existing **Copilot login** — run `copilot` then `/login` once (OS credential store), or set `COPILOT_GITHUB_TOKEN`/`GH_TOKEN`/`GITHUB_TOKEN`. Verify with `copilot_status`. | Uses your existing **Cursor login** — run `cursor-agent login` once (OS credential store), or set `CURSOR_API_KEY`. Verify with `cursor_status`. |567568<a id="security"></a>569570## ⚠️ Security571572All four backends run the model as an **autonomous agent**. The difference is whether you get a real573boundary: Codex enforces one, Copilot and Cursor offer best-effort ones, Antigravity offers none.574575### Antigravity — no usable boundary576577`agy -p` executes its own tools — reading and writing files, running shell commands, reaching578the network — with **no approval gate**. Through agy 1.1.2 that was simply how print mode worked,579with no opt-out at all. As of **1.1.3** it is a choice the bridge makes: agy finally gates headless580tool calls, and the bridge deliberately opts out with `--dangerously-skip-permissions`, because a581gated `-p` can do no useful work (it soft-denies even a plain file read, and print mode has no way582to prompt). The posture below is therefore unchanged — assume every call runs arbitrary code with583your privileges. Re-verified empirically on **agy 1.0.9 / Windows**, with the 1.1.3 amendment noted:584585- Print mode runs out-of-workspace file writes and live network fetches **even without**586 `--dangerously-skip-permissions` — that flag was a **no-op** for `-p` through 1.1.2. As of 1.1.3587 it is **load-bearing**: without it every tool-using call is soft-denied, and the bridge now always588 passes it (it must precede `-p`, whose *value* is the prompt). There is still **no** agy flag that589 makes print mode both safe and useful.590- agy 1.0.5 integrated a permission system (its logs show `toolPermission=request-review`), but it591 **still does not gate print-mode execution** — a fresh `-p` run created a file outside the592 workspace with no prompt. agy 1.0.12 reshuffled how that permission config *merges* (per-project593 files under `~/.gemini/config/projects/` now take precedence over594 `~/.gemini/antigravity-cli/settings.json`), and 1.0.13 made "Always Approve" rule matching595 strict (non-regex) by default with a `regex:` opt-in and relaxed its redirection checks — but596 those are config/interactive-approval changes, they add no print-mode approval gate, and the597 bridge reads none of it.598- `--sandbox` is **not** a usable boundary. agy 1.0.6 fixed its propagation into `-p` (the 1.0.6/1.0.7599 changelog calls this "sandbox isolation correctly enforced") and it now **does** block terminal/600 shell command execution — but re-verified on 1.0.9 that it leaves the `write_to_file` tool and601 network **wide open**: under `--sandbox` the model still wrote a file *outside* its workspace. agy602 1.0.9 hardened the sandbox's *command* path (stricter exact-match command checks; `.git` added to603 its dangerous-paths list), but none of that closes the out-of-workspace `write_to_file` hole. On604 top of that, a `--sandbox` run whose blocked terminal command halts it writes **no JSONL605 transcript** (only the SQLite `.db`, re-confirmed on 1.0.9). The bridge can now read that `.db`,606 but still never passes `--sandbox` — it's no boundary, with file writes and network left open.607608### Codex — a real sandbox you should use609610`codex exec` also has **no interactive approval gate**, but its `sandbox` flag is a genuine boundary611that codex enforces:612613- **`read-only`** (default) — reads and answers; writes nothing. Safe for untrusted *questions* on614 trusted content.615- **`workspace-write`** — may edit files under the workspace. Opt in deliberately, per task.616- **`danger-full-access`** — no sandbox at all. Avoid.617618Because there's no approval prompt, the flag you pass **is** the safety decision — choose it per619call.620621### Copilot — best-effort, not an OS sandbox622623`copilot -p` runs headless with `--allow-all-tools` (required — otherwise it blocks on per-tool624permission prompts). Its `sandbox` maps to copilot's tool/path permission flags, which are a625**real-ish but not enforced** boundary:626627- **`read-only`** (default) — auto-approves tools to run headless, then **denies** the local `write`628 and `shell` tools (`--deny-tool`). Blocks local file edits and command execution, but it is **not**629 an OS sandbox: other tools (including network/MCP) can still act. Weaker than Codex's `read-only`.630- **`workspace-write`** — writes allowed, but file access stays confined to the workspace (no631 `--allow-all-paths`).632- **`danger-full-access`** — `--allow-all` (tools + all paths + all URLs). Avoid.633634For a **hard** read-only boundary, prefer `codex_ask`.635636### Cursor — best-effort, agent-enforced637638`cursor-agent -p` runs headless with `--trust` (and `--force` when writes are allowed). Its `sandbox`639maps to cursor's mode/force flags — an **agent-enforced**, not OS-level, boundary:640641- **`read-only`** (default) — `--mode ask`: the local `write` and `shell` tools are **unavailable**,642 so cursor analyzes and answers but makes no edits (verified: it refuses to write files). Like643 Copilot, this is agent-enforced and **not** an OS sandbox. Weaker than Codex's `read-only`.644- **`workspace-write`** — `--force`: edits and commands allowed, file access rooted at `--workspace`.645- **`danger-full-access`** — `--force --sandbox disabled` (OS sandbox off). Avoid.646647For a **hard** read-only boundary, prefer `codex_ask`.648649### What that means for you650651- The `workspace` argument is only a *starting context*, **not a security boundary** — Antigravity652 can and does act outside it; Codex is bounded by its enforced `sandbox`; Copilot by its best-effort653 tool/path permissions; Cursor by its agent-enforced mode/force.654- An Antigravity call effectively runs **arbitrary code with your user privileges**. A Copilot or655 Cursor call does too outside its best-effort denials; a Codex call does unless you keep it at656 `read-only`.657- Only invoke these with **trusted prompts on trusted content**. Untrusted input here is the classic658 prompt-injection *lethal trifecta*: private-data access + code execution + network egress.659- For real isolation, run the **whole bridge inside a container or VM**.660661The bridge itself does only cross-platform filesystem reads under `~/.gemini/antigravity-cli/`,662`~/.codex/`, `~/.copilot/`, and `~/.cursor/` — no private APIs, no token theft. The risk above is663entirely in what the sub-agents are allowed to do.664665## FAQ666667<details>668<summary><b>Is this against Google's / OpenAI's / GitHub's / Cursor's Terms of Service?</b></summary>669670It runs the **official `agy`, `codex`, `copilot`, and `cursor-agent` CLIs under your own logins** — no671private APIs, no token theft, no quota abuse. It just bridges what the CLIs already do. That said, your672AI Pro / Antigravity, OpenAI / Codex, GitHub Copilot, and Cursor ToS apply, and you're responsible for673staying within them.674</details>675676<details>677<summary><b>Do I need all four CLIs?</b></summary>678679No. Each backend is independent — install only the CLI(s) you want. The tools for a missing backend680report "not found" via their `*_status` tool (`antigravity_status` / `codex_status` /681`copilot_status` / `cursor_status`) and never crash the server.682</details>683684<details>685<summary><b>When should I use Antigravity vs Codex vs Copilot vs Cursor?</b></summary>686687Use **Antigravity** for fast, cheap tool-calling, quick answers, and **image generation** (it's the688only backend with an image model) — and it now lets you **pick the model** too (agy's `--model`). Use689**Codex** for heavier reasoning, real code/repo work, or when you want a **real, enforced690`workspace-write` sandbox**. Use **Copilot** for agentic coding on your GitHub Copilot plan, or as a691second coding opinion alongside Codex — noting its sandbox is **best-effort**, not enforced. Use692**Cursor** for agentic coding on a Cursor plan, or when you want the **widest model menu** —693GPT, Claude, Grok, and Composer, all via `model` — noting its sandbox is **agent-enforced**, like694Copilot's. All four let you choose a `model`; in a swarm you can mix all four. See695[The four backends at a glance](#the-four-backends-at-a-glance).696</details>697698<details>699<summary><b>Will it break when agy updates?</b></summary>700701Less likely now. As of **agy 1.0.15** the bridge prefers agy's **stdout** on the happy path (1.0.15702fixed the print-mode stdout bug on Windows — `-p` now writes the clean answer there), which removes703its dependence on agy's **undocumented transcript schema** for normal runs. It still falls back to704reading the JSONL transcript, or the SQLite `.db` agy dual-writes, when stdout is empty (older agy,705non-Windows, or `--sandbox` runs) — so a schema change would only bite that fallback path. Re-verified706working on **1.0.15** (stdout answer clean under tool use; transcript/`.db` fallback intact; live ask707round-trip + `antigravity_status` diagnostics pass). Still, if you rely on the fallback, pin a708known-good `agy` version.709</details>710711<details>712<summary><b>Which model does Antigravity use — can I pick it?</b></summary>713714Yes. Pass `model` to `antigravity_ask`/`antigravity_continue` (or per task in `agent_swarm`) — it maps715to agy's `--model`, taking any slug from `agy models` (e.g. `"gemini-3.1-pro-high"`,716`"claude-sonnet-4-6"`). Omit it to use the `"model"` field in agy's `settings.json`, which717defaults to **`gemini-3.6-flash-high`** as of agy 1.1.6 — speed-optimized for cheap tool-calling.718719**agy 1.1.5 renamed every model**, replacing the old human labels (`"Gemini 3.1 Pro (High)"`) with720stable slugs (`gemini-3.1-pro-high`) — the old form is no longer accepted, so pass slugs. **agy 1.1.6721then added the `gemini-3.6-flash` family and moved the default to it.** The full list, re-checked live722on 1.1.8 and unchanged since 1.1.6:723`gemini-3.6-flash-low|medium|high`, `gemini-3.5-flash-low|medium|high`, `gemini-3.1-pro-low|high`,724`claude-sonnet-4-6`, `claude-opus-4-6-thinking`, `gpt-oss-120b-medium`. Note the slug bakes in the725reasoning effort, which is why the flash and pro models appear once per level.726727agy 1.0.5 added `--model`, but through ~1.0.14 switching to a different model in `-p` **hung** the728call, so earlier bridge versions stayed single-model. **Re-verified on agy 1.0.16 that the hang is729fixed** — a Claude model answers as Anthropic Claude, a Gemini model as Gemini, each in seconds. One730caveat the bridge handles for you: agy **silently ignores an unknown model** (it falls back to the731default with no error), so the bridge validates your slug against `agy models` and rejects a typo up732front.733</details>734735<details>736<summary><b>Can it generate images?</b></summary>737738**Yes — that's the `antigravity_image` tool**, on the Antigravity backend. agy's print mode generates739real images on your AI Pro quota; `antigravity_image` drives it, saves the file to a path you choose740(or a timestamped default in your workspace), fixes the extension to match the real bytes (agy picks741JPEG or PNG itself), and returns the path. Verified on **agy 1.0.9 / Windows**. Codex has no image742model — it's a coding agent.743</details>744745<details>746<summary><b>Does it cost extra money?</b></summary>747748No. It uses the **same quota you already pay for** — AI Pro for Antigravity, your Codex plan for749Codex, your GitHub Copilot plan for Copilot, your Cursor plan for Cursor. The smoke test spends a750negligible amount.751</details>752753<details>754<summary><b>Does it stream responses?</b></summary>755756The final answer is request/response — the CLIs return it all at once, so the tools return when the757agent finishes (each call typically takes 10–30 s; Copilot's reasoning models can run longer). If you758want to *watch* the agent work as it goes,759pass **`watch=true`** to any single-prompt tool: it opens the **Agent Intern** browser window and760live-streams the agent's steps — see [Watch mode](#watch-mode). It's coarse (a handful of steps, not761token-by-token), and the returned value is identical to the non-watch call.762</details>763764<details>765<summary><b>Can I run several calls at once?</b></summary>766767The **single-agent** tools are **serialized** inside the server: agy rewrites `last_conversations.json`768on every call, so concurrent runs sharing one state dir would race and could return the wrong769conversation. A `threading.Lock` makes extra requests queue rather than race. (On agy 1.1.8+ the770bridge also records the `conversation_id` agy reports for each run and prefers it when pinning a771continue, so that resolution no longer depends on the shared file — but the lock stays, since agy's772state dir is still shared and a fresh server process starts with nothing recorded.)773774For real parallelism use **[`agent_swarm`](#swarm)** — each agy worker runs in its own isolated state775dir (and Codex/Copilot/Cursor workers need none), so they don't race and the lock isn't needed (~2.8×776at 3 workers). That's the supported way to run many calls at once, across any backend.777</details>778779## Status & caveats780781- ✅ **Verified on agy 1.1.7 and 1.1.8 — nothing broke, and 1.1.8 made the bridge sturdier.** 1.1.8782 gave print mode an `--output-format` flag (`text` | `json` | `stream-json`). The existing text path783 was confirmed live on 1.1.8 first (ask, pinned continue, and `--model` all clean), then the bridge784 switched its plain ask/continue calls to `--output-format json`, because reading a contractual785 `response` field beats trusting the layout of bare text. The real prize is the `conversation_id`786 agy returns with it: the bridge records it and **pins a later `antigravity_continue` to exactly the787 conversation it last ran in that workspace**, instead of inferring it from `last_conversations.json`788 — shared state agy rewrites for *every* session, including your own interactive TUI work in the same789 folder. Practical difference: `antigravity_continue` now resumes *the bridge's own* thread, where790 before it could land on a conversation you'd since started in the Antigravity TUI. Older agy is791 unaffected — the flag is version-gated (pre-1.1.8 has no such flag), and any non-JSON stdout falls792 back to the previous text path, so a silently-ignored flag degrades instead of crashing.793 `VERIFIED_AGY_VERSION` → `(1, 1, 8)`. Not adopted: `--json-schema` (works; nothing here needs it).794 Nothing else in 1.1.7/1.1.8 reaches the bridge — the rest is interactive-TUI, plugin-hook, and795 MCP-*client* work.796- ✅ **[Watch mode](#watch-mode) reads agy's live event stream instead of scraping its transcript.**797 On agy 1.1.8+ the watched runners request `--output-format stream-json` and consume agy's typed798 `init` / `step_update` / `result` events straight off stdout. Verified before the rewrite that they799 arrive **incrementally** (a 17 s run spread its 18 events over 12.4 s), and confirmed live that a800 watched run's step count grows while agy works. The stream carries the real command as a nested801 object (the transcript stored tool args JSON-encoded *inside a string*), streaming text fragments,802 and a `conversation_id` — so a watched run now pins later continues just like a plain one. This803 retires the timer-based transcript polling, which matters beyond tidiness: agy has announced JSONL804 is being replaced by SQLite, and watch was the last path that would have broken when it goes.805 Pre-1.1.8 agy keeps the original transcript path, re-verified live.806- ⚠️ **Behavior change: multi-step answers now include the model's narration.** agy's `response` is807 the whole turn; the old transcript scrape returned only the last planner response. Identical for a808 single-step ask, different for a chatty multi-step one (one measured run: 297 chars vs 128, the809 full answer *ending in* the old one). The full turn is now returned on every path — `response` is810 agy's own contract for what the turn produced, and the old last-step rule silently dropped content811 whenever the model did the work and then closed with a short "Done."812- ✅ **Re-verified on agy 1.1.6 — no code change needed.** 1.1.6 added the `gemini-3.6-flash` family813 to `agy models` and moved the `settings.json` default to **Gemini 3.6 Flash (High)**; the default814 path and `--model gemini-3.6-flash-high` both round-tripped clean, and the JSONL + SQLite read paths815 still match agy's unchanged conversation schema. Its one bridge-adjacent fix — print mode now816 surfacing the real conversation-creation error instead of a misleading "no active conversation" —817 only improves the diagnostic the bridge already reads on failure. Everything else (Markdown custom818 agents, `/copy` and `/codesearch` polish, background-task hardening) is interactive-TUI or819 client-side work that doesn't reach the bridge. Docs-only: the model list and default examples now820 name the 1.1.6 slugs, and the guard test advertises `gemini-3.6-flash-high` against the live list.821- ⚠️ **Verified on agy 1.1.5 — it renamed every model, so old `model` values now fail.** 1.1.5822 replaced agy's human-readable model labels with stable slugs, and `agy models` reports only those:823 `"Gemini 3.1 Pro (High)"` is now `gemini-3.1-pro-high`, and the Claude entries are824 `claude-sonnet-4-6` and `claude-opus-4-6-thinking` (the mapping is not 1:1 — check825 `agy models`, or `antigravity_status`, for the current eight). Since the bridge validates `model` against826 `agy models`, an old label is **rejected up front** with the valid list — you lose the call, not827 your money, and never silently run on the wrong model. Pass slugs and you're fine. Nothing in the828 bridge's machinery needed changing (validation was always format-agnostic — which is exactly why829 the entire test suite stayed green while every *documented example* went stale), so this release is830 docs plus one new test that checks the models we advertise against the live `agy models` list.831 Everything else in 1.1.5 is interactive-TUI, MCP-client, or background-task work that doesn't reach832 the bridge; its new `--effort` flag is a second axis we don't pass, because the slug already pins833 the effort variant.834- ✅ **Verified on agy 1.1.4** — no code change was needed. 1.1.4 relaxed the 1.1.3 headless gate so835 that `-p` now **honors your persisted `settings.json` policies** (permissions, file access, sandbox836 mode, auto-execution, artifact review) instead of blanket-denying. `--dangerously-skip-permissions`837 still overrides those policies, so the flag stays load-bearing and stays exactly where it is —838 re-verified live against a workspace deliberately **absent** from `trustedWorkspaces`, with a839 `permissions.allow` list naming neither file nor command access: a workspace file read returned the840 right contents, and a terminal command and a file write both executed. Worth knowing: that flag is841 now the only thing between a bridge call and your own `settings.json` policy, and dropping it would842 get you whatever that file says rather than 1.1.3's deny-everything. 1.1.4 also stopped `/btw`843 side-questions from leaking into the conversation list as duplicates carrying the *parent's* title —844 that list is what conversation pinning reads, so one way to resume the wrong thread is gone.845- ✅ **Verified on agy 1.1.3** — base dir, `last_conversations.json` (still keyed by workspace path),846 the `brain/.../transcript.jsonl` path, the transcript schema, and the `-p`/`-c`/`--print-timeout`847 flags are all unchanged; a live `antigravity_ask` + conversation-pinned `antigravity_continue`848 round-trip returns clean over stdout and `antigravity_status` diagnostics pass. **1.1.3 broke and849 the bridge fixed** the one thing that mattered: headless `-p` no longer auto-approves tool calls,850 it **soft-denies** them (print mode cannot prompt), so without a flag even "read `pyproject.toml`851 and report the version" returned nothing — exit 0, empty stdout, the reason only on stderr. The852 bridge now passes `--dangerously-skip-permissions` on every agy path, which restores file writes,853 terminal commands and workspace reads (a live bridge round-trip reads this repo's real version854 again). The flag **must precede `-p`**, whose *value* is the prompt — otherwise the flag *becomes*855 the prompt and the task is silently dropped. **1.1.2** also made an unresolvable `--model` hard-fail856 in `-p` instead of silently falling back to the settings.json default (the bridge's `validate_model`857 still rejects a typo up front, without spending a call). **1.1.0's** execution-mode system858 (`--mode`, `request-review`) remains a no-op for the bridge: `-p` is spawned with DEVNULL stdin, so859 that interactive gate never engages. `--sandbox` behavior is likewise unchanged (blocks the860 terminal, not file writes). The print-mode stdout path (fixed on **1.0.15**, Windows) still861 applies; the transcript stays the fallback.862- ✅ **Verified on codex-cli 0.144.1** — `codex exec`, `-o/--output-last-message`,863 `codex exec resume`, the `--json` event stream, and the `~/.codex/sessions/.../rollout-*.jsonl`864 layout the continue path reads are all in place; a live `codex_ask` round-trip + `codex_status`865 pass. (Bumped from the 0.141.0 baseline: flags, session layout and the round-trip all re-verified866 unchanged.)867- ✅ **Verified on copilot 1.0.69** — `copilot -p -s` (clean stdout answer), `--session-id`868 set-then-resume, `--model`, `--output-format json` (watch stream), and the869 `~/.copilot/session-state/<id>/workspace.yaml` layout the continue fallback reads are all in place;870 live `copilot_ask` / `copilot_continue` round-trips + a mixed `agent_swarm` pass. (Bumped from871 1.0.68: 1.0.69 adds a `--resume` convenience flag the bridge doesn't need; `--session-id` still872 both *sets* a fresh id and resumes it — re-verified live, ACK then codeword recall.)873- ✅ **Verified on cursor-agent 2026.07.08** — `cursor-agent -p --output-format text --trust` (clean874 stdout answer), `create-chat` + `-p --resume <id>`, `--model` (validated against `cursor-agent875 models`), `--output-format stream-json` (watch stream), and the876 `~/.cursor/chats/<md5(workspace)>/<chat-id>/meta.json` layout the continue fallback reads are all in877 place; live `cursor_ask` / `cursor_continue` round-trips + a mixed `agent_swarm` pass. (2026.07.09878 is installed and `cursor_status` — found, logged in, chats dir — passes with flags/layout intact; a879 fresh live round-trip was deferred, Cursor usage limit reached.)880- 🖥️ **Console-detach** — before 1.0.15 agy `-p` wrote its answer to the *controlling terminal*,881 not stdout; under a TUI that text leaked into the host's prompt (seen on 1.0.9). 1.0.15 fixed this882 on Windows (stdout now carries the answer), but the bridge still spawns agy detached883 (`CREATE_NO_WINDOW` / a new POSIX session), which prevents the leak on older/other platforms and is884 harmless on 1.0.15+.885- 💾 **SQLite migration — handled** — agy still dual-writes a `.db` per conversation; on the fallback886 path, when the JSONL transcript is absent (already true for `--sandbox` runs, and the announced887 future default) `_read_response` falls back to reading the `.db`, verified to match across 100+888 conversations. See the [FAQ](#faq).889- 🐛 **agy stdout bug — fixed on 1.0.15** — `-p` now prints the clean answer to stdout in a non-TTY890 subprocess (Windows), so the bridge prefers stdout and only scrapes the transcript when stdout is891 empty (older agy, non-Windows, or `--sandbox`). (Codex and Copilot never had this problem — both892 are stdout-native.)893- 👁️ **Watch mode is experimental** — pass `watch=true` to any single-prompt tool to open the894 **Agent Intern** window and watch the agent work live (coarse steps; image shown inline).895 Best-effort and cross-platform; see [Watch mode](#watch-mode).896- 🔒 **Sandbox** — agy's `--sandbox` blocks only shell commands, so it's no boundary and the bridge897 never passes it. **Codex's `sandbox` is real and enforced** — use it; default `read-only`.898 **Copilot's `sandbox` is best-effort** (tool/path denials, not an OS sandbox); default `read-only`.899 **Cursor's `sandbox` is agent-enforced** (mode/force; read-only = `--mode ask` makes write/shell900 unavailable, not an OS sandbox); default `read-only`. See [Security](#security).901902## Requirements903904- Python 3.10+905- **For the Antigravity tools:** [`agy`](https://antigravity.google/) 1.0.0+ on `PATH` (state-file layout re-verified on **1.0.15**) and an active Antigravity / AI Pro session906- **For the Codex tools:** [`codex`](https://developers.openai.com/codex/) on `PATH` and logged in (`codex login`) — verified on **codex-cli 0.144.1**907- **For the Copilot tools:** [`copilot`](https://docs.github.com/en/copilot/how-tos/copilot-cli) on `PATH` and logged in (`copilot` → `/login`, or a `COPILOT_GITHUB_TOKEN`/`GH_TOKEN` env) — verified on **copilot 1.0.69**908- **For the Cursor tools:** [`cursor-agent`](https://cursor.com/cli) on `PATH` and logged in (`cursor-agent login`, or a `CURSOR_API_KEY` env) — verified on **cursor-agent 2026.07.08**909910Each backend is independent — install only the CLI(s) you plan to use; the other tools simply report "not found" via their `*_status` tool.911912> [!TIP]913> If `agy` isn't reliably on `PATH` (e.g. a new terminal or reboot drops it on Windows), set the914> **`AGY_BIN`** env var to its full path and the bridge will use that instead of `"agy"` — e.g.915> `AGY_BIN=%LOCALAPPDATA%\agy\bin\agy.exe`. Likewise, set **`CODEX_BIN`** if `codex` isn't reliably on916> `PATH` (the native Windows installer puts it under `%LOCALAPPDATA%\Programs\OpenAI\Codex\bin\`), and917> **`COPILOT_BIN`** if `copilot` isn't (the winget install lands under918> `%LOCALAPPDATA%\Microsoft\WinGet\Packages\GitHub.Copilot_*\copilot.exe`). Finally, set919> **`CURSOR_BIN`** if `cursor-agent` isn't reliably on `PATH` (the installer drops a `cursor-agent.CMD`920> shim a bare name can't launch on Windows).921922The bridge uses only cross-platform Python (`Path.home()`, `subprocess`) and reads paths under923`~/.gemini/antigravity-cli/`, `~/.codex/`, `~/.copilot/`, and `~/.cursor/`, which the CLIs write the924same way on every OS. **Developed and verified on Windows; macOS and Linux should work unmodified925provided the CLIs run there.** If you test it on those platforms, please open an issue / PR to confirm.926927## 🌐 Community & Acknowledgments928929- **Qiita (Japan):** A huge thanks to `@fallout` and the Japanese developer community for featuring this project and providing invaluable feedback!930 - [Detailed Hybrid Setup Guide (Claude Code × Antigravity CLI)](https://qiita.com/fallout/items/5097f0575b58f4c69b81)931 - [Quick Installation Guide](https://qiita.com/fallout/items/d699df3d6931c07eb38d)932933> 💡 **Path Resolution Fix:** Thanks to their community's real-world testing, we identified and resolved a Windows PATH edge case where the MCP server inherits a *stale* `PATH` at startup and can't find `agy`. The `AGY_BIN` environment-variable fallback was implemented directly inspired by their report!934935## License936937[MIT](LICENSE). Do whatever you want with it.938
Full transparency — inspect the skill content before installing.