agy-bridge
Integrates with Google Antigravity (agy) to delegate coding tasks to specialist roles such as solution architect, web/API/mobile/desktop engineer, test engineer, code reviewer, security auditor, performance auditor, and DevOps engineer. Supports task dispatch, status tracking, cancellation, session continuation, token usage reporting, and result review.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
a2a-panel
Delegate coding work from Claude Code to a team of Google Antigravity (agy) specialists, or to teams that mix Antigravity, Claude Code and Codex accounts, and watch and control it from a web panel or from Telegram.
Claude Code stays the team leader: it plans, splits the work and reviews the result. The heavy reading, editing and test running happens in Antigravity, so it uses your Antigravity quota instead of your Claude context. Claude reads back a short result: status, token usage, a git change summary and the tail of the output.
13 specialist roles that follow the software lifecycle:
solution-architect(requirements and design),web-engineer,api-engineer,mobile-engineer,desktop-engineer,lead-software-engineer,test-engineer,bug-triager,code-reviewer,security-auditor,web-performance-auditor,devops-engineer,release-manager.Web panel: live logs, dispatch, cancel and re-run from the browser, with light and dark themes.
Token usage: real token counts from
agy, per task and per role (a2a-panel usage).Safe process control: cancel stops the whole process group; wall-clock and silence timeouts, a concurrency cap and bounded memory protect your machine.
Sessions: continue an Antigravity conversation by id instead of resending context.
Presets: your coding style, frontend and API libraries and default technology choices, kept as markdown files and sent to the specialists they apply to.
Standard interfaces: an MCP server for Claude Code, and an A2A-style HTTP / JSON-RPC server for other clients.
Settings page: time limits, how many agents run at once, log retention and update checks, changed from the panel without a restart.
Telegram remote control: check on your agents, start work, approve team plans and answer your team leader from your phone.
Requirements
Node.js 18 or newer
The Antigravity CLI (
agy), installed and signed inClaude Code (for the MCP integration)
macOS or Linux. Windows is not tested.
Related MCP server: Antigravity MCP Bridge
Install
git clone https://github.com/CHANDARA-code/a2a-panel.git a2a-panel
cd a2a-panel
npm run build:panel # builds the web panel (optional, needed for the dashboard)
node cli.js doctor # checks Node, agy, sign-in, git and Claude Code
node cli.js init # registers the MCP server with Claude Code
node cli.js autostart enable # optional: start the server and dashboard at login (see below)With npm: npm install -g a2a-panel, then a2a-panel doctor and a2a-panel init. Restart Claude Code (or run /mcp) afterwards. In the examples below a2a-panel stands for node cli.js if you installed from a clone. To remove it again, see 14. Uninstall.
Coming from agy-bridge? This project used to be called agy-bridge. Run a2a-panel init (or node cli.js init) once: it removes the old agy-bridge MCP registration from Claude Code and registers a2a-panel. An npm install keeps using an existing ~/.agy-bridge data folder, so your task history and presets stay. The short a2a command still works.
Safety
Tasks run agy with --dangerously-skip-permissions, because headless agy cannot ask for approval. A task can edit files and run commands in its workspace without a prompt. Read SECURITY.md before you point it at a workspace you care about, and use plan mode when nothing should change.
Architecture Overview
+---------------------------------------+
| USER REQUEST / GOAL |
+---------------------------------------+
|
v
+---------------------------------------+
| Claude Code (Team Leader) |
| • High-Level Architecture |
| • Requirements Decomposition |
| • Code Review & Integration |
+---------------------------------------+
|
+------------------------+------------------------+
| A2A Protocol Bridge |
| (Native MCP Stdio / HTTP / JSON-RPC 2.0) |
v v
+---------------------------+ +---------------------------+
| A2A MCP Stdio Server | | A2A HTTP/JSON-RPC Server |
| (Direct inside Claude) | | (http://127.0.0.1:5188) |
+---------------------------+ +---------------------------+
\ /
\ /
v v
+---------------------------------------------------------------+
| ANTIGRAVITY SENIOR DEVELOPER TEAM (agy) |
| |
| [web-engineer] Frontend UI, SSR/SSG, React/Next |
| [api-engineer] REST/GraphQL APIs, DB schemas, ORM |
| [mobile-engineer] Flutter, Dart, iOS, Android |
| [desktop-engineer] Electron, Tauri, native macOS |
| [test-engineer] QA test suites, unit & integration |
| [bug-triager] Root cause analysis & reproduction |
| [security-auditor] OWASP audits, auth flow hardening |
| [code-reviewer] Multi-axis code review & logic |
| [web-performance-auditor]Core Web Vitals & bundle profiling |
| [solution-architect] Requirements, SRS, HLD/LLD, task plan|
| [devops-engineer] CI/CD, deploy, rollout, monitoring |
| [release-manager] Versions, changelogs, publishing |
| [lead-software-engineer] Complex multi-file implementations |
+---------------------------------------------------------------+1. Native Claude Code Integration
Claude Code automatically connects to the a2a-panel MCP server on startup once you have run a2a-panel init.
It provides Claude Code with the following tools:
a2a_dispatch_to_antigravity(role, task_description, workspace_path, mode, effort, model, conversation_id, acceptance_criteria, verification_command, preset, is_async, account)a2a_list_expert_agents()a2a_list_accounts()a2a_list_presets()a2a_get_task_status(task_id)a2a_cancel_task(task_id)a2a_validate_delivery(task_summary, acceptance_criteria, verification_command, workspace_path, account)a2a_notify_user(text, choices)anda2a_wait_for_user(timeout_seconds): talk to you on Telegram (see 8. Telegram remote control)
In Claude Code, you can:
"Design the database schema, then delegate the API endpoints to the Antigravity api-engineer and have the test-engineer cover them."
2. Command line
The package installs the a2a-panel command (also available as a2a):
# List available Antigravity developer roles & specialties
a2a-panel list
# Check A2A server status & agent readiness
a2a-panel status
# Open the web task panel (monitor, dispatch, cancel)
a2a-panel dashboard
# Start / Stop the HTTP & JSON-RPC daemon (listening on port 5188)
a2a-panel server start
a2a-panel server stop
# Start the daemon and dashboard automatically at login (macOS and Linux)
a2a-panel autostart enable
a2a-panel autostart # status
a2a-panel autostart disable
# Manage signed-in accounts (see "6. Accounts")
a2a-panel accounts # list
a2a-panel accounts add work-claude --provider claude --label "Work Claude"
a2a-panel accounts login work-claude
a2a-panel accounts check work-claude
a2a-panel accounts logout work-claude
a2a-panel accounts delete work-claude
# Dispatch a task directly from terminal
a2a-panel run web-engineer "Create a user avatar component"
a2a-panel run test-engineer "Write unit tests for the auth service"
a2a-panel run code-reviewer "Review the latest changes in git"
a2a-panel run web-engineer "Add a settings page" --preset my-team
a2a-panel run web-engineer "Create avatar" --account work-claude
# Manage preference presets (see "5. Presets")
a2a-panel presets # list
a2a-panel presets templates
a2a-panel presets new my-team --template nestjs-react
a2a-panel presets default my-team # or: a2a-panel presets default none
a2a-panel presets show my-team3. A2A HTTP & JSON-RPC Endpoints
When running a2a-panel server start:
Agent Card:
GET http://127.0.0.1:5188/.well-known/agent.jsonHealth Check:
GET http://127.0.0.1:5188/healthList Roles:
GET http://127.0.0.1:5188/rolesDispatch Task:
POST http://127.0.0.1:5188/tasks/send. Optionalpreset(a preset id, ornull/"none"for none; omitted means the default preset) and optionalaccount(account id). JSON-RPCmessage/sendtakes the same fields.Version and update (panel API):
GET /api/version(?refresh=1asks npm again, at most once a minute) returns the running and newest versions and how this copy was installed;POST /api/update(token required) installs the newest version withnpm install -gand restarts the server.Accounts (panel API, token required for changes):
GET /api/accounts,POST /api/accounts({id, provider, label?, model?}),PUT /api/accounts/:id,DELETE /api/accounts/:id,POST /api/accounts/:id/check,GET /api/accounts/:id/models(?refresh=1lists them again),POST /api/accounts/:id/login,POST /api/accounts/:id/logout,GET /api/accounts/logins/:loginId,POST /api/accounts/logins/:loginId/code,POST /api/accounts/logins/:loginId/cancel.Presets (panel API, token required for changes):
GET /api/presets,POST /api/presets({id, template?, from?, title?}),GET|PUT|DELETE /api/presets/:id,POST|DELETE /api/presets/:id/default, andPOST /api/prompt-preview({role, workspace, prompt, preset}) to see the exact prompt.Task Status:
GET http://127.0.0.1:5188/tasks/:id. Returns status, output,usage,verification,conversationId,changes,workspace,accountandprovider. JSON-RPCtasks/getreturns the same fields.Server-Sent Events Stream:
GET http://127.0.0.1:5188/api/events(text/event-stream). Streams real-time updates to the web panel so idle clients make no repeating polling requests. Emits initial burst on connect, then pushes updates only when data changes:hello:{"uptimeSeconds": <number>, "pid": <number>}on client connect.tasks:{"tasks": [...], "removed": [], "full": true}with the whole list on connect, then{"tasks": [<changed tasks>], "removed": [<task ids>], "full": false}with only the tasks that changed. A running task whose only change is more output is sent at most every 5 seconds.settings:{}when settings are saved;telegram: the Telegram connection status whenever it changes.teams:{}on connect and whenever team definitions or team run records change.usage:{}on connect and wheneverusage.jsonlchanges.login:{"id": <loginId>, "state": <state>}whenever an account login session updates (session details are fetched separately viaGET /api/accounts/logins/:id).: ping: periodic comment sent every 25 seconds while idle to keep the connection alive.The panel opens one stream per visible tab, closes it while the tab is hidden, and reconnects on its own; at most 32 streams are served at once (
A2A_MAX_EVENT_CLIENTS).
Live task log:
GET /api/tasks/:id/log?from=<byte offset>returns{"text", "next", "reset"}with the output after that offset (reset: truemeans the text replaces what you have, starting with the newest 30 KB).GET /api/tasks/:id/log/stream?from=<offset>pushes the same chunks aslogevents while the task writes; each event'sidis the next offset, so a reconnectingEventSourcecontinues where it stopped.JSON-RPC 2.0:
POST http://127.0.0.1:5188/rpcwithmessage/send,tasks/get,tasks/listandtasks/cancel. Streaming and push notifications are not implemented; the agent card says so.
4. Web Task Panel
Open http://127.0.0.1:5188/dashboard (or run a2a-panel dashboard).
Pages: Tasks, Teams, Accounts, Usage, Presets and Settings (the gear button). Updates are pushed to the page over one event stream, so an idle panel sends no repeating requests. After the first full list, the stream sends only the tasks that changed, and an open task's log loads only the new output.
Update button: when npm has a newer version, the header shows "Update to x.y.z". For a global npm install, Update now installs it and restarts the server (refused while tasks or team runs are running), and the page reloads on the new version; for a git clone it shows the commands to run. The check asks the npm registry at most every 6 hours;
A2A_UPDATE_CHECK=0turns it off.Monitor: stat cards, status filter, search, per-task detail with live log. Works on mobile.
Control: dispatch a task (specialist, workspace, prompt, preset, plan/edit mode, effort), preview the exact prompt, cancel a running task, run a task again.
Presets: create, edit and preview your preference files (see "5. Presets").
Built with React, Vite and Ant Design in
panel/. Light and dark themes.Tasks started from Claude Code (MCP) or the CLI show up too, because the panel reads the task logs and PID files in
logs/.The live log shows each tool the agent runs, with its main argument, for example
[tool] run_command: npm testor[tool] read_file: /path/to/file.ts. A tool call that fails shows as[error] <tool>: <args> (<reason>). Ifagyreports denied actions, the task output ends with[A2A] Antigravity denied these actions: ….
Tasks page. Each task shows the account that ran it, with its picture.

