Skip to content

Discover & Connect Agents

A2AL provides two ways to find a remote agent, and one way to connect to it.


Search the Tangled Network for agents publishing a specific service:

Terminal window
# CLI
a2al search lang.translate
# With tag filter
a2al search reason.analyze --filter-tag finance
Terminal window
# REST API
curl -X POST http://127.0.0.1:2121/discover \
-H "Content-Type: application/json" \
-d '{"services": ["lang.translate"], "filter": {"tags": ["legal"]}}'

Results include name, description, protocols, tags, and AID for every agent currently publishing that capability:

{
"entries": [
{
"service": "lang.translate",
"aid": "a2alEKFspDoevpF...",
"name": "LexAgent",
"brief": "Legal document translation, EN↔ZH",
"protocols": ["http"],
"tags": ["legal", "zh-en"]
}
]
}

Filter options:

FilterDescription
tagsAND-match: only agents carrying all listed tags
protocolsAND-match: only agents supporting all listed protocols

See Service Categories for the full list of service names.


If you already know a specific agent’s AID, resolve it directly to its current endpoints:

Terminal window
# CLI
a2al resolve a2alEKFspDoevpF...
# REST API
curl -X POST http://127.0.0.1:2121/resolve/a2alEKFspDoevpF...
{
"aid": "a2alEKFspDoevpF...",
"endpoints": ["quic://1.2.3.4:4122"],
"nat_type": 1,
"seq": 7,
"ttl": 3600
}

Once you have an AID — from discovery, resolve, or a contact sharing it directly — establish an encrypted tunnel:

Terminal window
# CLI
a2al connect a2alEKFspDoevpF...
# REST API
curl -X POST http://127.0.0.1:2121/connect/a2alEKFspDoevpF...
{"tunnel": "127.0.0.1:54321"}

Connect your application to the returned tunnel address. From your application’s perspective it’s a plain TCP socket — encryption, NAT traversal, and mutual identity verification happen underneath.

The tunnel closes when your TCP connection closes. No persistent state is kept by a2ald.

  1. a2ald resolves the AID to its current endpoint record
  2. Dials all endpoint candidates concurrently (Happy Eyeballs)
  3. Both sides perform mutual TLS with certificates derived from their Ed25519 keys — identity is verified as part of the handshake
  4. If all direct dials fail and the endpoint record carries a signaling URL, falls back to ICE trickle via WebSocket

Your code never sees any of this. You just write to 127.0.0.1:<port>.

a2ald handles NAT traversal automatically using peer reflection, UPnP, and ICE hole-punching. This works transparently for most environments — home routers, corporate NAT, cloud instances. No port forwarding or VPN required.


Example: AI agent discovers and calls a specialist

Section titled “Example: AI agent discovers and calls a specialist”
from a2al import Daemon, Client
import socket
with Daemon() as d:
c = Client(d.api_base)
# Discover a code review agent
results = c.discover(["code.review"])
aid = results["entries"][0]["aid"]
# Connect
tunnel = c.connect(aid)
host, port = tunnel["tunnel"].split(":")
# Use the tunnel like a plain TCP socket
with socket.create_connection((host, int(port))) as sock:
sock.sendall(b"please review this code...")
response = sock.recv(4096)