brainwires-a2a
Full Rust implementation of the Agent-to-Agent (A2A) protocol — the open standard (Google / Linux Foundation) for interoperable agent communication.
Covers all three protocol bindings: JSON-RPC 2.0, HTTP/REST, and gRPC.
Features
| Feature | Default | Description |
|---|---|---|
client |
yes (via native) |
HTTP client for JSON-RPC and REST (reqwest) |
server |
yes (via native) |
HTTP server for JSON-RPC and REST (hyper) |
native |
yes | Both client and server |
grpc |
no | Proto types (prost + tonic) |
grpc-client |
no | gRPC client transport |
grpc-server |
no | gRPC server service |
full |
no | Everything |
Types are always available with no features enabled — useful if you only need the data model.
Quick start
Client
use ;
use Url;
async
Server
Implement the A2aHandler trait once — the server routes JSON-RPC, REST, and gRPC requests to it automatically.
use SocketAddr;
use Pin;
use async_trait;
use *;
use Stream;
async
Protocol bindings
JSON-RPC 2.0 (primary)
The primary binding used by the official Python SDK. Requests are POST / with a JSON-RPC body. Streaming methods (message/stream, tasks/resubscribe) return text/event-stream (SSE) where each data: line is a JSON-RPC response.
Methods:
| Method | Description |
|---|---|
message/send |
Send a message, get Task or Message back |
message/stream |
Send a message, stream SSE events |
tasks/get |
Get a task by ID |
tasks/list |
List tasks with filters |
tasks/cancel |
Cancel a running task |
tasks/resubscribe |
Re-subscribe to task updates (SSE) |
tasks/pushNotificationConfig/set |
Create/update push config |
tasks/pushNotificationConfig/get |
Get push config |
tasks/pushNotificationConfig/list |
List push configs |
tasks/pushNotificationConfig/delete |
Delete push config |
agent/authenticatedExtendedCard |
Get extended agent card |
HTTP/REST
RESTful endpoints derived from google.api.http annotations in the proto spec. All endpoints also accept an optional /{tenant}/ prefix.
| Method | Endpoint | Description |
|---|---|---|
| GET | /.well-known/agent-card.json |
Agent card discovery |
| POST | /message:send |
Send message |
| POST | /message:stream |
Stream message (SSE) |
| GET | /tasks/{id} |
Get task |
| GET | /tasks |
List tasks |
| POST | /tasks/{id}:cancel |
Cancel task |
| GET | /tasks/{id}:subscribe |
Subscribe to updates (SSE) |
| POST | /tasks/{task_id}/pushNotificationConfigs |
Create push config |
| GET | /tasks/{task_id}/pushNotificationConfigs/{id} |
Get push config |
| GET | /tasks/{task_id}/pushNotificationConfigs |
List push configs |
| DELETE | /tasks/{task_id}/pushNotificationConfigs/{id} |
Delete push config |
| GET | /extendedAgentCard |
Get extended agent card |
gRPC
Generated from the official a2a.proto (lf.a2a.v1.A2AService) via tonic-build. Enable with the grpc, grpc-client, or grpc-server features.
The gRPC server runs on a separate port and can be enabled alongside HTTP:
let server = new
.with_grpc;
server.run.await?;
Transport selection (client)
// JSON-RPC (default, compatible with Python SDK)
let client = new_jsonrpc;
// REST
let client = new_rest;
// gRPC (requires grpc-client feature)
let client = new_grpc.await?;
All A2aClient methods work identically regardless of transport.
Error codes
Spec-defined JSON-RPC error codes are available as constants:
| Code | Constant | Meaning |
|---|---|---|
| -32700 | JSON_PARSE_ERROR |
Invalid JSON payload |
| -32600 | INVALID_REQUEST |
Request validation error |
| -32601 | METHOD_NOT_FOUND |
Method not found |
| -32602 | INVALID_PARAMS |
Invalid parameters |
| -32603 | INTERNAL_ERROR |
Internal error |
| -32001 | TASK_NOT_FOUND |
Task not found |
| -32002 | TASK_NOT_CANCELABLE |
Task cannot be canceled |
| -32003 | PUSH_NOT_SUPPORTED |
Push notifications not supported |
| -32004 | UNSUPPORTED_OPERATION |
Operation not supported |
| -32005 | CONTENT_TYPE_NOT_SUPPORTED |
Incompatible content types |
| -32006 | INVALID_AGENT_RESPONSE |
Invalid agent response |
| -32007 | EXTENDED_CARD_NOT_CONFIGURED |
Extended card not configured |
Cargo.toml
# Types only (no networking)
= { = "0.1", = false }
# Client + server (JSON-RPC + REST)
= "0.1"
# Everything including gRPC
= { = "0.1", = ["full"] }
Or via the brainwires facade crate:
= { = "0.1", = ["a2a"] }
License
MIT OR Apache-2.0