Introduction
a2a-rust is a pure Rust implementation of the Agent2Agent (A2A) protocol — an open standard for connecting AI agents over the network. It is written against the v1.0.1 specification; the version carried on the wire is 1.0, since §3.6 excludes patch numbers from requests, responses and Agent Cards.
If you're building AI agents that need to talk to each other, discover capabilities, delegate tasks, and stream results — this library gives you the full protocol stack with zero unsafe code, compile-time type safety, and production-grade hardening.
What is the A2A Protocol?
The Agent2Agent protocol defines how AI agents discover, communicate with, and delegate work to each other. Think of it as HTTP for AI agents: a shared language that lets any agent talk to any other, regardless of implementation.
The protocol defines:
- Agent Cards — Discovery documents describing what an agent can do
- Tasks — Units of work with well-defined lifecycle states
- Messages — Structured payloads carrying text, data, or binary content
- Streaming — Real-time progress via Server-Sent Events (SSE)
- Push Notifications — Webhook delivery for async results
Why Rust?
Rust gives you performance, safety, and correctness without compromise:
- Zero-cost abstractions — Trait objects, generics, and async/await with no runtime overhead
- No
unsafe— The entire codebase is free of unsafe code - Thread safety at compile time — All public types implement
Send + Sync - Exhaustive pattern matching — The compiler catches missing protocol states
- Production-ready — Battle-tested HTTP via hyper, robust error handling, no panics on any caller input or I/O failure
Architecture at a Glance
a2a-rust is organized as a Cargo workspace with four crates:
┌─────────────────────────────────────────────┐
│ a2a-protocol-sdk │
│ umbrella re-exports + prelude │
├──────────────────────┬──────────────────────┤
│ a2a-protocol-client │ a2a-protocol-server │
│ HTTP client │ agent framework │
├──────────────────────┴──────────────────────┤
│ a2a-protocol-types │
│ wire types, serde, no I/O │
└─────────────────────────────────────────────┘
| Crate | Purpose |
|---|---|
a2a-protocol-types | All A2A wire types with serde serialization. Pure data — no I/O, no async. |
a2a-protocol-client | HTTP client for calling remote A2A agents. Supports JSON-RPC and REST transports, plus WebSocket and gRPC behind feature flags. |
a2a-protocol-server | Server framework for building A2A agents. Pluggable stores, interceptors, and dispatchers. |
a2a-protocol-sdk | Umbrella crate that re-exports everything with a convenient prelude module. |
Key Features
- Full v1.0 wire types — Every A2A type with correct JSON serialization
- Quad transport — JSON-RPC 2.0, REST, WebSocket (
websocketfeature flag), and gRPC (grpcfeature flag), both client and server - SSE streaming — Real-time
SendStreamingMessageandSubscribeToTask - Push notifications — Pluggable
PushSenderwith SSRF protection - Agent card discovery — Static and dynamic card handlers with HTTP caching (ETag, Last-Modified, 304)
- Pluggable stores —
TaskStoreandPushConfigStoretraits with in-memory, SQLite, PostgreSQL, and tenant-aware backends - Multi-tenancy —
TenantAwareInMemoryTaskStore,TenantAwareSqliteTaskStore, andTenantAwarePostgresTaskStorewith full tenant isolation - Interceptor chains — Client and server middleware for auth, logging, metrics, rate limiting
- Rate limiting — Built-in
RateLimitInterceptorwith per-caller fixed-window limiting - Client retry — Configurable
RetryPolicywith exponential backoff for transient failures - Server startup helper —
serve()reduces ~25 lines of hyper boilerplate to one call - Request ID propagation —
CallContext::request_idauto-extracted fromX-Request-IDheader - Task store metrics —
TaskStore::count()for monitoring and capacity management - Task state machine — Validated transitions per the A2A specification
- Executor ergonomics —
boxed_future,agent_executor!macro,EventEmitterreduce boilerplate - Executor timeout — Kills hung agent tasks automatically
- CORS support — Configurable cross-origin policies
- Fully configurable — All defaults (timeouts, limits, intervals) are overridable via builders
- Mutation-tested — Zero surviving mutants enforced via
cargo-mutantsCI gate - No panics on fallible paths — Every operation that can fail on input, network, or storage errors returns
Result; the onlyexpectcalls in library code assert internal invariants (e.g. lock-poisoning propagation) that no caller input can trigger
All 11 Protocol Methods
| Method | Description |
|---|---|
SendMessage | Synchronous message send; returns completed task |
SendStreamingMessage | Streaming send with real-time SSE events |
GetTask | Retrieve a task by ID |
ListTasks | Query tasks with filtering and pagination |
CancelTask | Request cancellation of a running task |
SubscribeToTask | Re-subscribe to an existing task's event stream |
CreateTaskPushNotificationConfig | Register a webhook for push delivery |
GetTaskPushNotificationConfig | Retrieve a push config by ID |
ListTaskPushNotificationConfigs | List all push configs for a task |
DeleteTaskPushNotificationConfig | Remove a push config |
GetExtendedAgentCard | Fetch authenticated agent card |
What's Next?
- Installation — Add a2a-rust to your project
- Quick Start — See the protocol in action in 5 minutes
- Your First Agent — Build an echo agent from scratch
- Protocol Overview — Understand the A2A protocol model