One runnable client example per JSON-RPC method in the A2A specification,
sharing a single offline server. Every example uses the typed request /
response structs from [inference_gateway_adk::a2a_types] - no hand-rolled
JSON envelopes.
a2a-methods/
├── docker-compose.yaml # Server + one Compose profile per client
├── server/main.rs # shared offline server (echo fallback)
└── client/
├── message_send.rs # message/send
├── message_stream.rs # message/stream
├── tasks_get.rs # tasks/get
├── tasks_list.rs # tasks/list
├── tasks_cancel.rs # tasks/cancel
├── tasks_resubscribe.rs # tasks/resubscribe
├── push_config_set.rs # tasks/pushNotificationConfig/set
├── push_config_get.rs # tasks/pushNotificationConfig/get
├── push_config_list.rs # tasks/pushNotificationConfig/list
├── push_config_delete.rs # tasks/pushNotificationConfig/delete
└── agent_authenticated_extended_card.rs # agent/getAuthenticatedExtendedCard
The compose manifest builds one long-running server container plus eleven
per-method client containers, each parked behind its own
Compose profile so a bare docker compose up doesn't
fan out into eleven parallel runs.
cd examples/a2a-methods
# Pick a single method to exercise:
docker compose --profile message-send up --build
docker compose --profile message-stream up --build
docker compose --profile tasks-get up --build
docker compose --profile tasks-list up --build
docker compose --profile tasks-cancel up --build
docker compose --profile tasks-resubscribe up --build
docker compose --profile push-config-set up --build
docker compose --profile push-config-get up --build
docker compose --profile push-config-list up --build
docker compose --profile push-config-delete up --build
docker compose --profile agent-authenticated-extended-card up --build
# Or run every client in sequence against the same server:
docker compose --profile all-clients up --buildThe selected profile pulls the server service in as a dependency, so you
never need to start it by hand. No .env file is required - the server is
offline (no Inference Gateway, no LLM credentials).
In one terminal, start the server:
cargo run -p a2a-methods-serverIn another terminal, run any of the per-method clients:
cargo run -p a2a-methods-message-send
cargo run -p a2a-methods-message-stream
cargo run -p a2a-methods-tasks-get
cargo run -p a2a-methods-tasks-list
cargo run -p a2a-methods-tasks-cancel
cargo run -p a2a-methods-tasks-resubscribe
cargo run -p a2a-methods-push-config-set
cargo run -p a2a-methods-push-config-get
cargo run -p a2a-methods-push-config-list
cargo run -p a2a-methods-push-config-delete
cargo run -p a2a-methods-agent-authenticated-extended-cardThe server listens on port 8085 by default (override with SERVER_PORT=…).
Clients respect SERVER_URL and default to http://localhost:8085.
- No LLM is wired up.
message/sendandmessage/streamfall through to the built-in offline echo reply, so each client runs end-to-end without external credentials. - Examples that mutate state (e.g.
tasks/cancel,pushNotificationConfig/{set,get,list,delete}) seed their own task viamessage/sendfirst so they remain self-contained and re-runnable. - Webhook delivery for push notifications is tracked in a separate ticket;
the four
pushNotificationConfig/*methods here exercise the control plane (storage + retrieval) only. - The shared example server opts into the extended agent card by setting
supportsExtendedAgentCard: trueon the static agent card it advertises; this is what letsa2a-methods-agent-authenticated-extended-cardsucceed rather than receiveMETHOD_NOT_FOUND. Production agents should gate the flag on their own auth policy. tasks/resubscribelets a client re-attach to an existingtasks/{task_id}resource and receive a snapshot of its current state followed by any remainingTaskStatusUpdateEventdeltas. The example here seeds a task viamessage/send(which the echo handler completes immediately) so the resubscribed stream emits a snapshot and a terminalfinal: trueupdate.