A2A Protocol
What A2A is
Section titled “What A2A is”A2A (Agent-to-Agent) is an open protocol for agent interoperability — think of it as HTTP for AI agents. When enabled, AI Butler exposes an HTTP endpoint that other agents can call to discover its capabilities and delegate work, AND AI Butler can call external A2A peers when it decides a task is better handled by another agent.
The three things A2A enables:
- Delegation — an external agent hands a subtask to AI Butler, gets back a result. Or vice versa.
- Capability discovery — AI Butler publishes an agent card describing its tools, skills, and interfaces. Other agents query it to decide what to route.
- Distributed swarms — multiple Butler instances (or different A2A-compliant agents) collaborate on one task, bounded by shared safety controls.
How it works end-to-end
Section titled “How it works end-to-end” Your AI Butler External A2A-compliant agent ────────────── ─────────────────────────────
1. User asks for something complex │ ▼ 2. Agent decides this would be better handled by an external specialist — calls a2a.delegate │ ▼ 3. A2A client sends POST /v2/tasks with { task, capabilities_needed, caller_chain, budget, auth: Bearer <token> } ──────────► 4. Peer's A2A handler receives the request, checks the token, validates depth/loop headers, runs the task ◄────────── 5. Peer returns result + updated budget + trace 6. Your agent receives result, merges with its own context, returns to user in the original chatEvery hop updates three pieces of shared state:
- Caller chain — an append-only list of agent IDs along the delegation path. Used for loop detection.
- Budget remaining — total USD cost across all hops, decremented at each step.
- Distributed trace ID — OpenTelemetry-compatible trace context so you can correlate the whole chain.
Enabling A2A
Section titled “Enabling A2A”A2A is off by default and binds to 127.0.0.1 (localhost only) when enabled. That’s the secure default — if you want remote peers, you bind to an external interface and put a reverse proxy with TLS in front.
configurations: a2a: enabled: true port: 8081 # default bind_address: 127.0.0.1 # default; use 0.0.0.0 for remote peers token_hashes: - "a1b2c3d4e5f6..." # SHA-256 hex hashes of allowed bearer tokensRequests must include an Authorization: Bearer <token> header. The handler SHA-256s the token on every request and compares it (constant-time) against the configured hash list. Tokens themselves are never stored — only their hashes, in your config file. If an attacker reads your config.yaml, they can’t forge a valid token from the hash.
Generating a token pair
Section titled “Generating a token pair”# Generate a 32-byte random token, compute its SHA-256, keep the hash in configTOKEN=$(openssl rand -hex 32)HASH=$(echo -n "$TOKEN" | shasum -a 256 | awk '{print $1}')
echo "Give this to your peer: $TOKEN"echo "Paste this into config: $HASH"Restart AI Butler — the new hash takes effect. You can rotate tokens by replacing the hash list and restarting.
Agent card — what A2A peers see when they look at you
Section titled “Agent card — what A2A peers see when they look at you”Every A2A agent publishes a card describing itself. AI Butler’s card is generated at runtime and reflects the actual current state of the instance:
{ "name": "Butler (Sam's desk)", "description": "Personal AI assistant — self-hosted AI Butler v0.1", "url": "https://butler.example.com/a2a/v2", "version": "0.1.0", "capabilities": [ "memory.read", "memory.write", "schedule.manage", "iot.sensor.read", "channel.send" ], "skills": [ { "name": "morning-briefing", "description": "Generate a daily briefing" }, { "name": "weekly-report", "description": "Summarize the week from memory" } ], "auth_schemes": ["bearer"], "streaming": true, "updated_at": "2026-04-11T14:00:00Z"}The card respects the MCP server exposure allow-list (configurations.mcp_server.allowed_capabilities). If you restrict MCP to memory.read and data.read, those are the only capabilities advertised on the A2A card. Peers can’t discover tools you’ve chosen not to expose.
Fetch your own card to verify:
curl http://localhost:8081/a2a/v2/card \ -H "Authorization: Bearer $TOKEN"Swarm safety controls (shared with local swarm)
Section titled “Swarm safety controls (shared with local swarm)”A2A delegation is bounded by the same safety controls as local swarm — see the Swarm page for the full list. Short version:
configurations: swarm: enabled: true max_depth: 4 # max delegation hops budget_usd: 5.0 # total cost cap across all peers workspace_ttl_hours: 24| Control | How it helps with A2A specifically |
|---|---|
| Depth limit | Prevents unbounded A→B→C→D→E chains across peers — you can’t end up in a 50-hop delegation graph with runaway cost |
| Loop detection | The caller-chain header lets the handler detect when a peer tries to delegate back to an agent already in the chain (A→B→A). The request is refused with HTTP 409. |
| Budget cap | Total USD cost across all peers, not per-peer — a single budget that spans the entire delegation chain |
| Trace propagation | Every hop carries a trace ID so you can correlate logs across peers post-hoc |
Dynamic agent registry
Section titled “Dynamic agent registry”When configurations.registry.self_register: true, AI Butler publishes itself to a central A2A registry at startup and refreshes its health status every health_ttl_minutes:
configurations: registry: self_register: true health_ttl_minutes: 5Other agents in the same registry can discover AI Butler by capability — e.g. “find me an agent that provides memory.search”. The registry itself is just an HTTP service that speaks a simple discovery protocol; you can run your own or use a community one.
The registry is beta-within-beta for v0.1 — the client code is there, the discovery API is defined, but we haven’t validated it against a running registry with multiple peers. If you operate an A2A registry, reach out.
Protocol compliance
Section titled “Protocol compliance”AI Butler’s A2A implementation is designed for compatibility with Google’s A2A v2 spec. The handler covers:
-
POST /v2/tasks— inbound task delegation -
GET /v2/card— agent card discovery -
GET /v2/tasks/{id}— task status polling -
POST /v2/tasks/{id}/cancel— task cancellation - Bearer token auth with SHA-256 hash comparison
- Caller-chain header propagation
- Loop detection on inbound requests
- Budget-aware task execution
What’s not yet validated:
- Formal conformance suite run against the Google A2A reference implementation
- Interop with at least 3 external A2A-compliant agents
- Streaming response support for long-running tasks (handler accepts streaming requests but returns non-streaming responses)
All of these are on the v0.2 milestone. If you’re building an A2A peer and want to run interop tests, open an issue — we’ll fast-track it.
Practical setup — two Butlers talking to each other
Section titled “Practical setup — two Butlers talking to each other”The easiest way to test A2A end-to-end today is two AI Butler instances on the same LAN:
Instance 1 — butler-home.local:8081
configurations: a2a: enabled: true port: 8081 bind_address: 0.0.0.0 token_hashes: - "<sha256 of butler-home's own token>" - "<sha256 of the token butler-office gave you>" registry: self_register: trueInstance 2 — butler-office.local:8081
configurations: a2a: enabled: true port: 8081 bind_address: 0.0.0.0 token_hashes: - "<sha256 of butler-office's own token>" - "<sha256 of the token butler-home gave you>" registry: self_register: trueOnce both are running, ask butler-home something that references work-context: “check with my office Butler for any pending action items”. The home Butler will call a2a.delegate to butler-office, which runs the task and returns a result. Both audit trails record the delegation for accountability.
What’s coming in v0.2 for A2A
Section titled “What’s coming in v0.2 for A2A”- Formal conformance testing against the Google A2A reference suite
- Live interop validation with published partners + screenshots on this page
- Streaming response support end-to-end
- Registry federation — multiple registries, peer gossip, trust levels
- Signed agent cards — cryptographic verification of peer identity beyond bearer tokens
Contributing to A2A
Section titled “Contributing to A2A”The single highest-impact contribution is interop validation with a non-Butler A2A peer. If you’re building an A2A-compliant agent (or know someone who is), run a bidirectional delegation test:
- Generate a token pair and exchange hashes
- Delegate a simple task from your agent to AI Butler (e.g. “save this fact to memory”)
- Delegate a simple task from AI Butler to your agent
- File an issue with what worked, what didn’t, and any spec deviations you spotted
A dozen interop reports across different implementations is the fastest path from beta to ready for v0.2.
Related
Section titled “Related”- Multi-Agent Swarm — local specialist orchestration (no external peers)
- MCP Server — expose tools over MCP (different protocol, different use case)
- Subprocess Bridges — wrap non-A2A CLI tools as local tools
internal/protocol/a2a/— handler, client, and protocol type definitions