The A2A (Agent-to-Agent) CLI solves a specific problem: you want to run the same agent code on your laptop, in a Lightsail container, and inside Bedrock AgentCore Runtime, then call them all with identical commands. The CLI handles authentication, protocol version mismatches, and cross-environment routing so you can test locally and deploy without rewriting your orchestration layer.
This is not a managed service. It is a command-line client that speaks A2A protocol versions 0.3 and 1.0, carries agent-to-agent calls between environments, and abstracts the differences between localhost HTTP, Lightsail public endpoints, and Bedrock AgentCore's Cognito-gated runtime.
What the A2A CLI Does
The CLI is a single binary that:
- Discovers agent capabilities by fetching the agent card (A2A's service descriptor).
- Invokes agent tasks over JSON-RPC or REST, depending on what the agent advertises.
- Handles authentication tokens for Bedrock AgentCore Runtime (Cognito session headers).
- Proxies agent-to-agent calls when one agent needs to invoke another across deployment boundaries.
- Reports protocol version mismatches but continues if the wire format is compatible.
The reference implementation uses a Rust agent (A2A 1.0) that runs Mersenne prime tests and a Strands coordinator (A2A 0.3) that wraps Claude Haiku 5.5 on Bedrock. The Strands agent calls the Rust agent to execute the find_mersenne_primes tool. The CLI carries that call from AgentCore Runtime to a Lightsail container.
Deployment Shape
| Environment | Agent | Protocol | Authentication | Network Boundary |
|---|---|---|---|---|
| Localhost | Rust mersenne-agent | A2A 1.0 JSON-RPC + REST | None | localhost:8204 |
| Lightsail | Same Rust image | A2A 1.0 JSON-RPC + REST | None (public endpoint) | HTTPS via container service |
| Localhost | Strands coordinator | A2A 0.3 JSON-RPC | None | localhost:8209 |
| Bedrock AgentCore | Same Strands code | A2A 0.3 JSON-RPC | Cognito token + session header | HTTPS via AgentCore API |
The CLI uses the same command structure for all four:
a2a invoke --agent-card <URL> --task <task_name> --params <JSON>
For localhost, the agent card URL is http://localhost:8204/agent-card. For Lightsail, it is the public container service URL. For Bedrock AgentCore, it is the runtime endpoint with a Cognito token in the Authorization header and a session ID in a custom header.
Protocol Version Mismatch Handling
The Rust agent serves A2A 1.0. The Strands coordinator serves A2A 0.3. The CLI reads both by inspecting the agent card's protocol_version field and adjusting the request shape.
A2A 1.0 uses a different JSON-RPC method naming convention and adds optional fields for streaming and cancellation. A2A 0.3 does not support these fields. The CLI:
- Fetches the agent card.
- Checks the
protocol_versionfield. - Constructs the JSON-RPC request with the correct method name and optional fields.
- Logs a warning if the protocol version is unexpected but the wire format is compatible.
When the Strands agent (A2A 0.3) needs to call the Rust agent (A2A 1.0), it cannot use its own Python client because that client only speaks 0.3. Instead, the Strands agent shells out to the same a2a CLI binary and passes the Lightsail agent card URL. The CLI handles the version translation.
This is a temporary workaround. The A2A protocol is stabilizing, and future versions will likely converge on a single wire format with backward compatibility guarantees.
Authentication and Routing
Localhost
No authentication. The CLI sends HTTP requests directly to localhost:8204 or localhost:8209.
Lightsail
No authentication. The Lightsail container service exposes a public HTTPS endpoint. The CLI sends requests to that endpoint with the agent card URL as the base path.
Bedrock AgentCore Runtime
The CLI requires:
- A Cognito user pool token (obtained via
aws cognito-idp initiate-auth). - A session header (
X-AgentCore-Session-Id) that the runtime uses to track agent state. - The full agent card URL, which includes the runtime endpoint and agent ID.
The CLI stores the token in a local config file or environment variable. It adds the token and session header to every request. If the token expires, the CLI returns an authentication error and the user must refresh the token manually.
Cross-Environment Agent Calls
When the Strands agent on Bedrock AgentCore needs to call the Rust agent on Lightsail, the flow is:
- The Strands agent receives a task from the CLI.
- Claude Haiku 5.5 decides to invoke the
find_mersenne_primestool. - The Strands agent's tool implementation shells out to the
a2aCLI with the Lightsail agent card URL. - The CLI sends a JSON-RPC request to the Lightsail container.
- The Rust agent executes the Mersenne prime test and returns the result.
- The CLI returns the result to the Strands agent.
- The Strands agent returns the final result to the original CLI invocation.
This creates a chain: CLI (user) → AgentCore Runtime (Strands) → CLI (embedded) → Lightsail (Rust) → CLI (embedded) → AgentCore Runtime (Strands) → CLI (user).
The CLI does not maintain persistent connections. Each agent-to-agent call is a separate HTTP request. State is managed by the agents themselves, not by the CLI.
Observability Gaps
The CLI logs requests and responses to stdout. It does not emit structured logs, traces, or metrics. You cannot observe the full call chain without instrumenting each agent separately.
For production use, you would need to:
- Add OpenTelemetry tracing to the CLI and each agent.
- Correlate traces across the CLI → AgentCore → CLI → Lightsail boundary.
- Instrument the Strands agent's shell-out to the CLI so you can see when it makes cross-environment calls.
The reference implementation does not include this instrumentation.
Failure Modes
Token expiration: If the Cognito token expires mid-session, the CLI returns a 401 error. The user must refresh the token and retry. There is no automatic token refresh.
Protocol version incompatibility: If the agent card advertises a protocol version the CLI does not recognize, the CLI logs a warning and attempts to send the request anyway. If the wire format is incompatible, the agent returns a JSON-RPC error.
Network partition: If the Lightsail container is unreachable, the CLI times out after 30 seconds. The Strands agent's tool call fails, and Claude Haiku 5.5 receives an error message. The model may retry or return an error to the user.
Agent crash: If the Rust agent crashes mid-request, the CLI returns a connection error. The Strands agent's tool call fails. There is no retry logic in the CLI or the Strands agent.
Session ID mismatch: If the session header does not match the AgentCore Runtime's expected session ID, the runtime returns a 400 error. The CLI does not automatically create a new session.
Code Example: CLI Invocation
# Localhost Rust agent
a2a invoke \
--agent-card http://localhost:8204/agent-card \
--task find_mersenne_primes \
--params '{"n": 10}'
# Lightsail Rust agent
a2a invoke \
--agent-card https://mersenne.lightsail.aws/agent-card \
--task find_mersenne_primes \
--params '{"n": 10}'
# Bedrock AgentCore Strands agent
export A2A_TOKEN=$(aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id <id> --auth-parameters USERNAME=<user>,PASSWORD=<pass> --query 'AuthenticationResult.IdToken' --output text)
a2a invoke \
--agent-card https://agentcore.us-east-1.amazonaws.com/agents/<agent-id>/agent-card \
--task coordinate \
--params '{"prompt": "Find the first 10 Mersenne primes"}' \
--token $A2A_TOKEN \
--session-id <session-id>
The CLI reads the agent card, determines the protocol version, constructs the JSON-RPC request, and sends it to the appropriate endpoint.
When to Use This
Use the A2A CLI when:
- You are building agents that need to run in multiple environments (laptop, cloud VM, managed runtime).
- You want to test agent-to-agent calls locally before deploying to AWS.
- You need a single command interface that abstracts authentication and protocol version differences.
- You are willing to manage Cognito tokens and session IDs manually.
Avoid the A2A CLI when:
- You need automatic token refresh or session management.
- You require structured observability (traces, metrics, logs) across the full call chain.
- You are deploying agents that must handle protocol version mismatches in production (the CLI's version translation is a temporary workaround, not a long-term solution).
- You need retry logic, circuit breakers, or other resilience patterns (the CLI does not provide these).
Technical Verdict
The A2A CLI is a useful development tool for testing agent-to-agent calls across deployment boundaries. It handles the plumbing (authentication, protocol version detection, cross-environment routing) so you can focus on agent logic. The protocol version mismatch handling is pragmatic but fragile. The lack of observability and resilience patterns means you will need to build those layers yourself for production use. If you are experimenting with A2A agents on AWS and want a single command interface for localhost, Lightsail, and Bedrock AgentCore, this is a reasonable starting point. If you are deploying production agents, you will need to replace the CLI with a proper orchestration layer that handles token refresh, tracing, retries, and session management.
Top comments (0)