Keep the panel running after a restart
By default the server runs until you stop it or restart your computer. To have the dashboard at http://127.0.0.1:5188/dashboard every time you log in, turn on start at login:
a2a-panel autostart enableThis installs a per-user service and starts the server right away. It needs no sudo.
macOS | Linux | |
Service | LaunchAgent | systemd user service |
Starts | when you log in | when you log in, or at boot after |
Logs |
|
|
If it crashes | restarted automatically (after up to 30 seconds) | restarted automatically after 30 seconds |
Check it and control it:
a2a-panel autostart # on/off, running or not, PID, service file, log file
a2a-panel status # server status, including "At login"
a2a-panel server restart # with start at login on, these control the service
a2a-panel server stop # stops it until your next login
a2a-panel autostart disable # stop it and stop starting it at loginThings to know:
Saved environment. A login service doesn't get your shell's
PATH.enablesaves your currentPATH, plus anyA2A_*andAGY_BINvariables, so the server can findagyand the tools a task runs (Node.js, git, npm). Runa2a-panel autostart enableagain after you change any of these, switch Node.js versions (for example with nvm), or move the project folder. To see the file it would write without installing anything, runa2a-panel autostart enable --dry-run.macOS "Background Items Added". macOS shows this notification the first time, listed under "node". If the server doesn't start, open System Settings → General → Login Items & Extensions and make sure node is allowed under Allow in the Background. Then run
a2a-panel server restart.One server at a time.
enablestops a server you started earlier witha2a-panel server start, so the two don't compete for port 5188.Claude Code doesn't need it. The MCP integration runs tasks over stdio. Start at login is only for the web panel and the HTTP / JSON-RPC API.
Rebuild after changing the UI:
cd panel
npm ci # first time only (installs exactly what package-lock.json lists)
npm run build # type-checks, then writes panel/distnpm run dev serves the UI on port 5173 with /api proxied to the server. Set VITE_A2A_TOKEN to the contents of token for write calls in dev.
Example: building an eMenu with the team
This walkthrough built an eMenu app (NestJS API + React web) in an empty git repository at ~/Downloads/emenu. All the coding and testing was done by Antigravity agents.
Two tasks were sent in parallel with
POST /tasks/sendand"async": true. Theapi-engineerbuilt the NestJS backend inapi/, and theweb-engineerbuilt the React + Vite frontend inweb/. Each task had averification_command(cd api && npm run build && npm test,cd web && npm run build && npm test -- --run).Both agents finished in about 10–12 minutes. The bridge then ran each verification command itself, and both passed: 32 API tests and 24 web tests.
A
code-reviewertask inplanmode then reviewed both halves without editing files, and reported 13 findings ranked by severity.
Overview while a task runs. Stat cards, status filter, search and the task table. Running tasks have a Cancel button.

