- CLI Reference
- Commands
- ironflow a2a
ironflow a2a
Expose agents to remote agents over the Agent2Agent (A2A) protocol, version 1.0.
ironflow a2a --agent <function-id> [flags]ironflow a2a is a separate process. It calls the Ironflow server through the public API. It keeps no state: one A2A task is one Ironflow run, and the task ID is the run ID. You can restart the adapter while tasks run.
Each exposed agent has its own address:
| Address | Content |
|---|---|
<public-url>/agents/<function-id>/.well-known/agent-card.json | Agent Card. No token is necessary. |
<public-url>/agents/<function-id> | JSON-RPC binding |
<public-url>/agents/<function-id>/... | HTTP+JSON binding |
| Flag | Default | Description |
|---|---|---|
--agent | (none) | Function ID of an agent to expose. Repeatable. At least one is necessary. |
--caller-input | (none) | An event name that remote callers can send to a waiting run of the function, as <function-id>/<event-name>. Use the name that the agent passes to approve(). Repeatable. |
--server-url | (none) | Ironflow server URL. When not set, the adapter uses IRONFLOW_SERVER_URL, then http://localhost:9123. |
--api-key | IRONFLOW_API_KEY | API key for the Ironflow server. The key needs the developer role. |
--host | 127.0.0.1 | Host to listen on. |
--port | 9124 | Port to listen on. |
--public-url | http://<host>:<port> | Base URL that remote callers use. The adapter writes it into the Agent Cards. |
Environment
Section titled “Environment”| Variable | Description |
|---|---|
IRONFLOW_A2A_BEARER_TOKEN | Required. Remote callers send this token as Authorization: Bearer <token>. |
IRONFLOW_SERVER_URL | Ironflow server URL, when --server-url is not set. |
IRONFLOW_API_KEY | API key for the Ironflow server, when --api-key is not set. |
Authentication
Section titled “Authentication”Remote callers present the bearer token. The adapter calls the Ironflow server with its own API key. Callers do not get an Ironflow API key, so they can reach only the exposed agents.
All callers share one token. Each caller can read and cancel the tasks of the other callers for the same agent.
A caller reaches only the runs that the adapter started. A run of the same function that staff, an event or a schedule started is not an A2A task: the adapter does not list it and reports it as not found.
The adapter serves plain HTTP. For a host that is not loopback, put a TLS proxy in front of the adapter and set --public-url.
On a loopback listener, a request with a Host header that is not loopback and is not the --public-url host gets 403. This protects against DNS rebinding.
Task states
Section titled “Task states”| Ironflow run | A2A task |
|---|---|
| Waiting for capacity | TASK_STATE_SUBMITTED |
| Running or paused | TASK_STATE_WORKING |
Waiting for an event name that --caller-input lists | TASK_STATE_INPUT_REQUIRED |
| Waiting for any other reason | TASK_STATE_WORKING |
| Completed, failed, cancelled | TASK_STATE_COMPLETED, TASK_STATE_FAILED, TASK_STATE_CANCELED |
Limits
Section titled “Limits”SendMessagewaits 30 seconds at most for the task to finish. Then it returns the task in its current state. UseGetTaskorSubscribeToTaskto follow a long task.- Streams send task states and the names of completed steps. They do not send model tokens.
- Push notifications, the gRPC binding and the extended Agent Card are not available.
- A file part must carry a URL. Inline file bytes are not accepted.
- A message must have a
messageId, a role and at least one part. ThemessageIdis the idempotency key: a retry with the same ID gets the same task. - One request can be 4 MiB at most.
- An open stream sends a keep-alive comment line every 15 seconds.
ListTaskssetstotalSizeto the number of tasks in the returned page. UsenextPageTokento get more pages.SubscribeToTaskrefuses a task that is already completed, failed or canceled.- A failed task carries the error message of the run. Do not put secrets or internal addresses in the errors that an agent returns.
See Expose an agent over A2A for a full example.