Skip to main content

A2A Protocol Primer

Google’s A2A protocol (now under the Linux Foundation) is the communication standard that connects all agents on CRAFT. Understanding A2A is prerequisite knowledge for every agent author, regardless of which framework you choose — it defines the contract your agent must honour at its network boundary.

What A2A Is

A2A is an open, vendor-neutral protocol for agent-to-agent communication. Key properties:
  • Transport: JSON-RPC 2.0 over HTTP, with Server-Sent Events (SSE) for streaming responses
  • Discovery: Agent Cards served at a well-known URL describe capabilities
  • Framework-agnostic: works with Google ADK, Pydantic AI, LangGraph, or any custom implementation
  • Task-centric: every interaction creates a Task with a defined lifecycle
A2A defines the protocol, not the implementation. CRAFT agents are free to use any framework internally; they must speak A2A at their boundary.
CRAFT’s reference agents currently serve protocolVersion: "0.3.0" (verified against the live text2sql agent’s /.well-known/agent-card.json). The A2A specification reached v1.0 in early 2026 — the platform’s a2a-sdk Python library (pip install a2a-sdk) will track upstream as the SDK catches up. The a2a-sdk provides the canonical types and server utilities (A2AStarletteApplication, DefaultRequestHandler, AgentCard, etc.).

Agent Cards — Identity and Discovery

An Agent Card is a JSON document that describes what an agent does, what it can accept, and how to reach it. Every CRAFT agent publishes its card at:
This endpoint is unauthenticated — any orchestrator can fetch it to understand the agent’s capabilities before invoking it.

Agent Card Structure

Capabilities

CapabilityEffect when true
streamingAgent supports message/stream (SSE); callers may use real-time streaming
pushNotificationsAgent supports webhook push for task completion
stateTransitionHistoryAgent returns full task state transition history in responses
Clients should read capabilities from the Agent Card before calling methods that depend on them. Calling message/stream against an agent with streaming: false returns UnsupportedOperationError.

Skills

Skills are discrete capability declarations within an Agent Card. They help orchestrators understand what tasks the agent can handle and inform LLM routing decisions.
Claude Agent SDK and LangGraph also require explicit skill authoring — add AgentSkill objects to your AgentCard regardless of framework:
Google ADK and to_a2a(): ADK’s to_a2a() constructs a minimal Agent Card from the agent’s name, description, and instruction — but does not populate AgentSkill definitions. For production CRAFT registrations, author explicit AgentSkill objects even when using ADK, to give orchestrators rich capability descriptions for routing decisions. Claude Agent SDK — Wrapping as an A2A Agent: The Claude Anthropic SDK does not natively produce A2A AgentSkill definitions. Wrap a Claude call inside a standard A2A server:
LangGraph — Wrapping as an A2A Agent:

JSON-RPC Methods

The A2A protocol exposes these JSON-RPC methods on your agent’s root endpoint (POST /):
MethodUse CaseResponse
message/sendFire-and-forget, await a single complete responseJSON-RPC response with Task
message/streamReal-time SSE stream of status and artifact eventsSSE event stream
tasks/getPoll for current task stateTask object
tasks/cancelCancel an in-progress taskAcknowledgment
tasks/resubscribeReconnect to a dropped SSE streamSSE event stream from current state
Most CRAFT agents use message/stream exclusively — it is the preferred method for all production interactions because it delivers progressive status updates to the user.

Message Structure

Every request to a CRAFT agent is a Message containing one or more Parts:
The A2A spec uses camelCase for protocol fields (messageId, contextId, taskId). The platform’s a2a-sdk server also accepts snake_case input (message_id, context_id) and normalizes, but responses are always camelCase — match the spec to keep request/response symmetric.

Part Types

Part Typekind valueUse Case
TextPart"text"Natural language input or agent response
DataPart"data"Structured JSON — datasource context, artifact references, selection context
FilePart"file"Binary content referenced by URI (asset://artifacts/chart.png)
The context_id groups messages into a conversation session. CRAFT agents use this to retrieve conversation history from the task store and maintain coherent multi-turn dialogue.

Task Lifecycle

Every message/send or message/stream call creates or resumes a Task. Tasks follow a strict state machine:
Terminal states (completed, failed, canceled, rejected) are final — a task in a terminal state cannot be restarted. To continue a conversation, the client sends a new message with the same context_id.

SSE Streaming — Event Sequence

When a client calls message/stream, the server responds with Content-Type: text/event-stream and pushes events as the agent works. Each data: line is a complete JSON-RPC 2.0 response object.

Event Types

Result TypeWhen Used
TaskFirst event — the created task (state = submitted)
TaskStatusUpdateEventLifecycle state changes and intermediate messages
TaskArtifactUpdateEventCompleted artifacts (results, charts, files)

Protocol Rules

  1. The first event MUST be a Task or a Message
  2. Intermediate events are TaskStatusUpdateEvent (state=working) and TaskArtifactUpdateEvent
  3. The final event MUST be TaskStatusUpdateEvent with final: true and a terminal state
  4. The SSE connection closes after the final event

Wire Example — Text2SQL Stream

The following is a real-world event sequence from the CRAFT text2sql agent:

Chunked Artifact Streaming

Large artifacts can be delivered in chunks using the append and lastChunk flags:

Agent-to-Agent Communication Flow

The following sequence diagram shows how an orchestrator delegates a task to a sub-agent using the A2A protocol.

Authentication

Agent Cards declare supported authentication schemes in securitySchemes. CRAFT agents use JWT bearer tokens — the orchestrator injects them when calling sub-agents.
Agents validate the token, extract the user_id and org_id, and use them to scope all database queries and audit logs. A small UserContextBuilder that reads the Authorization header and exposes a typed context object to your dependencies is the canonical pattern for Pydantic AI + a2a server integrations.

Reconnection

If an SSE connection drops mid-stream, the client can reconnect using tasks/resubscribe:
The server resumes the event stream from the task’s current state. Your agent implementation does not need to handle this explicitly — A2AStarletteApplication and DefaultRequestHandler manage reconnection automatically.

Next Steps

Your First Agent

Build your first agent using Google ADK, Pydantic AI, or another supported framework.

Multi-Agent Patterns

Orchestration, delegation, and fan-out across multiple A2A agents.