Status filter. The "Running" filter while the api-engineer and web-engineer worked in parallel.

Task detail with live log. Click a task to open its details, prompt and live log. Each tool call appears as it happens.

New task. Pick a specialist, workspace, prompt, mode (plan only or edit files) and effort.

All tasks completed.

Completed task. Finish time, exit code and the full result. The code review's findings are at the end of the log.

Dark theme.

Mobile layout.
The result. The customer menu and the kitchen order board the agents built:


5. Presets
A preset holds your preferences as a folder of markdown files, one topic per file: coding style, frontend stack, API stack, testing, default technology choices, and anything else you add. When a task starts, the bridge adds the files that apply to that specialist to its prompt, under ### USER PREFERENCES, before the task itself.
Presets start empty. Nothing is added to a prompt until you create a preset and either make it the default or pick it for a task.
Files and roles
Each file can say which specialists it is for with a roles list in its frontmatter. A file without roles goes to every specialist. The web-engineer gets your frontend rules and not your ORM rules, so prompts stay short.
---
title: Frontend stack
roles: [web-engineer, web-performance-auditor, code-reviewer, test-engineer]
---
- React 19 + TypeScript, built with Vite.
- UI library: Ant Design 5. Do not add Tailwind or MUI.
- Server state: TanStack Query.In the panel you edit roles with a specialist picker; you don't need to write the frontmatter by hand.
Where presets live
Location | What it is |
| Your named presets: |
| Optional, per repository, can be committed so the team shares it. A file here replaces the preset file with the same name, and it applies even when no preset is chosen. |
| Starter templates shipped with the bridge: |
Role instructions and the engineering-practices template
Every task starts with its role's instructions (### YOUR ROLE). They come from an Antigravity plugin when one provides agents/<role>.md under ~/.gemini/config/plugins/ (or A2A_PLUGINS_DIR); otherwise from the bridge's own personas/<role>.md. A plugin agent replaces the bridge's persona for that role, and when several plugins provide the same role, the first plugin folder in alphabetical order wins.
The engineering-practices template adds working discipline to the prompt: core.md (verify before claiming, never fabricate, read before editing, match the codebase, stop before irreversible steps) goes to every specialist, and one guide per area goes only to the roles that need it: web.md, api.md, mobile.md, desktop.md, testing.md, debugging.md, security.md and git.md. Each role receives at most about 6,500 characters of it. If your Antigravity plugins already give agy these practices as skills, you don't need this template.
Which preset a task uses
Panel: the Preset field in New task, pre-filled with the default. "Preview prompt" shows exactly what the agent will receive.
Claude Code: the
presetargument ofa2a_dispatch_to_antigravity;a2a_list_presetslists them.CLI:
--preset <id>. HTTP / JSON-RPC: thepresetfield.If no preset is given, the default preset is used. Use
none(ornullin JSON) to send no preset. An unknown preset id is refused.
The preset and the files a task received appear in the task list, the task detail and the log header (Preset: and Preferences: lines). A task's MCP result ends with them too. The preference section is capped at 16,000 characters, and each file at 20,000.
Screenshots
Presets start empty.

