Go Micro speaks the [Agent2Agent (A2A) protocol](https://a2a-protocol.org) — the open standard for agents on different frameworks to discover and call each other over HTTP. The A2A gateway is the agent-side analogue of the [MCP gateway](../mcp.html): MCP exposes your services as tools, A2A exposes your agents as agents.
There is nothing to add to an agent. An agent already registers in the registry with `type=agent` metadata; the gateway discovers it, generates an **Agent Card** from that metadata, and translates incoming A2A tasks to the agent's existing `Agent.Chat` RPC — the same call `delegate` and flows use.
A2A is JSON-RPC over HTTP — a different wire protocol from go-micro's RPC — so *something* always translates between the two. That something doesn't have to be a separate process. There are two ways to run it:
- **A gateway** (above) fronts every agent in the registry behind one endpoint. Use it for a single front door, centralized discovery, and shared policy.
- **Directly on the agent.** `AgentA2A(addr)` makes the agent serve its own A2A endpoint when it runs — no separate gateway, and the task is handled in-process (no extra RPC hop):
```go
agent := micro.NewAgent("task-mgr",
micro.AgentServices("task"),
micro.AgentProvider("anthropic"),
micro.AgentA2A(":4000"), // also reachable at http://host:4000 over A2A
)
agent.Run()
```
The agent stays a normal go-micro service; this adds a second, A2A-native HTTP endpoint. Now any A2A client can `curl` it directly. Use it when each agent should be independently addressable without a gateway.
Both reuse the same handler; the only difference is whether the agent is reached over RPC (gateway) or in-process (embedded).
Every registered agent gets an Agent Card, generated from its registry metadata (name, the services it manages). Cards are not published by the agent — they are derived, the same way MCP tools are derived from service endpoints.
| Endpoint | Returns |
|---|---|
| `GET /agents` | a directory of all Agent Cards |
| `GET /agents/{name}` | one agent's card |
| `GET /agents/{name}/.well-known/agent.json` | one agent's card (well-known path) |
| `POST /agents/{name}` | the agent's JSON-RPC endpoint |
| `GET /.well-known/agent.json` | the single agent's card, when exactly one is registered |
- **`message/stream`** streams the completed `Task` as an SSE `data:` event, giving A2A clients a streaming-compatible path while the underlying agent call remains synchronous.
- **`tasks/resubscribe`** reconnects to an existing task stream, immediately emits the current task snapshot, then streams subsequent updates until the task reaches a terminal state.
- **`input-required`** task state carries human-input handoffs (for example checkpointed approval pauses) in task status, artifacts, and history; continue the task by sending a follow-up message with the same `taskId` and `contextId`.
Both directions work: the gateway exposes your agents, and `a2a.Client` (via `flow.A2A` or `delegate` to a URL) calls external ones. The task binding is what makes a Go Micro agent both reachable from, and able to reach, the A2A ecosystem today.