Skip to main content

Observable, resumable MCP bridge from Codex to Antigravity CLI

Project description

codex-agy-bridge

CI License: MIT

An observable, resumable MCP bridge that lets Codex delegate work to the official Antigravity CLI (agy) using the user's existing Antigravity login.

agy --print is a blocking command. Agent work can outlive an MCP tool timeout, and its useful progress normally exists only in local Antigravity trajectory files. This bridge starts a detached worker, returns a durable run_id immediately, and exposes status, transcript, result, cancellation, continuation, wait, and bounded parallel-goal tools over MCP.

Quick Install

Prerequisites:

  • Codex CLI or the Codex desktop app with local stdio MCP support
  • The official Antigravity CLI (agy), already authenticated locally
  • uv / uvx
  • tmux on macOS:
brew install tmux

Check the required commands:

codex --version
agy --version
uvx --version
tmux -V

Install the bridge from PyPI as a user-level Codex MCP server:

codex mcp add codex-agy-bridge \
  --env AGY_CMD="$(command -v agy)" \
  -- "$(command -v uvx)" codex-agy-bridge@latest

Restart Codex, then verify:

codex mcp get codex-agy-bridge
codex mcp list

Remove it with:

codex mcp remove codex-agy-bridge

Status

This project is experimental. It currently targets:

  • Codex CLI/app with local stdio MCP servers;
  • Antigravity CLI 1.0.8-compatible commands and trajectory files;
  • Python 3.11 or newer;
  • macOS plus tmux for persistent Terminal.app sessions.

Every run executes in a persistent tmux session. Terminal.app can be attached on demand without stopping the run when the window closes. Antigravity's local storage format is not a stable public API, so compatibility may require updates when the CLI changes.

Features

  • Starts long-running Antigravity work asynchronously.
  • Persists run state and logs across MCP server restarts.
  • Emits sparse durable run events and exposes agy_run_wait to avoid repeated status polling.
  • Returns bounded, sanitized transcript events without private model reasoning.
  • Opens each run in a persistent tmux session.
  • Continues an exact Antigravity conversation_id.
  • Cancels active process groups.
  • Groups named targets with bounded parallelism.
  • Deduplicates identical active start requests.
  • Keeps separate client-owned MCP server processes from terminating each other.
  • Detects authentication, rate-limit, quota, and response-timeout conditions.
  • Forwards CLI --sandbox and up to 16 --add-dir policy hints without claiming filesystem containment.
  • Discovers models, plugins, capabilities, changelog, and bridge diagnostics.
  • Starts foreground task sessions in tmux and experimental persistent --prompt-interactive sessions for occasional conversational input.

Install Details

Prerequisites

Install:

  1. Codex
  2. The official Antigravity CLI (agy), authenticated locally
  3. uv
  4. tmux for persistent terminal sessions:
brew install tmux

Confirm the required commands:

codex --version
agy --version
uv --version
tmux -V

Install in Codex from PyPI

Install the bridge without cloning this repository:

codex mcp add codex-agy-bridge \
  --env AGY_CMD="$(command -v agy)" \
  -- "$(command -v uvx)" codex-agy-bridge@latest

Paste the command exactly as shown. Do not replace $ or the text inside $(...) manually. In zsh, bash, and other POSIX-compatible shells, $(command -v agy) and $(command -v uvx) are command substitutions: the shell replaces them with the absolute paths to the installed executables. For example, the command may expand to:

codex mcp add codex-agy-bridge \
  --env AGY_CMD="/Users/alice/.local/bin/agy" \
  -- "/Users/alice/.local/bin/uvx" codex-agy-bridge@latest

Before installing, confirm that both commands are available:

command -v agy
command -v uvx

Neither command should produce empty output. If uvx is missing, install uv, which provides both uv and uvx:

curl -LsSf https://astral.sh/uv/install.sh | sh

Restart Codex, then verify:

codex mcp get codex-agy-bridge
codex mcp list

codex mcp add stores an stdio MCP server definition. When Codex starts the server, it launches the absolute uvx executable recorded by the command. uvx resolves codex-agy-bridge@latest from PyPI, creates an isolated cached environment, installs the package and its dependencies, then runs the codex-agy-bridge console script. AGY_CMD pins the bridge to the user's already-installed and authenticated agy executable.

