Skip to content

A2A Protocol

BMO supports the A2A protocol in both directions:

  • As a client, BMO can send work to another A2A-compatible agent with invoke_a2a.
  • As a server, bmo serve can expose BMO through an agent card and JSON-RPC endpoint.

Planes: A2A is the horizontal agent↔agent execution plane. MCP is tool access; ACP (bmo acp) is editor session streaming. Agent mesh only picks which peer receives the task. See Protocol support § Three planes.

invoke_a2a resolves the remote peer in this order (first match wins):

  1. agent_card_url — explicit URL or agent-card file path.
  2. agent_name — deployed agent from the BMO deploy registry (tunneled A2A URL when deploy is enabled).
  3. capability — mesh resolve when Agent mesh is enabled and no URL/name is set.
  4. options.a2a.default_agent_card_url — config default when the call omits the above.

Use invoke_a2a to send work to a remote A2A agent by base URL or agent-card file:

invoke_a2a(agent_card_url="https://other-agent.example.com", message="Refactor the auth module")

When the Agent mesh is enabled, you can omit agent_card_url and pass a capability instead; BMO resolves the capability to a registered agent and invokes it:

invoke_a2a(capability="run_tests", message="Run the full test suite")

The visible tool output is an aggregated final text result. The response metadata carries the remote task_id, context_id, task state, and any structured status_message, parts, and artifacts returned by the remote agent.

If the remote agent returns input-required, continue the same task by reusing the returned task_id:

invoke_a2a(
agent_card_url="https://other-agent.example.com",
task_id="remote-task-id",
context_id="remote-context-id",
message="approve"
)

To refresh the latest remote state without sending new input, call invoke_a2a again with task_id and no message.

If the remote agent returns auth-required, complete whatever authentication flow that agent requested, then reuse the same task_id to continue or refresh the task.

When the remote agent returns richer non-text task data, BMO preserves it in response metadata even though the visible tool output remains text-first for agent UX compatibility.

  • Reusing the same task_id continues the same remote task.
  • Reusing the same context_id lets related tasks stay grouped in the same remote A2A context when the peer supports it.

DAG workflows (orchestrate_workflow / execute_dag)

Section titled “DAG workflows (orchestrate_workflow / execute_dag)”

Multi-step remote graphs use the same mesh + A2A chain per node: capability resolve (when configured), then A2A task invoke. Non-terminal peer states stop the graph for follow-up—they are not silent success:

Remote stateMeaning for the workflow
input-requiredSend another message on the same task_id before downstream nodes run.
auth-requiredComplete the peer’s auth step, then continue on the same task.
failedPeer reported failure; no mesh transport retry.
Unreachable peerMay try the next mesh candidate for that node (same as standalone invoke_a2a).

See Tools reference (orchestrate_workflow, execute_dag) and maintainer tools-workflows.

Enable BMO’s A2A endpoint in your config:

[options.a2a]
enabled = true
agent_name = "BMO"
agent_description = "BMO AI coding agent"
default_timeout = 120

When enabled, bmo serve registers:

  • GET /.well-known/agent-card.json — agent discovery endpoint
  • POST /a2a — task execution endpoint

The published agent card advertises BMO’s JSON-RPC transport, streaming task events, fixed capability skills, and bearer authentication when server auth is configured.

  • BMO persists A2A task state so tasks remain queryable after completion.
  • BMO reuses the same BMO session for a new task on an existing context_id only after the latest task in that context has reached a terminal state. If the latest task is still active or waiting for input/auth, BMO creates a fresh local session for the new task.
  • If a caller sends structured JSON or file parts, BMO converts them into attachments and includes a short synthesized prompt header for the local agent.
  • If a part type cannot be translated safely, BMO fails the task explicitly instead of silently dropping it.

POST /a2a is protected by the same authentication as the rest of bmo serve. Callers must send Authorization: Bearer <token> unless the server was explicitly started with --allow-no-auth, which is restricted to loopback-only use. See the CLI reference and server configuration for how to set the token.

If an inbound A2A task reaches a permission gate, BMO returns input-required with the pending tool details. The caller can continue the same task by sending approve or deny as the next user message on that task.

OptionDefaultDescription
enabledfalseEnable A2A protocol support
agent_nameBMOName exposed in the agent card
agent_descriptionBMO AI coding agentDescription in the agent card
default_timeout120Client request timeout in seconds
default_agent_card_urlDefault agent card URL or file path when invoke_a2a is called without agent_card_url