> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hud.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# A2A chat

> Build a chat task on the HUD A2A orchestrator, serve it over the agent-to-agent protocol, and connect with any A2A-compatible client to test turns.

Sometimes you want to reach an environment over a standard wire protocol instead of the SDK. This example puts one in front of `Chat`: it serves a `messages`-style task as an [A2A](https://github.com/google/a2a) endpoint, so any A2A client - including another LLM using it as a tool - can hold a conversation with your environment.

A **`Chat`** is HUD's multi-turn conversation object, and it is protocol-agnostic (see [Chat](/v6/advanced/extending#chat-and-multi-turn)). The A2A layer is a reference server kept outside the SDK on purpose, so you copy and adapt it from [`cookbooks/a2a-chat`](https://github.com/hud-evals/hud-python/tree/main/cookbooks/a2a-chat).

## The pieces

| File            | What it does                                                                          |
| --------------- | ------------------------------------------------------------------------------------- |
| `server.py`     | A2A server: one `Chat` (conversation) per A2A context, agent card, citations artifact |
| `client.py`     | Minimal A2A client: send messages, print replies                                      |
| `llm_client.py` | LLM-fronted client: an OpenAI model decides when to call the A2A agent as a tool      |
| `chat_env.py`   | Sample chat environment with `messages`-style tasks to serve                          |

## The environment

A chat-style task takes the running conversation as a `messages` parameter and yields it as the prompt:

```python chat_env.py theme={"dark"}
from mcp.types import PromptMessage
from hud.environment import Environment

env = Environment(name="chat")

@env.template()
async def chat_simple(messages: list[PromptMessage]):
    yield messages   # the conversation so far is the prompt
    yield 1.0
```

## Run it

From `cookbooks/a2a-chat` (uv resolves the dependencies on first run):

```bash theme={"dark"}
# Terminal 1: serve the bundled chat task (spawns chat_env.py per turn)
uv run server.py

# Terminal 2: talk to it
uv run client.py            # plain client
uv run llm_client.py        # LLM-fronted client
```

The server publishes an agent card at `/.well-known/agent-card.json` and accepts A2A messages at the root endpoint. Each A2A context gets its own `Chat`, so concurrent conversations stay independent.

You configure the server through environment variables:

| Variable               | What it controls                                                                                                                                           |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HUD_MODEL`            | The agent's model, routed through the gateway (needs `HUD_API_KEY`).                                                                                       |
| `HUD_TASK` / `HUD_ENV` | Which task row to serve.                                                                                                                                   |
| `HUD_SOURCE`           | Spawns a different env source.                                                                                                                             |
| `HUD_ENV_URL`          | Attaches each turn to an already-served control channel instead of spawning. For example, `hud serve chat_env.py` then `HUD_ENV_URL=tcp://127.0.0.1:8765`. |

## See also

<CardGroup cols={2}>
  <Card title="Chat" icon="comments" href="/v6/advanced/extending#chat-and-multi-turn" />

  <Card title="Integrations" icon="puzzle-piece" href="/v6/advanced/extending" />
</CardGroup>
