a2a-rs
A Rust implementation of the Agent-to-Agent (A2A) Protocol v1.0.0, providing a type-safe, idiomatic way to build agent communication systems.
Features
- 🚀 A2A Protocol v1.0.0 - Implements the A2A specification (see Spec compliance for the small, documented divergences), including:
- Enhanced push notification management with listing and deletion
- Task listing with comprehensive filtering and pagination
- Authenticated extended card support
- Protocol extensions framework
- Multi-transport support: spec-compliant JSON-RPC 2.0 and HTTP+JSON, plus ConnectRPC (see Spec compliance)
- 🔄 Multiple Transport Options - HTTP support
- 📡 Streaming Updates - Real-time task and artifact updates
- 🔐 Authentication & Security - JWT, OAuth2, OpenID Connect support with agent card signatures
- 💾 Persistent Storage - SQLx integration for task persistence
- 🎯 Async-First Design - Built on Tokio with async/await throughout
- 🧩 Modular Architecture - Use only the features you need
- ✅ Type Safety - Leverages Rust's type system for protocol compliance
Quick Start
Add to your Cargo.toml:
[]
= "0.1.0"
# For HTTP client
= { = "0.1.0", = ["http-client"] }
# For HTTP server
= { = "0.1.0", = ["http-server"] }
# Full feature set
= { = "0.1.0", = ["full"] }
Client Example
use ;
use Transport;
async
Server Example
use ;
use ;
;
async
Architecture
This library follows a hexagonal architecture pattern:
- Domain: Core business logic and types
- Ports: Trait definitions for external dependencies
- Adapters: Concrete implementations for different transports and storage
Spec compliance
a2a-rs targets A2A Protocol v1.0.0 and is wire-compatible with the
specification: the domain types, transports, and StreamResponse/JSON-RPC
payloads follow the spec, so off-the-shelf A2A clients and servers interoperate.
There are a couple of small, deliberate divergences, all backward-compatible:
Last-Event-IDstream resumption is an opt-in enhancement, not a spec feature. The A2A spec reconnects a dropped stream by re-issuing the subscribe call (resuming from the task's current state). On top of that,a2a-rsadds gap-free resumption using the W3C SSE-standardid:field andLast-Event-IDheader (RetryingTransport/WebA2AClient::subscribe_resilienton the client; buffered replay on the server). This is fully interoperable — spec clients ignore theid:field and never send the header, getting standard reconnect-from-current-state behavior — but gap-free resume only works a2a-rs ↔ a2a-rs, not against third-party agents. For strictly spec-shaped streaming, useWebA2AClient::subscribe(orsubscribe_to_taskwithlast_event_id = None).- ConnectRPC is offered as an additional transport. The spec names three
transport bindings —
JSONRPC,GRPC, andHTTP+JSON.a2a-rsadds ConnectRPC as the in-tree default (advertised in the agent card under the non-specCONNECTRPCbinding), alongside a spec-compliant JSON-RPC 2.0 transport and HTTP+JSON/REST. For interop with third-party A2A agents use the JSON-RPC transport (JsonRpcClient/jsonrpc_router); ConnectRPC is the preferred path a2a-rs ↔ a2a-rs. - JSON-RPC method names follow the proto RPC names (
SubscribeToTask,SendStreamingMessage, …) rather than the canonical JSON-RPC strings (tasks/resubscribe,message/stream); the request/response bodies are spec-shaped ProtoJSON.
Feature Flags
client- Client-side functionalityserver- Server-side functionalityhttp-client- HTTP client implementationhttp-server- HTTP server implementationauth- Authentication support (JWT, OAuth2, OpenID Connect)sqlx-storage- SQLx-based persistent storagesqlite- SQLite database supportpostgres- PostgreSQL database supportmysql- MySQL database supporttracing- Structured logging and tracingfull- All features enabled
Examples
See the examples directory for complete working examples:
Documentation
Full API documentation is available on docs.rs.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.