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.
Two-stage registration lifecycle
Section titled “Two-stage registration lifecycle”- Stage 1 — Identity at MCP start:
When
xmsg mcpstarts as anagychild,xmsg servewalks its ancestor process chain to verify a trusted--agy-exebinary holding an open file descriptor to~/.gemini/antigravity-cli/presence/<conversation_id>.lock(matched by canonical(dev, ino), plus/proc/locksexclusiveFLOCKownership on Linux). The session immediately becomes addressable under its conversation UUID (registered: false), and messages sent to it queue inagy_pending_messages(outcome: "queued"). - Stage 2 — Credential capture & FIFO flush:
Once
ANTIGRAVITY_LS_ADDRESSandANTIGRAVITY_CSRF_TOKENare registered (either automatically via the Linux in-process command watcher or via the model runningxmsg register agy),xmsgstores the credentials in memory only, admits any subagents fromtranscript.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
agyconversation holds its presence lock without registered push credentials,xmsg servescans the attestedagyprocess’s descendant tree (/proc/<pid>/task/<tid>/children) every 100 ms. When a descendant tool command runs,xmsgverifies start times before and after reading/proc/<pid>/environand extracts onlyANTIGRAVITY_LS_ADDRESSandANTIGRAVITY_CSRF_TOKENdirectly into memory. While Arm A is watching on the first turn, thePreInvocationhook stands down (printing{}). - Darwin & Sandbox Fallback (Arm B′): On macOS (or Linux sandboxes where
/procis unreadable, or if a turn completes without running a shell command),xmsg register agy --hook --event pre-invocationreturns anephemeralMessageasking the model to runxmsg register agybefore 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 } ] }}Subagents (<P>/<child_uuid>@<node>)
Section titled “Subagents (<P>/<child_uuid>@<node>)”When a registered parent session P spawns a subagent via invoke_subagent:
PreInvocation: Admits the child fromP’sbrain/<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: Stampsas_agent: <conversationId>intocall_mcp_tool/mcp_xmsg_*calls sosend,reply, andinboxact as<P>/<child_uuid>@<node>(or asPwhen called by the parent).Stop: Clears the subagent’s active turn and sweeps any remaining messages in its turn mailbox to parentPwith ato=<P>/<child_uuid> agent_id=<child_uuid>header.
Server restart resilience
Section titled “Server restart resilience”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.
Home Manager switch
Section titled “Home Manager switch”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.
Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).