uvx is intentionally not bundled inside codex-agy-bridge. It is the external package runner that downloads and starts the bridge, so the bridge cannot install its own runner before it is launched. Keeping uv as an explicit prerequisite also lets Astral provide the correct signed executable for the user's operating system and CPU architecture.

Ask a Codex agent to install it

Paste this prompt into Codex:

Install codex-agy-bridge as a user-level stdio MCP server on this Mac.
First verify that codex, agy, uvx, and tmux are installed, and that agy is
authenticated. Do not install missing prerequisites without asking me.
Then run:

codex mcp add codex-agy-bridge \
  --env AGY_CMD="$(command -v agy)" \
  -- "$(command -v uvx)" codex-agy-bridge@latest

Verify the saved configuration with `codex mcp get codex-agy-bridge` and
`codex mcp list`. Tell me to restart Codex so the new MCP tools are loaded.

The README is the best place for this prompt because it is visible before the repository is cloned. AGENTS.md is intended for contributors working inside the checkout and should not cause an agent to modify a user's machine merely because it read the repository instructions.

Install from GitHub

Use this when you want to try the repository version directly:

codex mcp add codex-agy-bridge \
  --env AGY_CMD="$(command -v agy)" \
  -- uvx --from git+https://github.com/varadfromeast/codex-agy-bridge \
  codex-agy-bridge

Restart Codex, then verify:

codex mcp get codex-agy-bridge
codex mcp list

Remove it with:

codex mcp remove codex-agy-bridge

Install from a local clone

Use this when developing the bridge:

git clone https://github.com/varadfromeast/codex-agy-bridge.git
cd codex-agy-bridge
uv sync --extra dev

codex mcp add codex-agy-bridge \
  --env AGY_CMD="$(command -v agy)" \
  -- uv --directory "$PWD" run codex-agy-bridge

Configuration

The local-clone codex mcp add command writes the equivalent of:

[mcp_servers.codex-agy-bridge]
command = "/absolute/path/to/uv"
args = [
  "--directory",
  "/absolute/path/to/codex-agy-bridge",
  "run",
  "codex-agy-bridge",
]
startup_timeout_sec = 30
tool_timeout_sec = 30

[mcp_servers.codex-agy-bridge.env]
AGY_CMD = "/absolute/path/to/agy"

Useful environment variables:

Variable Default Purpose
AGY_CMD agy on PATH Exact Antigravity executable
AGY_BRIDGE_STATE_DIR ~/.local/state/codex-agy-bridge Durable run and goal state
AGY_BRIDGE_AGY_ROOT ~/.gemini/antigravity-cli Antigravity conversations and trajectories
AGY_BRIDGE_MAX_PARALLEL 50 Global concurrent-run limit
AGY_BRIDGE_COMPLETION_STABILITY_SECONDS 150 Time a final marker must remain stable

MCP Tools

Tool Purpose
agy_run_start Start, continue, or open an interactive foreground Run
agy_run_wait Block until selected Runs emit sparse wake events
agy_run_observe Read full, status, transcript, or raw terminal views
agy_run_input Send input with optional event/transcript preconditions
agy_run_cancel Cancel one active Run
agy_run_result Read final result metadata or bounded result chunks
agy_goal Create goals, start targets, and read aggregate status
agy_admin Read diagnostics, models, plugins, plugin validation, and changelog

Typical call flow:

agy_run_start
  -> run_id
  -> agy_run_wait
  -> agy_run_observe(view="full") when a wait event needs inspection
  -> agy_run_observe(view="terminal") when a timeout or classifier miss looks suspicious
  -> agy_run_input(expected_event_key=..., expected_transcript_step=...)
  -> agy_run_result

Use agy_run_start with the exact conversation_id returned by a previous Run to continue. Every start and continuation also requires an absolute workspace path.

How It Works

See docs/ARCHITECTURE.md for the detailed process topology, lifecycle diagrams, and module responsibilities. See docs/MCP_VISION.md for the lean MCP control-loop vision.

Codex
  |
  | MCP over stdio
  v
server.py
  |
  v
