Skip to main content
Glama

memoh-antigravity-cli-mcp

An MCP server that lets a chat agent drive the official Antigravity CLI (agy) headlessly: run a task in a separate agent context, resume it later, inspect what it actually did, and get through Google sign-in on a machine with no browser.

Built for Memoh workspaces, usable from any MCP client.

you ──> Memoh agent ──> [MCP stdio] ──> agy -p --output-format stream-json ──> agent works
             ▲                                                                    │
             └────────────── ok / status / response / tool_calls ◄────────────────┘

Why this exists

agy is perfectly usable from a shell. Two things bite you the moment you wrap it in an MCP server, and both are handled here:

1. Interactive login cannot be done from print mode. agy -p waits for authentication with a hard-coded 60 second limit, then exits with authentication timed out. The OAuth URL appears in that window — far too short to hand it to a human, and it dies before the authorization code comes back. The interactive sign-in runs the same OAuth flow with no such limit, so this bridge runs that one process inside a tmux session. The PKCE verifier lives in that process, which is why the login is split into agy_login_start / agy_login_submit and survives between the two calls.

2. Headless mode ignores permissions.allow, and denied runs report success. Tracked upstream as issue #548. With permissions left alone, headless agy cannot show an approval prompt, so every file read or command is auto-denied — while the run still returns SUCCESS and exit code 0. The denial is only visible in denied_hints. This bridge surfaces permission_mode, denied_hints and tool_calls on every result so "did nothing" can never be mistaken for "did the work".


Related MCP server: antigravity-mcp

Requirements

Node

18 or newer (no dependencies)

agy

official Antigravity CLI, installed and signed in

tmux

only for the sign-in flow; not needed for agy_run

Install the CLI, then check it:

curl -fsSL https://antigravity.google/cli/install.sh | sh   # see the official docs for the current one-liner
export PATH="$HOME/.local/bin:$PATH"
agy --version

Install

git clone git@github.com:LoliLin/memoh-antigravity-cli-mcp.git
cd memoh-antigravity-cli-mcp

# Optional: bundle tmux + its shared libraries into ./bin/ so the sign-in flow
# works even when the MCP host runs in a container without tmux on PATH.
sh scripts/vendor-tmux.sh

There is no build step and no npm install — the server is plain ESM on the Node standard library.

Register it

Generic MCP config:

{
  "mcpServers": {
    "antigravity-cli": {
      "command": "node",
      "args": ["/abs/path/to/memoh-antigravity-cli-mcp/server.mjs"],
      "cwd": "/abs/path/to/memoh-antigravity-cli-mcp",
      "env": { "AGY_DEFAULT_CWD": "/path/to/your/workspace" }
    }
  }
}

In Memoh: Settings → MCP → add a stdio server, with node as the command and the absolute path to server.mjs as its argument. Then probe the connection — the ten agy_* tools should appear.

Environment

Variable

Meaning

AGY_DEFAULT_CWD

working directory for runs when a call omits cwd. Defaults to the server's own working directory.

AGY_BIN

explicit path to the agy binary, if it is not on PATH.

Sign in

Ask the agent for agy_status first. If auth is not authenticated:

  1. agy_login_start → returns the Google OAuth URL.

  2. Open it in a browser, sign in with your own account, and copy the authorization code.

  3. agy_login_submit(code="…").

  4. agy_status(probe_auth=true) to confirm.

Sign in with your own account and stay inside your own quota. If agy_login_start says tmux is not usable, the path and error in its reply tell you why — running scripts/vendor-tmux.sh is usually the fix.

Tools

Tool

Purpose

agy_status

binary, version, auth state, resolved tmux, known sessions. Call this first.

agy_run

run a prompt in a new conversation.

agy_continue

follow up in an existing conversation (conversation_id, label, or continue_last).

agy_sessions

list remembered label → conversation mappings.

agy_models

models available to the signed-in account.

agy_agents

named agents exposed by the CLI.

agy_login_start

begin sign-in, return the OAuth URL, keep the session alive.

agy_login_submit

feed the authorization code back into the waiting process.

agy_login_cancel

abort a pending sign-in.

agy_auth_help

explain the sign-in paths and where config lives.

