> ## Documentation Index
> Fetch the complete documentation index at: https://agno-v2-codex-docs-audit-20260719-0149.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# A2A

> Expose Agno agents via the A2A protocol

<Badge icon="code-branch" color="orange">
  <Tooltip tip="Introduced in v2.1.2" cta="View release notes" href="https://github.com/agno-agi/agno/releases/tag/v2.1.2">v2.1.2</Tooltip>
</Badge>

The [Agent-to-Agent Protocol (A2A)](https://a2a-protocol.org/latest/topics/what-is-a2a/) is an open standard for agents to communicate with each other.

Agno integrates with A2A, enabling Agno agents and teams to be exposed in an A2A-compatible format.

The `A2A` interface works with the [AgentOS](/agent-os/introduction) runtime to provide this functionality.

## Setup

Set `a2a_interface=True` when creating an `AgentOS` instance:

```python a2a_agentos.py theme={null}
from agno.agent import Agent
from agno.os import AgentOS

agent = Agent(name="My Agno Agent", id="my_agent")

agent_os = AgentOS(
    agents=[agent],
    a2a_interface=True,
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="a2a_agentos:app", reload=True)
```

By default, all local agents, teams, and workflows in the AgentOS are exposed via A2A. Remote instances (`RemoteAgent`, `RemoteTeam`, `RemoteWorkflow`) are excluded from this default.

Specific agents, teams, and workflows can be exposed by initializing the interface explicitly:

```python a2a_interface_initialization.py theme={null}
from agno.agent import Agent
from agno.os import AgentOS
from agno.os.interfaces.a2a import A2A

agent = Agent(name="My Agno Agent", id="my_agent")

# Initialize the A2A interface specifying the agents to expose
a2a = A2A(agents=[agent])

agent_os = AgentOS(
    agents=[agent],
    interfaces=[a2a], # Pass the A2A interface to the AgentOS using the `interfaces` parameter
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="a2a_interface_initialization:app", reload=True)
```

## A2A Endpoints

For each available agent, team and workflow, the following A2A-compatible endpoints will be available:

### Agents

* `/a2a/agents/{id}/.well-known/agent-card.json`:
  Returns the [Agent Card](https://a2a-protocol.org/v0.3.0/topics/agent-discovery/#1-well-known-uri) describing the agent in A2A format.
  See [API reference](/reference-api/schema/a2a/get-agent-card).

* `/a2a/agents/{id}/v1/message:stream`:
  Runs the agent, streaming the responses as events in A2A format.
  See [API reference](/reference-api/schema/a2a/stream-message-agent) and [A2A protocol docs](https://a2a-protocol.org/v0.3.0/specification/#356-method-mapping-reference-table).

* `/a2a/agents/{id}/v1/message:send`:
  Runs the agent, returning the response in A2A format (non-streaming).
  See [A2A protocol docs](https://a2a-protocol.org/v0.3.0/specification/#356-method-mapping-reference-table).

### Teams

* `/a2a/teams/{id}/.well-known/agent-card.json`:
  Returns the Team Card describing the Team in A2A format. See [API reference](/reference-api/schema/a2a/get-team-card).

* `/a2a/teams/{id}/v1/message:stream`:
  Runs the team, streaming the responses as events in A2A format. See [API reference](/reference-api/schema/a2a/stream-message-team) and [A2A protocol docs](https://a2a-protocol.org/v0.3.0/specification/#356-method-mapping-reference-table).

* `/a2a/teams/{id}/v1/message:send`:
  Runs the team, returning the response in A2A format (non-streaming). See [API reference](/reference-api/schema/a2a/run-message-team).

### Workflows

* `/a2a/workflows/{id}/.well-known/agent-card.json`:
  Returns the Workflow Card describing the Workflow in A2A format. See [API reference](/reference-api/schema/a2a/get-workflow-card).

* `/a2a/workflows/{id}/v1/message:stream`:
  Runs the workflow, streaming the responses as events in A2A format. See [API reference](/reference-api/schema/a2a/stream-message-workflow) and [A2A protocol docs](https://a2a-protocol.org/v0.3.0/specification/#356-method-mapping-reference-table).

* `/a2a/workflows/{id}/v1/message:send`:
  Runs the workflow, returning the response in A2A format (non-streaming). See [API reference](/reference-api/schema/a2a/run-message-workflow).

<Note>
  A2A clients expect a server to expose only a single agent.
  To use your Agno A2A interface with those clients, use `/a2a/agents/{id}/` (or `/a2a/teams/{id}/`, `/a2a/workflows/{id}/`) as the base URL.
</Note>

## Authorization

With [authorization](/agent-os/security/authorization/overview) enabled, A2A routes sit behind the same JWT verification and scope checks as the REST API. Send the token as `Authorization: Bearer <token>`.

| A2A method                        | Agents        | Teams        | Workflows        |
| --------------------------------- | ------------- | ------------ | ---------------- |
| `.well-known/agent-card.json`     | `agents:read` | `teams:read` | `workflows:read` |
| `message:send` / `message:stream` | `agents:run`  | `teams:run`  | `workflows:run`  |
| `tasks:get`                       | `agents:read` | `teams:read` | Not exposed      |
| `tasks:cancel`                    | `agents:run`  | `teams:run`  | Not exposed      |

Per-resource scopes apply through the A2A prefix: a token with `agents:my-agent:run` can call `POST /a2a/agents/my-agent/v1/message:send`. The deprecated `/a2a/message/send` and `/a2a/message/stream` dispatch routes require `agents:run` at the route, then re-check the run scope for the resolved target's type (`agents:run`, `teams:run`, or `workflows:run`) before running it. See [Scopes](/agent-os/security/authorization/scopes) for the full route-to-scope mapping.

### Run identity

For anonymous callers, the `X-User-ID` header and the `userId` field in `params.message.metadata` attribute the run to a user. Authenticated callers are pinned to their token's principal, and any client-supplied identity is ignored. Anonymous callers cannot claim reserved principals (`sa:*`, `__scheduler__`).

### Task ownership

`tasks:get` requires `contextId` (the session the run belongs to) and returns `400` without it. For callers scoped to a user (a service account, or a JWT user under [user isolation](/agent-os/security/authorization/user-isolation)), `tasks:get` and `tasks:cancel` verify that the task belongs to that user in that session. `tasks:cancel` also requires `contextId` for these callers.

<Warning>
  Before v2.7, A2A routes were mounted outside the AgentOS auth middleware and accepted unauthenticated requests even with `authorization=True`. v2.7 moves A2A behind the unified auth layer. If your deployment relied on open A2A endpoints, mint credentials with the scopes above for those callers before upgrading.
</Warning>

## Connecting to A2A Servers

Agno provides two ways to connect to A2A-compatible servers:

### Using A2AClient

For direct A2A protocol access:

```python theme={null}
from agno.client.a2a import A2AClient

client = A2AClient("http://localhost:7003/a2a/agents/my-agent")
result = await client.send_message(
    message="Hello!",
    headers={"Authorization": f"Bearer {token}"},  # Required when the server enforces authorization
)
```

See [A2A Client](/agent-os/client/a2a-client) for full documentation.

### Using RemoteAgent

For a higher-level agent interface:

```python theme={null}
from agno.agent import RemoteAgent

agent = RemoteAgent(
    base_url="http://localhost:7003",
    agent_id="my-agent",
    protocol="a2a",
)
response = await agent.arun("Hello!", auth_token=token)  # auth_token required when the server enforces authorization
```

See [RemoteAgent Reference](/reference/agents/remote-agent) for full documentation.

## Developer Resources

* [AgentOS Reference](/reference/agent-os/agent-os)
* [A2A Client Documentation](/agent-os/client/a2a-client)
* [A2A Protocol Documentation](https://a2a-protocol.org/latest/)
* [Examples](/agent-os/usage/interfaces/a2a/basic)
