a2a-protocol

v2026.09.24

Agent-to-Agent horizontal messaging — Linux Foundation AAIF 2026 standard. Use when multiple agents across systems/vendors need to exchange tasks, results, or capabilities without sharing a runtime.

GitHub
Install command
npx skhub add akillness/a2a-protocol
Markdown
SKILL.md

A2A Protocol

Overview

MCP exposes tools to an agent. A2A connects agents to agents. The 2026 Linux Foundation AAIF specification standardizes capability cards, task envelopes, and the negotiation handshake — so a Claude agent can hand work to a Codex agent (or a third-party vendor agent) without bespoke glue.

When to use

  • Two agents need to collaborate across runtime/vendor boundaries
  • You're tired of writing custom HTTP wrappers between agent systems
  • Cross-org agent collaboration (your billing agent ↔ vendor support agent)
  • Mesh / federated agent systems

Don't use when

  • Both agents share a runtime (just call a function or use orchestrator)
  • One-direction tool call → use MCP (mcp-builder)

Core concepts

ConceptWhat
Agent CardPublic manifest — capabilities, endpoint, auth, SLAs
Task EnvelopeJob description + inputs + budget + deadline
ArtifactTyped output a task produces
StreamLong-running task progress channel (SSE)
NegotiationOptional capability/SLA agreement before send

Agent Card example

{
  "name": "acme-research-agent",
  "version": "0.4.1",
  "endpoint": "https://agents.acme.com/research/a2a",
  "auth": {"type": "oauth2", "scopes": ["a2a:invoke"]},
  "skills": [
    {
      "name": "summarize_url",
      "input_schema": {"type": "object", "properties": {"url": {"type": "string"}}},
      "output_schema": {"type": "object", "properties": {"summary": {"type": "string"}}},
      "max_cost_usd": 0.5,
      "max_latency_s": 30
    }
  ],
  "transports": ["streamable-http", "websocket"]
}

Sending a task

from a2a.client import A2AClient
client = A2AClient(card_url="https://agents.acme.com/research/.well-known/agent-card.json")

task = await client.send_task(
    skill="summarize_url",
    inputs={"url": "https://example.com/paper"},
    budget={"max_cost_usd": 0.3, "deadline_s": 20},
)
async for event in task.stream():
    if event.type == "artifact":
        print(event.artifact.summary)
    elif event.type == "status":
        print(event.status)

Server side

from a2a.server import A2AServer, skill

class ResearchAgent(A2AServer):
    @skill(name="summarize_url", max_cost_usd=0.5, max_latency_s=30)
    async def summarize(self, url: str) -> dict:
        page = await fetch(url)
        return {"summary": await llm.summarize(page)}

ResearchAgent().serve(port=8080)

Negotiation handshake

Before sending heavy tasks, negotiate:

Client → Server: capability inquiry + budget
Server → Client: accept | counter | reject (with reason)
Client → Server: send task (if accepted)

Use when SLAs matter or pricing varies.

Discovery

  • Well-known path: /.well-known/agent-card.json
  • Federated registry (2026 spec): registry.a2aproject.io
  • Local mesh: mDNS service _a2a._tcp

Security

  • All transport over TLS, mutual auth recommended
  • Per-skill scopes (don't grant blanket "invoke any skill")
  • Verify Agent Card signature against publisher key
  • Budget caps enforced server-side, not just client-claimed
  • Treat received artifacts as untrusted input → run through agent-guardrails

Common pitfalls

  • Don't tunnel arbitrary MCP through A2A — they're different layers
  • Don't share session/memory across A2A boundary; pass explicit context
  • Don't skip the deadline — long-running needs streaming, not blocking

Further reading

  • Linux Foundation AAIF 2026 spec
  • Google A2A Project reference implementation
  • A2A vs MCP — a2a connects agents, mcp exposes tools
Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

Not specified

Source path

.agent-skills/a2a-protocol

Default branch

main

Latest commit

f579bfe

Tree SHA

34a09b3