A2A agent card at /.well-known/agent-card.json: what to publish in 2026
·8 min read

A2A agent card at /.well-known/agent-card.json: what to publish in 2026

Agent2Agent is how one agent hires another. The minimum viable agent card, skills vs capabilities, auth schemes that work, and two failure modes.

A2Aagent cardwell-knownAI agents

Agent2Agent (A2A) is the protocol that lets one agent hire another as a peer. Where llms.txt tells a crawler what to read and an MCP server tells a model what tools to call, A2A tells a foreign agent that your product is an agent it can hand a task to. The pointer to that fact is a small JSON document you publish at a fixed URL: /.well-known/agent-card.json.

This guide covers the minimum viable A2A agent card in 2026, the fields that actually get read by discovery clients, the split between skills and capabilities, and the verify loop that catches the two failures we see most often on scans.

Why the fixed URL matters

Unlike MCP, which is still settling around the /.well-known/mcp.json hint, A2A locked its discovery path early: the card lives at https://yourbrand.com/.well-known/agent-card.json, exact spelling, served with Content-Type: application/json. Clients probe that path and only that path. A card at /agent-card.json, /.well-known/agent.json, or anywhere else is invisible.

The fixed path is a feature. It means a peer agent looking to delegate a task to yours does not need a directory lookup or a marketing site read. Domain plus known path plus GET is the entire handshake. Do not fight the convention.

The minimum viable card

This is the smallest card that a compliant A2A client will accept and mount as a callable peer:

{
  "name": "yourbrand-agent",
  "description": "Ships llms.txt, JSON-LD, and MCP scaffolding for a scanned site.",
  "url": "https://api.yourbrand.com/a2a",
  "provider": {
    "organization": "YourBrand Inc",
    "url": "https://yourbrand.com"
  },
  "version": "1.0.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false
  },
  "authentication": {
    "schemes": ["bearer"]
  },
  "defaultInputModes": ["text"],
  "defaultOutputModes": ["text", "file"],
  "skills": [
    {
      "id": "generate-llms-txt",
      "name": "Generate llms.txt",
      "description": "Produce an llms.txt file for a given site URL.",
      "tags": ["llms.txt", "ai-seo"]
    }
  ]
}

Ten top-level fields, one skill entry. That is a functional card. Every extra field is discretionary and will churn as the spec matures; keep the surface small on version one.

Skills vs capabilities: do not confuse them

The two most misused fields on real A2A cards we scan.

  • capabilities — protocol features your endpoint supports. streaming means you can send incremental task updates. pushNotifications means you can call a webhook the client provides. This is a technical contract about transport, not about what your agent does.
  • skills — the actual jobs your agent will take on. Each skill needs an id (stable, machine-key), name (human label), description (one sentence, imperative), and tags (short strings a client can filter on). This is the field a peer agent reads to decide whether to hire yours.

A card with rich capabilities and a single empty skill teaches every client on the network that your agent is a hollow shell. A card with three sharp skills and no capabilities is fine — clients will use the defaults.

Authentication: pick one, stick to it

The authentication.schemes array is the whole contract about how peer agents call you.

  • [] or omitted — public agent, no auth. Fine for a demo or a read-only agent that only returns public data. Rate-limit at the edge.
  • ["bearer"] — the mainstream choice in 2026. Client sends Authorization: Bearer <token>. Simple, predictable, works with every hosted LLM stack.
  • ["oauth2"] — for agents acting on behalf of a specific user with user-scoped data. Higher friction; only pick it if the data model requires per-user consent.

Do not list all three "just in case". Peer clients pick the first scheme they recognize and hit your endpoint with those headers; if you cannot actually accept OAuth, listing it will produce silent failures at task-dispatch time.

When to publish an A2A card at all

A2A is a protocol for agents that accept task requests from other agents. If your product is a scanner, a report generator, a translator, a form-filler that runs as a service — yes, ship a card. If your product is a static content site, a blog, or a marketing page, an A2A card is not the right signal; those sites belong to the llms.txt and schema.org discovery layers instead.

Rule of thumb: if you cannot answer the question "what task can a foreign agent hand mine, and what does it get back", you do not need an A2A card yet. A missing card is neutral. A card pointing at a non-agent endpoint is a strong negative signal.

Cross-referencing A2A with your other agent files

Three signals should agree if you publish A2A:

  • /llms.txt — mention the A2A endpoint in the "Optional" section with one line. Agents that never read /.well-known/ still get the pointer.
  • Schema.org JSON-LD on the marketing page — a WebSite block with potentialAction referencing the same skills you list in the A2A card. Grounds LLM search on the same vocabulary. Templates in the JSON-LD guide.
  • /.well-known/mcp.json — if you also expose an MCP server for tool sessions, list it in the same directory. A2A and MCP are complementary: A2A is "hire this agent to do a job", MCP is "let this model call these tools inside its own session". See the /.well-known/ directory guide for how the pointers coexist.

Three files, one story. That is what an AI-agent-ready site looks like in 2026.

How to verify the card is landing

  1. curl -I https://yourbrand.com/.well-known/agent-card.json — expect 200 and Content-Type: application/json. If you get text/html, your framework is wrapping the file in an HTML shell (Next.js, Nuxt, Astro all do this by default). Move the file to public/.well-known/ or add a route rule, then re-check.
  2. curl https://yourbrand.com/.well-known/agent-card.json | jq .skills[0].id — expect a skill id back cleanly, not an HTML parse error.
  3. Point an A2A client at your domain (the reference client at a2aproject.github.io/A2A is the honest starting point in 2026). If it lists your skills and lets a test task through, the loop is closed.
  4. Run a full scan on agentfix.pro. It checks the card path, the content-type, the required fields, and the endpoint reachability alongside 30 other agent-readiness signals, and ships the missing files back filled in.

The two failure modes that catch everyone

First: HTML wrapper on the JSON. The card returns 200 but the framework injected a full HTML shell around it. Every client rejects the parse and moves on silently. Test with curl -I, not a browser tab. Fix by serving the file as a raw asset, not through the app router.

Second: card without a live endpoint. The url field points at a service that returns 502, 404, or an HTML login page. The card looks fine to a scanner; the first real task dispatch fails and the client will not retry your domain for days. If the endpoint is not ready, do not ship the card. Silence beats a broken promise.

Related: MCP server card for your site, the /.well-known/ directory for AI agents, and the 33-signal GEO checklist.

Want this shipped for you?

AgentFix scans your site for all 33 AI-readiness signals and emails you a personalised ZIP with the missing files generated from your content. WordPress, Webflow, Tilda, Shopify, cPanel install guides for each. From $1 one-time.