orchestration.py -- persists state --> core.py / state.py
  |
  | starts detached Python worker
  v
runner.py --> supervision.py -- launches --> agy print/interactive
  |                         |
  |                         v
  |                  Antigravity trajectory
  |                         |
  +------ reads progress ---+
  |
  +-- persistent session --> terminal.py --> tmux --> Terminal.app
  1. server.py exposes stable MCP tools and delegates behavior.
  2. orchestration.py validates requests, enforces parallel limits, deduplicates active retries, persists initial state, and starts a detached runner.
  3. cli.py owns executable discovery, capability probing, read-only commands, and run command construction.
  4. runner.py provides the detached worker entrypoint and process adapters.
  5. supervision.py launches print or interactive mode and discovers the conversation, streams sanitized progress, observes completion, and records terminal state.
  6. core.py atomically persists JSON and reads Antigravity trajectory JSONL.
  7. terminal.py owns persistent tmux execution and Terminal.app interaction.

Each prompt receives a unique completion marker. A response is considered complete only after that marker remains the latest response for a stability window. The marker is removed before results are returned.

Core Files

Read these in this order to understand the product:

  1. src/codex_agy_bridge/server.py
    • The public MCP contract.
    • Start here to see every tool and its arguments.
  2. src/codex_agy_bridge/orchestration.py
    • The product's control plane.
    • Owns goals, concurrency, cancellation, durable reservation, and detached-run startup.
  3. src/codex_agy_bridge/run_request.py
    • The Run Request module.
    • Owns request validation, workspace normalization, execution-policy capability checks, deduplication identity, and initial persisted state.
  4. src/codex_agy_bridge/runner.py
    • The detached-worker entrypoint and process adapter.
    • Owns command construction, tmux launch, and process shutdown.
  5. src/codex_agy_bridge/supervision.py
    • The lifecycle supervision module for one run.
    • Owns conversation discovery, incremental transcript polling, progress monitoring, completion detection, timeouts, and cancellation.
  6. src/codex_agy_bridge/transcript.py
    • Provides one supervisor-owned TranscriptHarvester per conversation.
    • Retains only file identity, byte offset, a partial record, the latest step, and the latest completed response.
  7. src/codex_agy_bridge/core.py
    • The persistence and Antigravity compatibility layer.
    • Owns state paths, atomic writes, stateless transcript reads, response extraction, and bounded per-run failure classification.
  8. src/codex_agy_bridge/state.py
    • The persisted data contracts and run-state machine.
  9. src/codex_agy_bridge/terminal.py
    • The macOS terminal adapter built on tmux and AppleScript.
  10. src/codex_agy_bridge/lifecycle.py
  • Registration and stale cleanup for client-owned MCP server processes.

Public transcript requests remain stateless full reads. Provider classification only inspects bounded logs after a run exits without a response; it is never a launch preflight or persisted health gate.

The most useful tests for learning behavior are:

  • tests/test_mcp_stdio.py: real MCP initialization and tool discovery.
  • tests/test_detached_run.py: end-to-end detached run with a fake agy.
  • tests/test_orchestration.py: start deduplication and tmux session creation.
  • tests/test_runner.py: command construction, completion, and progress output.
  • tests/test_core.py: transcript parsing and provider-health behavior.
  • tests/test_terminal.py: tmux and Terminal.app command construction.

State and Observability

Run state survives MCP server restarts under:

~/.local/state/codex-agy-bridge/
  runs/<run-id>/
    state.json
    bridge.log
    agy.log
    agy.stdout.log
    agy.stderr.log
    terminal-progress.log
    session-events.jsonl
    notify.seq
  goals/<goal-id>/
    state.json
  servers/
    <pid>.json

session-events.jsonl stores sparse durable lifecycle events, and notify.seq stores the latest event id so agy_run_wait can wait on tiny marker files instead of repeatedly parsing transcripts. Old terminal run directories are swept by the janitor, preserving only durable state.

agy_run_observe(view="status", compact=false) returns diagnostic paths. agy_run_observe(view="transcript") returns bounded events by default; full event content is opt-in and length-capped. Private model reasoning fields are never exposed.

Execution Risk

