# The A2A Agent Card

An Agent Card is the JSON document an A2A agent publishes at `/.well-known/agent-card.json` so other agents can find out what it does before speaking to it. It names the agent, its protocol version, the endpoint URL, its declared capabilities and its skills. Connect's is generated from the same registry as the documentation.

- **Status:** Reference
- **Audience:** developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/protocols/agent-card/

## The fields, and which ones a caller acts on

**`protocolVersion`** — The A2A version the agent speaks. Connect's says `1.0.0`. A caller uses it to decide whether it can talk at all.
**`name` and `description`** — Human-readable identity. Read by a person choosing an agent and by a model deciding whether this agent is relevant.
**`url`** — Where to send messages. Not necessarily the same host the card was fetched from, which is why a caller must read it rather than assume.
**`version`** — The agent's own version, distinct from the protocol's.
**`capabilities`** — Declared behaviour: `streaming`, `pushNotifications`, and whether an authenticated extended card exists. Connect declares all three false.
**`defaultInputModes` / `defaultOutputModes`** — The media types accepted and produced. Connect's are plain text.
**`skills`** — The named things this agent can do, each with an id, a description and examples. This is the list a caller matches a question against.

The two fields that change a caller's behaviour most are `url` and `skills`. Everything else is context; those two are instructions.

## What must never be in a public card

A card is fetched by anyone, cached by intermediaries, and served with permissive cross-origin headers so that browser-based agents can read it. Treat it as a billboard.

- **No credential of any kind** — not a key, not a token, not a signed URL. A card that carries one has published it.
- **No internal hostname or private endpoint.** The `url` should be the public address. An internal one leaks topology and does not work anyway.
- **No skill that writes without authentication.** If a skill can change something, the card is advertising an unauthenticated write to every agent on the internet.
- **No personal contact details.** A support address belongs on a documentation page a person reads, not in a machine-readable file crawlers harvest.
- **No capability the agent does not have.** A card is a promise. Declaring `streaming: true` on an agent that cannot stream produces callers that hang.

> **Careful** The most common overclaim is declaring an authenticated extended card that was planned and never built. A caller then asks for it, gets an error, and has to decide whether the agent is broken or lying. Declaring `false` is the honest and cheaper answer.

## Does Connect use an Agent Card?

Yes. It is served at `/.well-known/agent-card.json`, generated from the same registry the rest of the corpus comes from so that it cannot drift from what the documentation says. The file on disk is authoritative; the route serves it with the correct content type, a five-minute cache and `Access-Control-Allow-Origin: *`, because a well-known document another agent fetches cross-origin is useless if the browser refuses it, and nothing in the card is private.

If the file is missing — a checkout that has not run the machine-artefact generator — the route builds a minimal card in process rather than returning `404` on a well-known URI that other agents probe. That fallback says plainly that it is a fallback, and its skill list is empty, so nobody is told about skills that are not being served.

An earlier A2A draft used a different well-known path, so `/.well-known/agent.json` also answers, with a `Link` header naming `agent-card.json` as canonical. A redirect costs nothing and means an agent built against that draft finds the card instead of concluding Connect does not speak A2A.

Connect's card declares five skills, `streaming: false`, `pushNotifications: false` and `supportsAuthenticatedExtendedCard: false`. Every one of those declarations matches what [the endpoint](/docs/protocols/a2a/) actually does.

## Checking a card before you trust it

1. Fetch the card and check `protocolVersion` against what your client speaks.
   - Result: You know whether a conversation is possible before you attempt one.
2. Compare `url` against the host you fetched the card from.
   - Result: A card that points somewhere else is not automatically wrong, but it is a fact worth logging — the trust you place in the card came from the domain that served it.
3. Read the skill descriptions the way you would read an unfamiliar tool list.
   - Result: Skill text lands in your model's context. It is written by somebody else and should be reviewed, not absorbed.
4. Send one small message to the cheapest skill.
   - Result: A working reply confirms the card describes something real. Cards are static files and can outlive the service they describe.

## Questions

### Where exactly does the card live?

At `/.well-known/agent-card.json` on the agent's domain — for Connect, `https://connectbyjbrh.com/.well-known/agent-card.json`. The older draft path `/.well-known/agent.json` also answers here and points at the canonical one.

### Does Connect publish a private card for authenticated callers?

No. `supportsAuthenticatedExtendedCard` is false and the request for one is refused with an explanation. The public card is the whole advertised surface, which is a deliberate choice rather than an omission.

### How often should I re-fetch a card?

Connect's is served with a five-minute cache directive, which is a reasonable floor. Re-read it when a call starts failing in a way that suggests the skill list moved, rather than on every message.

## Related

- [A2A — the Agent2Agent protocol](https://connectbyjbrh.com/docs/protocols/a2a/)
- [A2A agent discovery](https://connectbyjbrh.com/docs/protocols/a2a-discovery/)
- [Well-known URIs](https://connectbyjbrh.com/docs/protocols/well-known-uris/)
- [The Connect Agent Card](https://connectbyjbrh.com/developers/agent-card/)
- [Interoperating over A2A](https://connectbyjbrh.com/developers/a2a-integration/)

## What this page is based on

- https://a2a-protocol.org/latest/specification/
- `backend/app/a2a_server.py` — _card(), the well-known routes and headers
- `docs-source/facts.py` — PROTOCOLS['a2a'].well_known
