Skip to main content
Glama
rhishi99

agy-headless-bridge MCP server

by rhishi99

agy-headless-bridge

Call the Google Antigravity CLI (agy) headlessly โ€” and actually get output back.

Codename PtyGravity ยท pty + antiGravity

License: MIT Python Platform Tests

๐Ÿ“– Architecture & docs โ†’ rhishi99.github.io/agy-headless-bridge


agy -p "<prompt>" prints nothing when its stdout is not a real terminal โ€” so calling it from a subprocess, an MCP server, CI, or another coding agent (Claude Code, etc.) yields an empty string and exit 0. This package fixes that. It runs agy through a fresh pseudo-terminal, so agy sees a tty and emits normally; the bridge then strips the ANSI/TUI noise and hands you clean text.

from agy_headless_bridge import run

print(run("Explain a closure in one line."))
# -> A closure is a function that remembers variables from the scope where it was defined.

It ships three entry points around one core:

Entry point

Import / command

Use it for

Library

from agy_headless_bridge import run

embedding agy in your Python

CLI

agy-bridge "prompt" / python -m agy_headless_bridge

shell scripts, quick calls

MCP server

python -m agy_headless_bridge.mcp_server

letting an agent (Claude Code) call agy as a tool


The problem โ€” upstream bug #76

agy gates its stdout on isatty(). The instant stdout isn't a terminal, it goes silent โ€” no output, no error, exit 0:

$ agy -p "say hi" | cat
$            # empty. exit 0. nothing.

The common winpty agy -p "..." workaround needs a terminal that already exists, so it still fails from any automated/non-TTY caller.

Related MCP server: agent-browser-mcp

The fix โ€” give agy a tty it didn't ask for

Allocate a brand-new pseudo-terminal (one that needs no parent tty) and attach agy to it. Same code path on every OS โ€” only the pty allocator differs.

flowchart TD
    A["Caller โ€” non-TTY<br/>Claude Code ยท MCP ยท subprocess ยท CI"] -->|"prompt"| B{{"run(prompt)"}}
    B --> C["find_agy()<br/>$AGY_PATH โ†’ PATH โ†’ OS defaults"]
    C --> D{"sys.platform?"}
    D -->|"win32"| E["pywinpty<br/>PtyProcess.spawn"]
    D -->|"posix"| F["stdlib pty<br/>os.openpty + Popen"]
    E --> G(["fresh pseudo-terminal"])
    F --> G
    G --> H["agy -p prompt<br/>isatty == True โ†’ emits"]
    H -->|"raw bytes + ANSI/TUI chrome"| I["clean()<br/>strip CSI/OSC ยท collapse \r repaints ยท drop spinner glyphs"]
    I -->|"clean text"| A

Platform

pty backend

Status

Windows

ConPTY via pywinpty (PtyProcess)

โœ… verified (agy 1.0.6)

Linux / macOS

stdlib pty (os.openpty + subprocess.Popen)

๐Ÿงช implemented, untested โ€” reports welcome

Why not just the existing agy Claude Code plugins? They wrap agy for triggering (slash commands, model selection) but still call agy -p directly โ€” so in any headless context they hit this exact empty-output bug. This package fixes the I/O layer they're missing. Use both together.


Install

pip install agy-headless-bridge          # pywinpty auto-installs on Windows only

From source:

git clone https://github.com/rhishi99/agy-headless-bridge
cd agy-headless-bridge
pip install -e .

Prerequisite: the Antigravity CLI itself, installed and authenticated (https://antigravity.google/cli). The bridge locates the binary via, in order: $AGY_PATH โ†’ agy on PATH โ†’ OS default install paths.


Usage

Library

from agy_headless_bridge import run, AgyNotFoundError

try:
    answer = run("reply with exactly: OK", timeout=60)
    print(answer)
except AgyNotFoundError:
    print("install agy first")

run(prompt, timeout=180, agy_path=None) -> str โ€” raises AgyNotFoundError if the binary is missing, TimeoutError on timeout, ValueError on empty prompt. Returns "" only if agy genuinely emitted nothing.

CLI

agy-bridge "reply with exactly: OK"
python -m agy_headless_bridge "reply with exactly: OK"   # equivalent

MCP server (Claude Code & other MCP clients)

claude mcp add --transport stdio antigravity -- \
    python -m agy_headless_bridge.mcp_server

Or add to your MCP config manually:

{
  "mcpServers": {
    "antigravity": {
      "command": "python",
      "args": ["-m", "agy_headless_bridge.mcp_server"]
    }
  }
}

Exposes two tools โ€” agy_ask(prompt) and agy_research(query) โ€” so your agent can delegate work to Antigravity / Gemini. The server speaks JSON-RPC stdio directly (no MCP SDK dependency) and routes every call through the pty bridge, so it works in the non-TTY context an MCP host runs it in.


Configuration

Env var

Default

Meaning

AGY_PATH

auto-detect

Absolute path to the agy binary

AGY_BRIDGE_TIMEOUT

180

Seconds before a call is killed


How clean() works

agy's pty output is a TUI stream, not plain text. clean() removes:

  • CSI / OSC ANSI escapes โ€” colors, cursor moves, window-title sets

  • \r repaints โ€” a spinner overwrites one line many times; only the final paint is kept

  • box-drawing & spinner glyphs โ€” โ•ญโ”€โ•ฎ โ”‚ โ ‹โ ™โ น TUI chrome

โ€ฆleaving just the model's answer.


Development

pip install -e ".[dev]"
pytest

Unit tests (cleaning, arg validation, binary discovery) always run. The live agy round-trip test auto-skips when agy isn't installed, so CI stays green without Antigravity present.


Scope & non-goals

  • Model selection (Gemini Pro / Flash / Claude inside agy) is not handled here โ€” that's an agy settings.json concern, already covered by the antigravity-cc Claude Code plugin. Pair the two.

  • Does not install or authenticate agy.

  • Not affiliated with Google. Antigravity and agy are Google products.

License

MIT.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

โ€“Maintainers
โ€“Response time
โ€“Release cycle
โ€“Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rhishi99/agy-headless-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server