Academy → Messaging ChannelsOfficial documentation · Arabic guidance

A2A (Agent-to-Agent)

التواصل بين الوكلاء A2A

Intermediate5 min readLesson 295 questions✓ 2026-08-18
Before you read

What this page is, and what it holds.

This page covers A2A (Agent-to-Agent). You will use hermes tools enable a2a and hermes gateway setup here; about 5 minutes to read. Open the channel to yourself first with an allowlist. An open channel means anyone can message your agent.

8sections
5code examples
2tables
2commands
845source words
What you will be able to do

Outcomes taken from this page, not a template.

  • Understand what بوابة المراسلة is and when you need it.
  • Run hermes tools enable a2a and hermes gateway setup and understand what happens next.
  • Read the table and take only the row that applies to you.
  • Set A2A_HOST in the right place.
Identifiers you will meet

Exactly as they appear in Hermes.

Commands
  • hermes tools enable a2a
  • hermes gateway setup
Environment variables
  • A2A_HOST
  • A2A_PUBLIC_URL
  • ROLE_USER
  • A2A_PEER_TOKENS
  • A2A_BEARER_TOKEN
  • A2A_REPLY_TIMEOUT
Page map

Jump to the part you need.

  1. 01When to use A2A
  2. 02Enable
  3. 03Outbound: calling other agents
  4. 04Inbound: being callable
  5. 05Security model
  6. 06Configuration reference
  7. 07Quick test
  8. 08Troubleshooting
The full official page

Nothing summarised away.

The documentation body below is reproduced from the official source so commands and identifiers stay exact. Each section carries a short note describing what it contains.

A2A ↗ is the open Agent2Agent protocol (v1.0, stewarded by the Linux Foundation) for communication between independent AI agents. The Hermes A2A plugin works in both directions: your agent can call other A2A agents as tools, and other agents can send tasks to your Hermes over HTTP.

It interoperates with any A2A-compliant peer — another Hermes, LangChain, CrewAI, Google ADK agents, or anything built on the official a2a-sdk.

When to use A2A

Explains the idea itself. Read it slowly; the later sections build on it.

  • Hermes ↔ Hermes across machines — let your desktop agent hand tasks to a Hermes 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 Hermes 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

Settings you configure once. Change one at a time so you can see what each does. Commands here: hermes gateway setup.

Shell1 line
hermes gateway setup      # pick A2A

Or in ~/.hermes/config.yaml:

YAML6 lines
gateway:
  platforms:
    a2a:
      enabled: true
      extra:
        port: 9900

The outbound client tools ship as the a2a toolset, off by default — enable it per platform:

Shell3 lines
hermes tools enable a2a --platform cli        # CLI/TUI sessions
hermes tools enable a2a --platform telegram   # or any messaging platform
hermes tools enable a2a --platform a2a        # let inbound A2A tasks call peers (agent chaining)

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

A lookup table. Do not read it all; find the row that applies to you.

With the a2a toolset enabled, the agent gets:

ToolWhat it does
a2a_discover(url)Fetch and summarize a peer's Agent Card
a2a_call(agent, message, context_id?)Send a task, get the reply; multi-turn via context_id
a2a_list()Configured peers, saved conversations, metrics
a2a_history(context_id)Recall a persisted A2A conversation
a2a_orchestrate(capability, message, mode?)Fan a task out to every peer advertising a capability (all / first / best)

Configure known peers in config.yaml:

YAML6 lines
a2a_agents:
  researcher:
    url: "http://research-box.local:9900"
    auth: { type: bearer, token: "..." }
    timeout: 120
    capabilities: [web_search, research]

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

Explains the idea itself. Read it slowly; the later sections build on it.

With the platform enabled, Hermes 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

Settings you configure once. Change one at a time so you can see what each does. Set A2A_HOST in your environment, not in the chat.

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 ~/.hermes/a2a_audit.jsonl.
  • Anti-loop — per-context turn caps stop two agents ping-ponging forever.

Configuration reference

A lookup table. Do not read it all; find the row that applies to you.

Env varDefaultMeaning
A2A_PEER_TOKENS_(unset)_Per-peer credentials name:token,… (preferred)
A2A_BEARER_TOKEN_(unset)_Shared token; identity falls back to caller IP
A2A_HOST127.0.0.1Bind host — only widens when a token is set
A2A_PORT9900Inbound port
A2A_AGENT_NAMEhostname-derivedName on the Agent Card
A2A_PUBLIC_URL_(unset)_Routable URL advertised on the card (reverse proxies / k8s)
A2A_TRUSTED_PEERS_(unset)_Allow-list of authenticated identities
A2A_ALLOW_ALL_USERSfalseAllow any authenticated peer (dev only)
A2A_RATE_LIMIT60Requests/minute per identity
A2A_MAX_PINGPONG_TURNS5Anti-loop turn cap per context (max 20)
A2A_REPLY_TIMEOUT300Seconds to wait for the agent's reply
A2A_PUSH_SECRETbearer tokenHMAC secret for push-notification signing
A2A_ADVERTISED_TOOLSETSall registeredRestrict which skills appear on the Agent Card

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

Settings you configure once. Change one at a time so you can see what each does. Set ROLE_USER in your environment, not in the chat.

Shell9 lines
# From another machine / agent:
curl http://your-host:9900/.well-known/agent-card.json

curl -X POST http://your-host:9900/ \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <token>' \
  -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage",
       "params":{"message":{"messageId":"m1","role":"ROLE_USER",
                 "parts":[{"text":"What tools do you have?"}]}}}'

Troubleshooting

A troubleshooting section. Find the symptom that matches yours rather than reading it end to end.

  • 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, or have the caller register a push-notification config and poll GetTask.
Knowledge check

5 questions answered by this page alone.

Every option is a real identifier from the Hermes documentation. The wrong ones are real too, just from other pages.

1. According to this lesson, which command does “pick A2A”?
2. In this lesson's table, what is the “What it does” for “a2ahistory(contextid)”?
3. Which of these environment variables actually appears in this lesson?
4. Which of these headings does not appear in this lesson?
5. Which configuration key appears in this lesson's examples?