agy-headless-bridge MCP server

agy-headless-bridge MCP server

Enables calling Google's Antigravity CLI (agy) headlessly through MCP, providing tools like agy_ask and agy_research for agents like Claude Code.

Category
访问服务器

README

<!-- mcp-name: io.github.rhishi99/agy-headless-bridge -->

<div align="center">

agy-headless-bridge

Call the Google Antigravity CLI (agy) headlessly — and actually get output back.

Codename PtyGravity · pty + antiGravity

PyPI PyPI downloads MCP Registry tests License: MIT Python Platform

📖 Architecture & docs → rhishi99.github.io/agy-headless-bridge

</div>


TL;DR — the problem, before & after

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, Codex, …) returns an empty string and exit 0 — silently. This package gives agy a fresh pseudo-terminal so it emits normally, then cleans the output.

flowchart TB
    subgraph B["❌ BEFORE — agy -p from any non-TTY caller"]
        direction TB
        a1["subprocess · MCP · CI · agent"] --> a2["agy -p &quot;prompt&quot;"]
        a2 --> a3["stdout gated by isatty()"]
        a3 --> a4["(empty string)<br/>exit 0 · no error · no output"]
    end
    subgraph A["✅ AFTER — through agy-headless-bridge"]
        direction TB
        b1["subprocess · MCP · CI · agent"] --> b2["run(prompt)"]
        b2 --> b3["allocate fresh pseudo-terminal"]
        b3 --> b4["agy -p &quot;prompt&quot;<br/>isatty() == True"]
        b4 --> b5["clean() strips ANSI/TUI"]
        b5 --> b6["clean text ✓"]
    end

    classDef bad fill:#2a1313,stroke:#f87171,color:#ffd9d9;
    classDef good fill:#0f2a1e,stroke:#34d399,color:#d7ffe9;
    class a1,a2,a3,a4 bad;
    class b1,b2,b3,b4,b5,b6 good;
# ❌ The problem — plain subprocess
import subprocess
r = subprocess.run(["agy", "-p", "say hi"], capture_output=True, text=True)
print(r.stdout)          # '' — prints nothing, exit 0

# ✅ The fix
from agy_headless_bridge import run
print(run("say hi"))     # 'Hi! How can I help?'

Three entry points around one core:

Entry point Invoke Use for
Library from agy_headless_bridge import run embedding agy in Python
CLI agy-bridge "prompt" shell scripts, quick calls
MCP server python -m agy_headless_bridge.mcp_server letting an agent call agy as a tool

The problem in detail — 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.

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) 🧪 pty mechanics verified on Linux CI (stub-driven); real agy round-trip untested on hardware — report results here

[!TIP] POSIX (macOS & Linux) users wanted. The pty mechanics are verified on Linux CI, but the real agy round-trip on POSIX hasn't been run on hardware. If you're on macOS/Linux: pip install agy-headless-bridge, try it, and tell us how it went — pass or fail. PRs 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.


Prerequisites

Before installing this bridge you need:

  1. Python 3.9+ — python --version.
  2. The Antigravity CLI (agy), installed and authenticated:
    • Install: https://antigravity.google/cli
    • Authenticate once interactively (agy opens a browser OAuth flow), or set ANTIGRAVITY_API_KEY in your environment if you use an API key.
    • Verify it runs in a real terminal: agy -p "say hi" should print a reply. (From a pipe it won't — that's the very bug this package fixes.)
  3. Windows only: pywinpty (installed automatically as a dependency). POSIX uses the stdlib pty module — nothing extra.

This package does not install or authenticate agy, and does not bundle any credentials. It only spawns the agy already on your machine.


Install

Requires Python 3.9+.

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 .

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:
    print(run("reply with exactly: OK", timeout=60))
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 mcp add --transport stdio antigravity -- \
    python -m agy_headless_bridge.mcp_server

The server speaks JSON-RPC stdio directly (no MCP SDK dependency) and routes every call through the pty bridge.

Tool schema (what an agent — or you, integrating manually — sees):

Tool Argument Type Required Description
agy_ask prompt string ✅ one-shot prompt sent to agy
agy_research query string ✅ wrapped as a deep-research prompt for agy

Response shape — a standard MCP tools/call result; the answer is the text content:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": { "content": [ { "type": "text", "text": "<agy's cleaned answer>" } ] }
}

