Skip to content
/ ra2a Public

Rust SDK for the Agent2Agent (A2A) Protocol.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

qntx/ra2a

ra2a

CI License Rust crates.io docs.rs

Comprehensive Rust SDK for the Agent2Agent (A2A) Protocol — client transport, server framework, streaming, gRPC, and multi-backend task storage.

ra2a implements the full A2A protocol specification (v0.3.0) with an idiomatic Rust API — Axum server middleware, reqwest-based client, SSE streaming, gRPC transport, push notifications, and pluggable SQL storage backends. For the upstream protocol specification, see google/A2A.

See Security before using in production.

Quick Start

Add ra2a to your project:

cargo add ra2a

Build an Agent (Server)

use async_trait::async_trait;
use ra2a::{
    error::Result,
    server::{A2AServerBuilder, AgentExecutor, ExecutionContext},
    types::{AgentCard, AgentCapabilities, AgentSkill, Message, Part, Task, TaskState, TaskStatus},
};

struct MyAgent { card: AgentCard }

#[async_trait]
impl AgentExecutor for MyAgent {
    async fn execute(&self, ctx: &ExecutionContext, message: &Message) -> Result<Task> {
        let reply = Message::agent(vec![Part::text("Hello from ra2a!")]);
        Ok(Task::new(&ctx.task_id, &ctx.context_id)
            .with_status(TaskStatus::with_message(TaskState::Completed, reply)))
    }

    async fn cancel(&self, ctx: &ExecutionContext, task_id: &str) -> Result<Task> {
        Ok(Task::new(task_id, &ctx.context_id)
            .with_status(TaskStatus::new(TaskState::Canceled)))
    }

    fn agent_card(&self) -> &AgentCard { &self.card }
}

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let card = AgentCard::builder("My Agent", "http://localhost:8080")
        .description("A minimal A2A agent")
        .version("1.0.0")
        .skill(AgentSkill::new("chat", "Chat", "General chat", vec![]))
        .build();

    A2AServerBuilder::new()
        .executor(MyAgent { card })
        .host("0.0.0.0")
        .port(8080)
        .cors(true)
        .build()
        .serve()
        .await
}

Talk to an Agent (Client)

use ra2a::client::{A2AClient, Client};

#[tokio::main]
async fn main() -> ra2a::Result<()> {
    let client = A2AClient::new("https://agent.example.com")?;

    // Discover agent capabilities
    let card = client.get_agent_card().await?;
    println!("Agent: {} — {}", card.name, card.description.unwrap_or_default());

    // Send a message and stream responses
    let message = ra2a::types::Message::user_text("Hello!");
    let mut stream = client.send_message(message).await?;

    while let Some(event) = futures::StreamExt::next(&mut stream).await {
        println!("{:?}", event?);
    }
    Ok(())
}

Feature Flags

Feature flags keep compile-time dependencies minimal — enable only what you need:

Flag Default Description
client yes HTTP/JSON-RPC client, SSE streaming, card resolver, middleware
server yes Axum HTTP server, event queue, task lifecycle, REST + SSE endpoints
grpc gRPC transport via tonic/prost (requires protobuf)
telemetry OpenTelemetry tracing spans and metrics
postgresql PostgreSQL task store via sqlx
mysql MySQL task store via sqlx
sqlite SQLite task store via sqlx
sql All SQL backends (postgresql + mysql + sqlite)
full Everything (server + grpc + telemetry + sql)
# Server with PostgreSQL storage and telemetry
ra2a = { version = "0.4", features = ["server", "postgresql", "telemetry"] }

# Client only
ra2a = { version = "0.4", default-features = false, features = ["client"] }

# Everything
ra2a = { version = "0.4", features = ["full"] }

Design

Aspect Detail
Protocol version A2A v0.3.0
Transport HTTP/JSON-RPC + SSE streaming + gRPC
Server framework Axum with Tower middleware
Client reqwest + reqwest-eventsource (SSE)
Task storage In-memory (default), PostgreSQL, MySQL, SQLite
Authentication HMAC-SHA256 push notification verification
Serialization serde (JSON) + prost (protobuf)
Async runtime tokio
Linting pedantic + nursery (warn), correctness (deny)

Examples

Run the built-in examples to see ra2a in action:

# Start the server
cargo run --example server --features server

# In another terminal, run the client
cargo run --example client --features client

Security

See SECURITY.md for disclaimers, supported versions, and vulnerability reporting.

Acknowledgments

License

Licensed under either of:

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project shall be dual-licensed as above, without any additional terms or conditions.

About

Rust SDK for the Agent2Agent (A2A) Protocol.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Contributors 2

  •  
  •