New preset from a template. Start from a template, copy another preset, or start empty.

Editor. One tab per markdown file. Set the file name and the specialists it applies to, then edit the markdown. Set a preset as the default, delete it, or discard your changes.

Markdown preview.

Picking a preset for a task. The default preset is pre-selected.

Prompt preview. Shows exactly what the specialist receives, with the files that apply to it. For the web-engineer this preset leaves out api.md.

The task records its preset. Asked which libraries it was told to use, the agent answered Ant Design 5 and TanStack Query (from frontend.md), and Jest, supertest, Vitest and React Testing Library (from testing.md).

Mobile.
6. Accounts
Run tasks on multiple signed-in accounts across three agent CLIs: Google Antigravity (agy), Claude Code (claude), and Codex (codex).
Each account is bound to a provider and maintains its own isolated credentials, session state, and configuration directory.
Logos for Antigravity and Codex come from the official editor extension on your machine when installed (nothing is bundled); Claude's logo is the Simple Icons glyph (CC0); otherwise a neutral mark is shown.
Built-in System Accounts
Three built-in accounts represent your machine's default CLI sign-ins without environment overrides:
agy: Default Antigravity sign-inclaude: Default Claude Code sign-incodex: Default Codex sign-in
System accounts cannot be modified or deleted. When a task does not specify an account, it defaults to the built-in agy account.
Account Storage and Isolation
Account configurations and profiles are stored under accounts/ in the data directory (or A2A_ACCOUNTS_DIR), created with restricted 0700 directory permissions:
Claude Code:
accounts/<id>/claudepassed asCLAUDE_CONFIG_DIR. Tasks remove Anthropic environment tokens (ANTHROPIC_API_KEY,ANTHROPIC_AUTH_TOKEN,CLAUDE_CODE_OAUTH_TOKEN) so the profile credentials are used.Codex:
accounts/<id>/codexpassed asCODEX_HOME.Antigravity:
accounts/<id>/homepassed asHOME. The account home links to every entry of your real home except.geminiandLibrary. ItsLibraryis a real folder linking to your real~/Libraryitems exceptKeychainsandPreferences; itsPreferenceslinks to your real preferences exceptcom.apple.security.plist; and on macOS it gets its own keychain atLibrary/Keychains/login.keychain-db(empty password, unlocked before each run, inside the0700account folder)..geminiholds only a linkconfig -> ~/.gemini/config, so plugins and personas are shared while the sign-in is not.
Adding an account always adds a sign-in next to the existing ones: it never replaces your default sign-in or another account's. Your real keychain, its search list and its settings are never modified.
Limits of Antigravity isolation: verified on macOS. On Linux, check that a new account shows signed out before you sign in. Added Antigravity accounts cannot use certificates from your real login keychain (for example iOS code signing); run signed builds on your default Antigravity account.
Choosing a model
Wherever the panel asks for a model (an account's model, a team leader's model), it offers a list of the models that account can use, so you don't need to know model ids. The list comes from the account's own CLI, run with that account's sign-in, and is kept for 10 minutes (the refresh button asks again):
Antigravity:
agy models, for example "Gemini 3.8 Flash (High)" or "Claude Opus 4.6 (Thinking)".Codex:
codex debug models, without the models Codex marks as hidden.Claude Code: the aliases its
--helpnames (fable,opus,sonnet), each meaning the newest model of that family. You can also type a full model name.
Leaving the field empty uses the account's default model. A model id that is not in the list can still be typed and used.
Signing In
Use the web panel's Accounts view or the CLI to sign into accounts:
Claude Code (
claude): Browser login viaclaude auth login. In non-interactive contexts, it outputs a login URL and prompts for a verification code (a2a-panel accounts login <id>or through the panel dialog).Codex (
codex): Browser login opens the OAuth flow and listens onhttp://localhost:1455(one active browser login session allowed at a time due to the fixed port). Codex also supports device code authentication (--device-auth) where a URL (https://auth.openai.com/codex/device) and a one-time code (e.g.ABCD-EFGH2) are displayed.Antigravity (
agy): the panel shows the Google sign-in link; after you sign in, the page shows a code that you paste into the panel. agy only offers this in a terminal, so a2a-panel runs it in a pseudo-terminal (script). A Terminal-window sign-in is available as a fallback, anda2a-panel accounts login <id>signs in from your own terminal.
API key accounts
Besides signing in, an account can use an API key from a model provider. It runs Claude Code or Codex against that provider, so tasks, teams, token usage and budgets work like any other account. Add one under Accounts, Add account, Use an API key: pick the service, paste the key, and a2a-panel fills in the base URL and suggested models from the provider's own setup guide and checks the key where the provider has a free check.
Runs with | Services |
Claude Code ( | Anthropic API, DeepSeek, Kimi (Moonshot AI, international and China), Z.ai GLM, Zhipu GLM (China), MiniMax (international and China), Alibaba Cloud Model Studio (Qwen), OpenRouter, Volcengine Ark, and any other Anthropic-compatible endpoint such as a LiteLLM gateway |
Codex ( | OpenAI API, Kimi, MiniMax, OpenRouter, Groq, and any other endpoint that speaks the OpenAI Responses API |
The base URLs and suggested models come from each provider's Claude Code or Codex guide as of November 2026. Model names change often; you can edit them, and the model picker lists the provider's current models where it offers a free model list.
Codex accounts get their own
config.tomlwith amodel_providersentry; Codex only speaks the Responses API, so providers that only offer Chat Completions cannot run through Codex.The service logos come from LobeHub Icons (MIT, see
panel/src/assets/service-logos/LICENSE), and the Anthropic API uses the same Claude glyph as Claude Code (Simple Icons, CC0); they are their owners' trademarks and only identify each service.Anthropic says Claude Code is only supported on Claude models. Other providers' Claude Code endpoints are provided and supported by those providers.
From the command line:
a2a-panel accounts serviceslists the services,printf %s "$KEY" | a2a-panel accounts add deepseek-1 --service deepseekadds one (the key is read from stdin orA2A_API_KEY, never from the command line), anda2a-panel accounts key <id>replaces a key.
Choosing a service. Each service shows its logo and region, grouped by the CLI it runs with. Type a name such as "qwen" or "deepseek" to filter.

Key accounts next to sign-in accounts. A key account shows its service, the last 4 characters of the key, its model and whether the key works. Change key replaces it; there is no sign-in.

Names and Profile Pictures
Account cards show the account's real name and email where the provider makes them available:
Provider | Name | Photo | |
Antigravity | Google profile | yes | Google profile photo |
Codex | from the sign-in token | yes (and plan) | none |
Claude | display name from the account's | from | none |
For Codex the name, email and plan are read locally from the id_token in that account's auth.json. For Claude the display name is read from oauthAccount in the account's own .claude.json, only when its email matches. For Antigravity the email is read from the stored sign-in (agy's keychain entry gemini, or its older token file; the newest one wins), and the name and photo come from one request to Google's user-info endpoint with that account's own access token, made after a status check; if the token has expired, the name saved earlier is kept. Tokens are never logged, stored elsewhere or returned by the API; only name, email, plan and the photo are saved. A picture you upload always takes precedence, and removing it shows the provider photo again.
Each account can have a custom avatar picture (PNG, JPEG, WebP, max 512 KB) uploaded via the panel UI or PUT /api/accounts/:id/avatar. Uploaded images are validated against their magic byte signatures, stored in accounts/<id>/avatar.<ext> (or accounts/.avatars/<id>.<ext> for built-in accounts), and served with X-Content-Type-Options: nosniff, Content-Security-Policy: default-src 'none', and Cache-Control: no-cache headers. Deleting an account removes its picture.
Everywhere else in the panel (leader and member pickers, team cards, run details, usage cards) an account shows the same name as its card; a label you typed yourself takes precedence.
Usage & Budgets
The panel tracks token usage across tasks and monitors provider plan quotas and user-defined token budgets:
What a token total means: for every CLI it is new input plus output. New input is input not read from a prompt cache (for Claude Code it includes cache writes; for Codex it is input minus cached input). Cache reads are recorded separately as
cache_read_tokens, so totals and budgets compare fairly across Antigravity, Claude Code and Codex.Accounts added again: usage counts for an added account only from the moment it was created, so an account that reuses the id of a deleted one starts at zero.
Provider Quotas:
Claude Code: Captures rate limit events and displays unified windows (
5-hour,7-day,7-day Opus,7-day Sonnet) with utilization percentages and reset times. Status turnslimitedif rate limit status is not allowed or the task encounters a usage limit error.Codex: Reads rate limits from the task's own session rollout file under
$CODEX_HOME/sessions/YYYY/MM/DD/rollout-*-<thread_id>.jsonlwith5-hourandWeeklywindows. Status turnslimitedwhen a rate limit reached type is reported.Antigravity: Antigravity reports token usage only (no proactive quota API); tasks failing with quota exhaustion or resource capacity errors mark the account as
limited.
Token Budgets:
Configure period budgets per account (
day,week, ormonth) with a token threshold (minimum 1,000 tokens). Periods start at 00:00 local time (day: today, week: Monday, month: 1st of month).Set
stop: trueto enforce hard stops: tasks dispatched to that account are refused before spawning if the period budget is exhausted.CLI:
a2a-panel accounts budget <id> --period day|week|month --tokens N [--stop]anda2a-panel accounts budget <id> --clear.
Cost Caveat:
Reported cost values represent API list-price equivalents (e.g. from Claude's
total_cost_usdormodelUsage). Subscriptions are billed per plan, not per token.
MCP Tool
a2a_account_usage:Summarizes usage, quota windows, and budget capacity for each configured account in a single line, allowing a coordinating leader to pick an account with available room.
CLI Account Commands
a2a-panel accounts # list accounts and their status
a2a-panel accounts add my-claude --provider claude --label "Personal Claude"
a2a-panel accounts login my-claude # start sign-in flow
a2a-panel accounts check my-claude # check sign-in status against provider CLI
a2a-panel accounts budget my-claude --period day --tokens 50000 --stop
a2a-panel accounts budget my-claude --clear
a2a-panel accounts logout my-claude # sign out
a2a-panel accounts delete my-claude # sign the account out, then remove its folder
a2a-panel usage --days 30 # token usage totals, quota windows and budgetsThe built-in accounts agy, claude and codex are the sign-ins those tools use on this computer, also outside a2a-panel. Signing one of them in or out replaces that sign-in, so the CLI asks for --yes (a2a-panel accounts login claude --yes) and the panel asks for confirmation. To add another account next to it, use accounts add or Add account instead.
Screenshots
Emails are masked in these screenshots.
Accounts. Several accounts per CLI, each with its own name, photo, sign-in state and usage. Built-in accounts are your default sign-ins; added accounts sit next to them.

Add account. Pick the CLI and sign in with its own login, or use an API key from DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenRouter, Anthropic, OpenAI and others. A new account never replaces an existing sign-in.

Usage. Tokens per account (new input plus output), plan quota where the provider reports it, budgets and daily activity.

7. Teams
A Team organizes coding work by separating the planning and execution into distinct accounts:
Leader account: Read-only, turns a goal into a short task plan (and optionally reviews the final work). It runs with
persona: falseand minimal output to keep planning token-efficient.Member accounts (developers): Specialist accounts (
agy,claude,codex) that code and test specific tasks using their own quotas. Each developer only receives its own task prompt, acceptance criteria, overall goal, and outputs from tasks it explicitly depends on.
Why Teams Save Tokens
In traditional multi-agent orchestration, the orchestrator keeps all agent context, file contents, and intermediate test runs in its context window, rapidly consuming context and token quota. With Teams:
The leader only produces a structured JSON plan (and a concise final review if requested).
Each developer spends its own isolated provider quota and sees only what it needs to execute its assigned task.
Intermediate file changes, logs, and tool calls never re-enter the leader's context window.
Team templates
The quickest way to build a team: in the panel choose Teams → New team and pick a template, or run a2a-panel teams new <id> --template <template>. A template fills in the description, the leader's instructions and effort, the members' roles and notes, the parallel limit and leader review. It then picks your accounts:
The leader is an account of the suggested CLI that does not lead another team yet, so a second team gets a different leader (for example
claudeleads the iOS team andclaude-2the Android team).Each member gets a different signed-in account, preferring the CLI the template suggests. With fewer accounts than members, the remaining roles are merged into the last member.
Everything stays editable before you save.
Template | Leader (suggested) | Members (roles) |
| Claude | web-engineer, api-engineer, test-engineer |
| Claude | mobile-engineer ×2, test-engineer |
| Claude | mobile-engineer ×2, test-engineer |
| Codex | mobile-engineer ×2, test-engineer |
| Claude | api-engineer ×2, test-engineer + security-auditor |
| Claude | bug-triager, a fixer (any engineering role), test-engineer; one step at a time |
| Claude | code-reviewer, security-auditor, web-performance-auditor; read-only |
| Claude | release-manager, test-engineer, devops-engineer; nothing is published |
Templates are JSON files in team-templates/; npm run check validates their roles, CLIs and limits. API: GET /api/team-templates and GET /api/team-templates/:id/draft (a ready-to-save team with your accounts filled in).
Example: Claude Leads iOS Development with Two Antigravity Developers
Imagine an iOS app project where you want Claude Code to architect and coordinate tasks, while two Antigravity developer accounts do the actual Swift and UI implementation:
{
"id": "ios-squad",
"name": "iOS Squad",
"description": "Native iOS Swift & SwiftUI engineering squad",
"leader": {
"account": "claude",
"model": null,
"effort": "medium",
"instructions": "Decompose into standalone SwiftUI and core data tasks."
},
"members": [
{ "account": "agy-dev1", "roles": ["mobile-engineer"], "notes": "SwiftUI and view models" },
{ "account": "agy-dev2", "roles": ["test-engineer", "api-engineer"], "notes": "Networking and unit tests" }
],
"workspace": "/Users/developer/projects/MyApp",
"maxParallel": 2,
"review": true
}Plan-First vs. Plan-and-Build
Plan-first (
mode: "plan"): The leader generates the task plan and stops at statusplanned. You can inspect the task breakdown, assignees, and dependencies before executing witha2a-panel teams execute <runId>or through the web dashboard.Plan-and-build (
mode: "accept-edits"): The leader generates the plan and the scheduler immediately starts executing tasks across available members as dependencies are satisfied.
Concurrency and the Same-Folder Warning
maxParallel(1 to 4, default 1): Limits how many developer tasks run concurrently.Same-folder warning: Tasks that do not have
depends_onrelationships can run simultaneously in the same workspace directory. To prevent conflicting edits to the same files, assign developers separate files or chain dependent tasks usingdepends_on.
Leader Review
When review: true is enabled and at least one task completes, the leader runs a review step upon task completion. The leader inspects git status and git diff --stat (max 2000 characters) and returns a verdict (Verdict: ACCEPTED or Verdict: REVISION NEEDED) with up to 10 findings.
CLI Team Commands
a2a-panel teams # list configured developer teams
a2a-panel teams show ios-squad # inspect team configuration
a2a-panel teams new ios-squad --file team.json # create team from JSON file
a2a-panel teams templates # list team templates
a2a-panel teams new ios --template ios-app # create a team from a template, accounts picked for you
a2a-panel teams delete ios-squad # delete team
a2a-panel teams run ios-squad "Add dark mode" # run team (foreground progress tracking)
a2a-panel teams run ios-squad "Add dark mode" --plan # plan only
a2a-panel teams runs # list recent team runs
a2a-panel teams execute <runId> # execute a planned runMCP Tools for Claude Code
When connected via MCP, Claude Code can inspect and drive teams using:
a2a_list_teams(): List configured teams, their leaders, and member roles.a2a_run_team(team, goal, workspace_path, mode, is_async): Start a team run (returns a compact summary to save tokens).a2a_get_team_run(run_id): Check plan progress, task statuses, token counts, and review results.a2a_cancel_team_run(run_id): Cancel an active team run and its running developer tasks.
Screenshots
Teams. Each team has a leader account with its own instructions and member accounts with roles. Here Claude leads the iOS team and Codex leads the Android team.

A plan waiting for approval. In plan-first mode the Claude leader read the workspace and split the goal into three tasks for two accounts, with dependencies. Nothing is built until you press "Build this plan".

8. Telegram remote control
Use a Telegram bot of your own to follow and steer a2a-panel from your phone. a2a-panel asks Telegram for new messages itself (long polling), so no port is opened on your computer and nothing has to be reachable from the internet.
Set it up in the panel under Settings (the gear button), Telegram remote control. The page walks you through it:
In Telegram, open @BotFather, send
/newbot, pick a name and a username ending inbot, and paste the token it gives you.Open your new bot and press Start (for a group: add the bot and send a message there). Press Find my chat: the panel lists the chats that wrote to the bot, with their ids and the people in them. Pick yours.
Choose who may control it: the allowed user ids are filled in from that chat (a group chat needs them; a private chat works without). Starting work from Telegram (
/run,/team, the Build button) stays off until you turn it on, and/runneeds a workspace. Messages for your team leader are delivered either way.Turn it on, save, and press Send test message.

The bot only listens to that one chat, ignores other people and other bots, and ignores commands older than 10 minutes (sent while the server was down). If the bot already sends its updates to a webhook, a2a-panel says so and does not take it over; use a separate bot.
Commands
Command | What it does |
| Version, uptime, agents running against the limit, team runs, signed-in accounts, leader inbox |
| Latest tasks; one task with the end of its log |
| Latest team runs; your teams |
| Start one agent in the configured workspace (needs "Allow starting work") |
| Plan a team run; the plan arrives with Build and Cancel buttons |
| Stop a task or a team run |
| Tokens per account today, with budget use |
| A message for your team leader |
You also get a message when a task finishes (with a Log button), when a team plan is ready (with Build and Cancel), and when a team run ends. Tasks that belong to a team run are reported once, with the run, so six parallel agents don't send six messages.
Your team leader listens too. Claude Code (after a2a-panel init) and any other MCP client that runs a2a-panel mcp, Antigravity included, get two tools:
a2a_notify_user(text, choices)sends you a message;choicesadds up to six answer buttons.a2a_wait_for_user(timeout_seconds)waits for your next message,/dotext or button tap and returns it.
Tell your leader, for example: "When you finish a step or need a decision, message me with a2a_notify_user and wait for my answer with a2a_wait_for_user." Messages sent while no leader is waiting are kept (up to 50) until one asks. Both tools talk to the running server, so the server must be running (a2a-panel server start or start at login).
The bot token is kept in settings.json in the data folder (mode 0600) and is never sent back by the API. You can also set every option as an environment variable (A2A_TELEGRAM_ENABLED, A2A_TELEGRAM_BOT_TOKEN, A2A_TELEGRAM_CHAT_ID, A2A_TELEGRAM_ALLOWED_USER_IDS, A2A_TELEGRAM_ALLOW_RUN, A2A_TELEGRAM_WORKSPACE, A2A_TELEGRAM_NOTIFY_TASKS, A2A_TELEGRAM_NOTIFY_RUNS).
9. Security model
The server only answers requests whose
Hostheader is127.0.0.1,localhostor[::1]on the server port (blocks DNS rebinding).No CORS headers are sent.
Every non-GET request needs the token in
thetokenfile in the data folder(mode 0600, created on first start). Send it asX-A2A-Token: <token>orAuthorization: Bearer <token>. A request with anOriginheader must be same-origin.The panel receives the token inside its own HTML, which only same-origin pages can read.
The MCP server and the CLI run tasks in-process and do not use the HTTP API. Only the two Telegram tools (
a2a_notify_user,a2a_wait_for_user) call the running server, with the token from the token file.Cancel stops the whole agent process group (SIGTERM, then SIGKILL after 5 seconds). Tasks started before this version run without their own process group, so cancel stops the agent and its descendants by walking the process tree.
Panel dispatch defaults to "Plan only". "Edit files" lets the agent edit files and run commands in the chosen workspace.
10. Limits
Change these in the panel under Settings: they are saved in settings.json in the data folder and apply to the next task, without a restart, for the server, the MCP server and the CLI. An environment variable with the same name still works and wins over the saved value; the panel shows it read-only. 0 turns a limit off.
Settings page. Changed values are marked and can go back to their default; a value set by an environment variable is marked and read-only (here the update check).

Variable | Default | Effect |
|
| Stops a task that runs longer than this and marks it failed. |
|
| Stops a task that prints nothing for this long. Off by default because headless |
|
| Refuses a new task while this many agents are running, across the server, MCP server and CLI. |
|
| Output kept in memory per task. The log file under |
|
| Time between SIGTERM and SIGKILL when stopping a task. |
|
| Limit for the bridge's own run of a |
|
| Task logs older than this are deleted when a new task starts. |
| on | Set to |
|
| Registry the update check asks. |
| the | npm used to install an update. |
A stopped task shows failed with the reason (Timed out after … or No output for …).
Running many agents at once. For 40 agents and tasks that take 3 or 4 hours, set these in Settings:
Agents at the same time: 40 (up to 200). Each running agent is its own Claude Code, Codex or Antigravity process, so memory, CPU and each provider's rate limits set the real ceiling; spread the agents over several accounts.
Task time limit: longer than your longest task, for example 300 minutes, or 0 for no limit. The default of 60 minutes stops longer tasks.
Silence limit: keep it at 0, or set it well above the longest quiet stretch, because agents can think for minutes without printing.
From Claude Code, start long tasks with
is_async: trueand check them witha2a_get_task_status, so no single tool call has to wait hours.
What the server does to stay fast: it reads the process table once per second for all running tasks instead of twice per task, keeps parsed task summaries and team runs until their files change, cleans up old logs at most every 10 minutes, and pushes only changed tasks to the panel; a running task whose only change is more output is pushed at most every 5 seconds, and an open task's log streams by itself. Measured with 40 agents each printing 20 lines a second: the server used about 7% of one CPU core and 136 MB of memory, the task list answered in about 8 ms, and the panel received about 100 KB in 30 seconds. On macOS, start at login (a2a-panel autostart enable) runs the server as an interactive process; before 0.4.0 macOS gave it the light background limits on CPU and disk it uses for services that don't say what they are. a2a-panel server restart updates an existing start-at-login service.
11. Usage tracking and sessions
Tasks run with --output-format stream-json (or JSONL streaming for Claude Code and Codex). The bridge turns the event stream into readable text, and records token usage per task and per account.
a2a-panel usageshows totals, a per-role breakdown, and a per-account breakdown, read fromlogs/usage.jsonl. The same data is atGET /api/usage.Each synchronous MCP result ends with the task's token usage, its conversation id, and
git status/git diff --statof the workspace, so you can check the work without reading the agent's account.Pass
conversation_id(from an earlier result) to continue that conversation instead of resending context. Passmodelto pick a model.A run whose final status from the agent is not
SUCCESSis marked failed.
12. Verification gate
If a task has a verification_command (MCP tool, /tasks/send, or JSON-RPC message/send), the agent is told to run it, and then the bridge runs it again itself in the workspace once the agent has finished successfully.
Exit code 0: the task stays
completed.Non-zero exit or a timeout (
A2A_VERIFY_TIMEOUT_MS, default 10 minutes): the task is markedfailed, and the result includes the command's output tail.The result and the log record the outcome as "run by the bridge (not the agent)".
a2a_validate_deliveryuses the same gate.If the agent itself failed, the command is not run.
The command runs through
sh -cwith your user's permissions, like the agent does. Cancelling the task stops it; otherwise the timeout is the limit.
A passing command only proves what that command checks. If the agent also wrote the tests, a green run says little, so review the diff too.
13. Tests
npm test
# or:
node --test test/server.test.js test/accounts.test.js test/teams.test.jsThe tests start a server on a random port with fake agent binaries, a temporary accounts directory, a temporary logs directory and a temporary token, so they use no agent quota and leave no history behind.
14. Uninstall
Run the steps in this order: the first ones use the a2a-panel command, which the later ones remove.
1. Stop the server and turn off start at login.
a2a-panel autostart disable # removes the LaunchAgent / systemd user service and stops it
a2a-panel server stop # stops a server you started by hand, if one is running2. Remove it from Claude Code.
claude mcp remove a2a-panel
claude mcp remove agy-bridge # only if you used the old nameRestart Claude Code (or run /mcp) so the a2a_* tools disappear.
3. Remove the program.
npm uninstall -g a2a-panel # if you installed it from npm
npm unlink -g a2a-panel # if you ran "npm link" in a clone
rm -rf ~/path/to/a2a-panel # if you cloned it: delete the clone folder (this also deletes its data)4. Delete your data (optional). This is your task history, token usage, presets, settings (including a Telegram bot token) and the access token. Keep it if you might reinstall.
Installed from | Data folder |
npm |
|
A clone | the clone folder itself: |
| the folder it points to |
rm -rf ~/.a2a-panel ~/.agy-bridge # npm install data
rm -rf ~/Library/Logs/a2a-panel # macOS start-at-login logs5. Project files (optional). If you added .agy/preferences/ to a repository, those files belong to that repository. Delete them there if you no longer want them.
Nothing else is installed. a2a-panel doesn't change the Antigravity CLI (agy), its sign-in, or your Claude Code settings beyond the MCP registration removed in step 2.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hand tasks, bugs and finished work to AI coding agents, and get back a write-up with evidence.
Hosted coding agent: start, follow up on and stop tasks that can open GitHub pull requests.
Coordination hub for AI coding agents: message teammates, ask humans, audit every event.
Task management for teams building with AI agents. Agents claim tasks and report progress.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables Claude to delegate tasks to external coding agents (Codex or Antigravity) for independent reviews, separate quota usage, and async processing.6MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI clients to run Google Antigravity coding sub-agents as MCP tools, with synchronous and asynchronous execution, task polling, and sandboxed Docker workspace isolation.-
- AlicenseAqualityAmaintenanceEnables Claude Code and Claude Desktop to delegate token-heavy tasks to Antigravity headless subagents, offloading file edits, test runs, and exploration while preserving Claude's context window.1210 npm1MIT
- AlicenseAqualityBmaintenanceEnables Codex to delegate bounded code analysis, review, isolated edits, multimodal research, and native image generation to supervised Antigravity workers, with queued execution, retries, and inspectable patches.232MIT