Common agy_run arguments:

  • prompt (required) — self-contained; the delegate does not see your chat history.

  • cwd — narrowest directory containing the work.

  • mode — "plan" (read-only) or "accept-edits".

  • timeout_seconds — set it explicitly; analysis often needs minutes.

  • model, label, skip_permissions, json_schema, add_dirs, sandbox, effort, agent.

Usage

"Have antigravity look at why this repo fails to build, then report back."
  → agy_run(prompt="…", cwd="/path/to/repo", mode="accept-edits", timeout_seconds=900, label="build-fix")

"Ask it to follow up on the same thing."
  → agy_continue(prompt="…", session="build-fix")

A conversation is not tied to the server process: each call is a fresh agy process that resumes the stored conversation by id (official --conversation / --continue). Restarting the MCP server, or the host, does not lose it.

Design notes

  • One process per call, resumable sessions. Conversations live in agy's own store, so a crash cannot take a session with it, and every run leaves a raw .ndjson transcript (log_path).

  • Terminal driver only where it is unavoidable. tmux is used only to hold an interactive sign-in open. Everything else is headless stream-json.

  • The result is parsed, not trusted. tool_calls is reassembled from step_update events (ACTIVE carries the arguments, DONE carries the output) so you can audit what was run rather than reading a summary that might contradict it.

The compliance boundary

This bridge deliberately stays outside the CLI, and should stay that way:

  • Every action is the official agy binary with documented flags (agy -p … --output-format stream-json, agy models, agy --version) or the normal interactive sign-in UI.

  • It never contacts Google endpoints directly and never performs its own OAuth token exchange.

  • It never reads, writes, moves or copies agy credential files. Sign-in is driven through agy's own UI, so the token stays agy's.

  • It sets no undocumented environment variables (only PATH, TERM, NO_COLOR).

  • Quotas and account limits are the signed-in user's own. Working around them is out of scope.

Permissions

skip_permissions maps to the vendor's own documented --dangerously-skip-permissions flag, and means the delegate will not stop to ask before running commands or editing files in cwd and below.

  • It is ON by default here, because headless runs are otherwise auto-denied (see issue #548). Pass skip_permissions: false for a run that must not touch anything.

  • Every result echoes skip_permissions and a permissions: line, so the grant is never silent.

  • Point cwd at the narrowest directory that contains the work, not at a home directory.

  • Prefer mode="plan" when you only want analysis.

Testing

# Protocol + status smoke test. Needs no agy and no auth.
node test/harness.mjs

# Adds a real agy_run plus an auth probe. Requires a signed-in agy.
node test/harness.mjs --run

# Two unrelated processes resuming one conversation (the persistence claim).
sh test/persist-probe.sh [DIR]

The harness speaks JSON-RPC to server.mjs over stdio exactly like an MCP client does. The login flow can be exercised too: --login-start, --login-submit <code>, --login-status.

Layout

server.mjs                     MCP tool definitions + stdio transport
lib.mjs                        agy invocation, stream-json parsing, session store
tmux.mjs                       pty driver for the interactive sign-in
scripts/vendor-tmux.sh         bundle tmux + libs into ./bin/ (gitignored)
test/harness.mjs               JSON-RPC smoke tests
test/persist-probe.sh          cross-process conversation resume check
skills/antigravity-delegation/ agent-facing skill describing when and how to delegate
runs/, bin/, state.json        runtime state; all gitignored

Known limitations

  • The sign-in TUI is interactive by nature. If the tmux session is killed mid-flow, the PKCE verifier goes with it and you start over with a new URL.

  • Resuming a long conversation replays the transcript, so input tokens (and latency) grow with conversation length. This is inherent to --conversation resume.

  • runs/ and state.json grow over time; clean them up on your own schedule.

  • Permission handling depends on upstream issue #548. Once permissions.allow is honoured in headless mode, the default here should be revisited.

License

MIT — see LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP-compatible coding agents to run the local Antigravity CLI as a coding agent, manage conversation context and common options, and inspect usage, quota, models, version, help, and read-only slash commands.
    17 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI harnesses to delegate code analysis, modification, testing, and long-running tasks to the locally installed Antigravity CLI via stdio MCP, with job status tracking and conversation continuity.
    3
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables OpenAI Codex to delegate tasks to Google Antigravity CLI, running them headlessly and polling for results.
    4
    MIT