A2A (Agent-to-Agent) lets agents collaborate across network boundaries when they cannot share a codebase. A remote agent might belong to another team, run on a separate server for security, or use a different language or framework. Instead of importing its agent object, a client discovers it and sends requests over HTTP. A2A defines the shared communication format; it does not require both sides to use the same agent implementation. section 9.6
An A2A exchange has two central parts:
- An agent card is a JSON document served at `/.well-known/agent.json`. Its name and description identify the agent and help a client choose it; its URL identifies where to send requests, and its capabilities describe features such as streaming. section 9.6.1
- A task request goes to the URL in the card. The server executes its agent and returns a standardized response. The server provides the card and handles tasks; the client retrieves the card and sends tasks. section 9.6.1
Figure 9.12 A2A client-server model: client queries agent card and sends task requests, server provides agent information and executes tasks.
The client-server diagram separates discovery of an agent card from submission and execution of a task. section 9.6.1
To expose an existing agent, provide its card and an `AgentExecutor`. The executor adapts an A2A request to the agent’s interface: extract user input from `RequestContext`, call `agent.run()`, and place the result on the `EventQueue` as an A2A message. A request handler and `A2AStarletteApplication` connect that executor to the HTTP server; the library handles endpoint configuration and routing. section 9.6.2
from a2a.server.agent_execution import AgentExecutor, RequestContext
from a2a.server.events import EventQueue
from a2a.utils import new_agent_text_message
class MathAgentExecutor(AgentExecutor):
"""Adapter connecting A2A requests to our Agent."""
def __init__(self, agent: Agent):
self.agent = agent
async def execute(
self,
context: RequestContext, # A2A-formatted input
event_queue: EventQueue,
) -> None:
# 1. Extract user input from A2A format
user_input = context.get_user_input()
# 2. Run our Agent
result = await self.agent.run(user_input)
# 3. Convert result to A2A format and respond
await event_queue.enqueue_event(
new_agent_text_message(result.output)
)
The executor listing shows the translation boundary between an A2A request and an existing agent’s `run()` method. section 9.6.2
Use a remote specialist in existing orchestration
A `RemoteAgent` wrapper fetches the agent card during initialization and copies its name and description. Because it inherits from `Agent`, it can be registered in `sub_agents` for a transfer or wrapped in `AgentTool` for a specialist call. The caller can then compose local and remote agents through the same interface, while A2A handles the network boundary. The examples illustrate the integration rather than a complete, executable A2A implementation. section 9.6.3 section 9.6
Treat a deployed A2A endpoint like a public API. Consider authentication between agents, HTTPS/TLS for traffic, and access control over requested operations. Streaming and asynchronous task processing are available concerns, but their detailed implementation is deferred to the A2A documentation. section 9.6.3