Antigravity is an agentic CLI. It can read and write files, execute commands, and access the network with the current user's privileges. This bridge is not a sandbox or security boundary.

The bridge always enables Antigravity's dangerous permission-skip policy so unattended Runs do not stall on CLI approval prompts. Any dangerously_skip_permissions=false input is rejected; the only allowed value is true. sandbox=true and additional_directories are CLI policy hints forwarded as --sandbox and --add-dir; live testing with Antigravity CLI 1.0.8 showed that they do not enforce filesystem containment. A workspace scopes conversation context only.

Interactive Runs are experimental and should be used sparingly. The bridge queues submitted prompts and releases one after observing a completed planner response in Antigravity's transcript. If those private transcript event semantics change, delivery may stall. agy_run_observe(view="status") exposes the queue depth and delivery state.

Goals are an MCP scheduler implemented by this bridge. They are not an Antigravity feature, and separate targets do not share native conversation context.

The bridge does not read or copy Antigravity OAuth credentials. It invokes the installed agy binary and reads ordinary local conversation metadata and trajectory files.

Model-provider calls may cost money. MCP clients should ask for user approval before starting or continuing a run when cost consent has not already been given.

Development

git clone https://github.com/varadfromeast/codex-agy-bridge.git
cd codex-agy-bridge
uv sync --extra dev
uv run pytest
uv run ruff check .
uv build

Run the server directly:

uv run codex-agy-bridge

The server uses stdio transport. Do not print diagnostic text to stdout; it would corrupt MCP framing.

Publishing

The official MCP Registry stores metadata, not package artifacts. A pushed version tag runs .github/workflows/publish.yml, which:

  1. Verifies that the tag, Python package, and Registry metadata versions match.
  2. Runs lint, tests, build, and distribution checks.
  3. Publishes the wheel and source distribution to PyPI through GitHub OIDC.
  4. Creates a GitHub release containing both distributions.
  5. Waits for the package to become visible on PyPI.
  6. Publishes server.json to the MCP Registry through GitHub OIDC.

Before pushing the first tag, create a pending PyPI Trusted Publisher for:

  • Repository: varadfromeast/codex-agy-bridge
  • Workflow: publish.yml
  • Environment: pypi

No long-lived PyPI or MCP Registry publishing token is required.

The registry is currently in preview. See:

Compatibility

The compatibility boundary is isolated in core.py. The current reader expects Antigravity trajectory JSONL under:

~/.gemini/antigravity-cli/brain/<conversation-id>/
  .system_generated/logs/transcript.jsonl

If Antigravity completes its migration to SQLite or a local daemon API, a new adapter can replace this reader without changing the MCP tool contract.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codex_agy_bridge-0.1.4.tar.gz (57.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_agy_bridge-0.1.4-py3-none-any.whl (71.8 kB view details)

Uploaded Python 3

File details

Details for the file codex_agy_bridge-0.1.4.tar.gz.

File metadata

  • Download URL: codex_agy_bridge-0.1.4.tar.gz
  • Upload date:
  • Size: 57.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codex_agy_bridge-0.1.4.tar.gz
Algorithm Hash digest
SHA256 94bf9a4f3e9491b8e6907e0ea06d908ecac73d374da9c7b89641b317d345475e
MD5 508bdc484e98fa56a268b529dc1e45ae
BLAKE2b-256 13992ea13e465e0ecb6e8c3324f1bdfdb094590b2934702526efd3adaa844173

See more details on using hashes here.

Provenance

The following attestation bundles were made for codex_agy_bridge-0.1.4.tar.gz:

Publisher: publish.yml on varadfromeast/codex-agy-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codex_agy_bridge-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for codex_agy_bridge-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 b34cb49f287892817ff8e64f6dcfb256a0aa2016376e3034e54b3c40bcfa3373
MD5 9a84bbbfed5bd7df92a99bee9946fd82
BLAKE2b-256 827aae803075954e3b307f3084cd954ac631a5cb167e7a3117b34cfe66767d74

See more details on using hashes here.

Provenance

The following attestation bundles were made for codex_agy_bridge-0.1.4-py3-none-any.whl:

Publisher: publish.yml on varadfromeast/codex-agy-bridge

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page