Skip to main content
A2A is the open Agent2Agent protocol (v1.0, stewarded by the Linux Foundation) for communication between independent AI agents. The Mibyan A2A plugin works in both directions: your agent can call other A2A agents as tools, and other agents can send tasks to your Mibyan over HTTP. It interoperates with any A2A-compliant peer — another Mibyan, LangChain, CrewAI, Google ADK agents, or anything built on the official a2a-sdk.

When to use A2A

  • Mibyan ↔ Mibyan across machines — let your desktop agent hand tasks to a Mibyan on a server, or vice versa, each with its own memory, tools, and credentials.
  • Delegating to specialist agents — a peer that advertises web_search/research/coding skills on its Agent Card can be discovered and called mid-conversation.
  • Being a callable service — expose your Mibyan so other frameworks’ agents can send it tasks.
When you want multiple agents on the same machine, prefer delegation (in-process subagents) or the kanban board (durable multi-profile work queue) — A2A is for crossing process/machine/framework boundaries.

Enable

Or in ~/.mibyan/config.yaml:
The outbound client tools ship as the a2a toolset, off by default — enable it per platform:
The tools are available in every process type — CLI, TUI, gateway, and cron — without the inbound platform needing to be enabled.

Outbound: calling other agents

With the a2a toolset enabled, the agent gets: Configure known peers in config.yaml:
Then just ask: “Ask the researcher agent to summarize today’s arXiv postings.” Direct URLs work too — a2a_call accepts any A2A endpoint.

Inbound: being callable

With the platform enabled, Mibyan serves:
  • Agent Card at GET /.well-known/agent-card.json (canonical v1.0 path; the legacy agent.json also answers) — advertises your agent’s name, skills (derived from enabled toolsets), and auth requirements.
  • JSON-RPC 2.0 at POST / — canonical v1.0 methods (SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, SubscribeToTask, push-notification config CRUD) plus the pre-1.0 path-style aliases (message/send, …).
  • SSE streaming for SendStreamingMessage, with spec-correct JSON-RPC-enveloped frames.
  • Push notifications (webhooks) for long-running tasks, HMAC-SHA256 signed.
Inbound tasks are injected into a live gateway session — the same agent, memory, and tools that serve your other channels — and the final reply is returned to the caller as the task result. Conversations are keyed by the A2A contextId, so a peer can hold a multi-turn exchange. Interoperability is verified against the official Python a2a-sdk (card resolution, SendMessage, streaming).

Security model

Secure by default; every widening step is explicit:
  • No token ⇒ localhost only. The server binds 127.0.0.1. Remote exposure requires a bearer token and an explicit A2A_HOST.
  • Per-peer tokens — A2A_PEER_TOKENS="alice:tok1,bob:tok2" gives each peer its own credential; the authenticated name drives rate limiting, trust, and audit.
  • Prompt-injection filtering — inbound text is filtered and framed as untrusted peer input. Remote peers cannot invoke operator slash commands.
  • Outbound redaction — credential-shaped strings (API keys, JWTs, tokens) are scrubbed from replies.
  • Audit log — every exchange appends to ~/.mibyan/a2a_audit.jsonl.
  • Anti-loop — per-context turn caps stop two agents ping-ponging forever.

Configuration reference

Behind a reverse proxy or Kubernetes Service, set A2A_PUBLIC_URL (or rely on X-Forwarded-Host/X-Forwarded-Proto) so the Agent Card advertises a URL peers can actually call back.

Quick test

Troubleshooting

  • Peers can’t reach the card URL — the card was advertising your bind address; set A2A_PUBLIC_URL to the externally routable URL.
  • 401 Unauthorized — token mismatch; check A2A_PEER_TOKENS/A2A_BEARER_TOKEN on the server and the peer’s auth: block.
  • Server won’t bind non-localhost — by design: set a bearer token first, then A2A_HOST=0.0.0.0.
  • Replies time out on long tasks — raise A2A_REPLY_TIMEOUT (the orphan sweep follows it, so a late reply is stored, not discarded), or have the caller register a push-notification config and poll GetTask.