skip to content

Antigravity

Antigravity (agy) interactive sessions run an internal language server bound to a loopback port authenticated with an ephemeral per-session CSRF token (ANTIGRAVITY_LS_ADDRESS and ANTIGRAVITY_CSRF_TOKEN). Because Antigravity exposes those variables only inside the interactive harness and the run_command subshells it spawns (not to MCP server children or external hooks), xmsg uses a two-stage registration lifecycle.

  1. Stage 1 — Identity at MCP start: When xmsg mcp starts as an agy child, xmsg serve walks its ancestor process chain to verify a trusted --agy-exe binary holding an open file descriptor to ~/.gemini/antigravity-cli/presence/<conversation_id>.lock (matched by canonical (dev, ino), plus /proc/locks exclusive FLOCK ownership on Linux). The session immediately becomes addressable under its conversation UUID (registered: false), and messages sent to it queue in agy_pending_messages (outcome: "queued").
  2. Stage 2 — Credential capture & FIFO flush: Once ANTIGRAVITY_LS_ADDRESS and ANTIGRAVITY_CSRF_TOKEN are registered (either automatically via the Linux in-process command watcher or via the model running xmsg register agy), xmsg stores the credentials in memory only, admits any subagents from transcript.jsonl, and flushes all queued messages in FIFO order (outcome: "delivered").

Linux command watcher (Arm A) vs. Hook prompt (Arm B′)

Section titled “Linux command watcher (Arm A) vs. Hook prompt (Arm B′)”
  • Linux In-Process Command Watcher (Arm A): While an attested agy conversation holds its presence lock without registered push credentials, xmsg serve scans the attested agy process’s descendant tree (/proc/<pid>/task/<tid>/children) every 100 ms. When a descendant tool command runs, xmsg verifies start times before and after reading /proc/<pid>/environ and extracts only ANTIGRAVITY_LS_ADDRESS and ANTIGRAVITY_CSRF_TOKEN directly into memory. While Arm A is watching on the first turn, the PreInvocation hook stands down (printing {}).
  • Darwin & Sandbox Fallback (Arm B′): On macOS (or Linux sandboxes where /proc is unreadable, or if a turn completes without running a shell command), xmsg register agy --hook --event pre-invocation returns an ephemeralMessage asking the model to run xmsg register agy before anything else.

Hook configuration (~/.gemini/config/hooks.json)

Section titled “Hook configuration (~/.gemini/config/hooks.json)”

Configure PreInvocation, PreToolUse, and Stop in ~/.gemini/config/hooks.json:

{
"xmsg-register": {
"PreInvocation": [
{
"type": "command",
"command": "xmsg register agy --hook --event pre-invocation"
}
],
"PreToolUse": [
{
"matcher": "call_mcp_tool|mcp_xmsg_.*",
"hooks": [
{
"type": "command",
"command": "xmsg register agy --hook --event pre-tool-use",
"timeout": 5
}
]
}
],
"Stop": [
{
"type": "command",
"command": "xmsg register agy --hook --event stop",
"timeout": 5
}
]
}
}

When a registered parent session P spawns a subagent via invoke_subagent:

  • PreInvocation: Admits the child from P’s brain/<P>/.system_generated/logs/transcript.jsonl, binds <P>/<child_uuid>@<node>, marks the child’s turn active, and prints {} so the child never receives a registration prompt.
  • PreToolUse: Stamps as_agent: <conversationId> into call_mcp_tool / mcp_xmsg_* calls so send, reply, and inbox act as <P>/<child_uuid>@<node> (or as P when called by the parent).
  • Stop: Clears the subagent’s active turn and sweeps any remaining messages in its turn mailbox to parent P with a to=<P>/<child_uuid> agent_id=<child_uuid> header.

If xmsg serve restarts while an agy session is open, the running xmsg mcp child reconnects to agent.sock with backoff, restoring stage-1 registration so inbound messages queue safely until the next turn re-registers push credentials.

Set programs.xmsg.harnesses.agy.enable = true (requires programs.antigravity-cli.enable = true) to configure the MCP server, skill, --agy-exe, and ~/.gemini/config/hooks.json automatically. See NixOS & Home Manager.

palette
dark
light
↑↓ select↵ apply esc close

Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).