On failure the text is an [agy-mcp] ERROR: ... string (agy missing, timeout, etc.) rather than a JSON-RPC error, so the agent always gets a readable reply.


Use cases & wiring it into your AI coding tools

The whole point: let one AI coding tool delegate work to Gemini via Antigravity, headlessly. Common setups:

Use case How
Claude Code asks Gemini for a second opinion / diff review MCP server → agy_ask tool
A CI step runs an agy prompt and captures the answer agy-bridge "..." in the workflow
A Python pipeline fans work out to agy from agy_headless_bridge import run
Codex / any MCP-capable agent delegates to agy register the same MCP server
Cron / scheduled job summarizes logs via agy agy-bridge in the script

Wire into Claude Code

Register the MCP server, then prompt Claude to use it:

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

Prompt to Claude Code: "Use the agy_ask tool to ask Antigravity to review this function for edge cases, then summarize its findings for me."

If you also want slash-command triggering and model selection, pair this bridge with the community antigravity-cc Claude Code plugin — that handles the /agy:* commands and Gemini/Claude model swap; this handles the headless I/O.

Wire into Codex (or any MCP client)

Add the server to the client's MCP config:

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

Prompt to the agent: "Call agy_research with the query 'idiomatic error handling in Rust' and turn the result into a checklist."

Use from a shell / CI script

ANSWER="$(agy-bridge 'Summarize the key risk in this diff in one sentence.')"
echo "$ANSWER"

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 ANSI escapes (CSI/OSC — colors, cursor moves), \r repaints (a spinner overwrites one line; only the final paint is kept), and box-drawing / spinner glyphs (╭─╮ │ ⠋⠙⠹) — leaving just the model's answer.

What comes off the pty vs. what you get back:

RAW (off the pty)                          CLEANED (returned to you)
─────────────────────────────────────     ─────────────────────────
⠋ thinking…\r⠙ thinking…\r\x1b[2K          A closure is a function that
\x1b[32m╭─────────────╮\x1b[0m              captures variables from the
\x1b[32m│\x1b[0m A closure is a function     scope where it was defined.
that captures variables from the
scope where it was defined.
\x1b[32m╰─────────────╯\x1b[0m

Troubleshooting / FAQ

pip install fails on Windows building pywinpty — pywinpty is a native extension. If pip tries to build from source and errors with a compiler/cl.exe message, install the Microsoft C++ Build Tools (or use a Python where a prebuilt pywinpty wheel exists — recent CPython on Windows has them). Upgrade pip first: python -m pip install -U pip.

AgyNotFoundError — the bridge can't find agy. Set AGY_PATH to the absolute path of the binary, or make sure agy is on your PATH (agy --version should work in your shell).

Empty string returned — agy produced no output. Confirm it works in a real terminal first: agy -p "say hi". If that's also empty, the problem is agy/auth, not the bridge. Re-authenticate (agy interactively) or check ANTIGRAVITY_API_KEY.

TimeoutError — the call exceeded AGY_BRIDGE_TIMEOUT (default 180s). Raise it for long prompts: AGY_BRIDGE_TIMEOUT=600 agy-bridge "..." or run(prompt, timeout=600).

Pseudo-terminal allocation fails — rare. On Windows it means pywinpty isn't importable (reinstall it). On POSIX it means the system is out of pty slots or pty.openpty() is denied (containers with no /dev/pts); run with a real pty available.

Garbled / partial output — open an issue with the OS, Python + agy version, and the raw output; clean() may need another glyph rule.

Development & CI

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 runners (which don't have agy) stay green and never need credentials. CI runs on Windows + Linux across Python 3.9 and 3.12.


Scope, non-goals & disclaimer

  • Model selection (Gemini Pro / Flash / Claude inside agy) is not handled here — it's an agy settings.json concern, covered by the antigravity-cc plugin. Pair the two.
  • Does not install or authenticate agy, and ships no credentials.
  • Automating any vendor CLI may interact with that vendor's terms / rate limits. You are responsible for using agy within Google's terms of service. This project only changes how stdout is captured — it does not bypass auth, quotas, or any access control.
  • Not affiliated with Google. Antigravity and agy are Google products.

License

MIT.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选