Recipes
Each of these starts from a concrete situation and ends with a result you can verify. The complete set of options and commands is in the REST API and the individual topic pages.
1. Make a local service callable from anywhere
Section titled “1. Make a local service callable from anywhere”Situation: a model server, a workflow or an internal API runs on your machine, and another agent, another machine or a colleague should be able to call it — without opening a port or configuring a domain.
a2al register # 1. create an identity (skip if you have one)a2al inbound bind --addr 127.0.0.1:8080 --aid <your-AID> # 2. bind the port the service actually listens ona2al publish lang.translate --aid <your-AID> # 3. optional: publish a capability name for others to findGive --addr the address the service actually listens on, and never 2121 (that is the daemon’s administrative port).
How the other side calls it
a2al get <your-AID> /your/api/path # AID knowna2al search lang.translate # AID unknown: search by capability name, then callSigns of success: the other side runs a2al get <your-AID> /.well-known/agent.json and gets your service’s JSON back; the caller’s IP, network and NAT setup make no difference.
Keeping it available: the binding is stored with the identity in the data directory and is restored after a restart; publish records expire about 1 hour after the daemon stops. For something that must stay findable, keep the daemon resident (Windows / macOS: a2ald service install; Linux: Deploy with systemd). Restricting who may call is covered in Security Practices.
2. Reach an agent behind someone else’s NAT
Section titled “2. Reach an agent behind someone else’s NAT”Situation: an agent runs on a colleague’s laptop, a remote workstation or a machine at home. You have only its AID, and you would rather not install a VPN, depend on a public IP, or rely on a tunnel address that goes stale.
Prerequisites: both machines run a2ald, and the other side has registered an AID and published it (or has bound a service as in recipe 1).
# a single HTTP calla2al get <peer-AID> /.well-known/agent.json
# a TCP connection that needs to stay up (SSH, databases, gRPC)a2al tunnel open <peer-AID> --local-port 2222# Tunnel: 127.0.0.1:2222ssh -p 2222 user@127.0.0.1Signs of success: the call completes. The other machine may have no routable public address at all; a2ald handles NAT traversal transparently.
When the other side is offline: hand the task over with a note and let it collect when it returns.
a2al note send <your-AID> <peer-AID> "$(printf '%s' 'Run task X' | base64 -w0)"3. Wire a local service into an AI assistant
Section titled “3. Wire a local service into an AI assistant”Situation: you are using Claude, Cursor or another MCP host and want it to call a model, a private tool or a company-internal API on your machine, with the service never exposed to the internet.
npx -y a2ald mcp add # 1. add MCP (the host must reload before the tools appear)Do step 2 in the host or on the command line:
a2al register # create an AIDa2al inbound bind --addr 127.0.0.1:11434 # Ollama, as an exampleYou can also simply tell the assistant: “register a new identity and bind the Ollama instance on my machine at 127.0.0.1:11434” — it will call a2al_agent_register and a2al_agent_patch.
Step 3 (across machines): hand the AID to the other side; they resolve it with a2al resolve <AID> and then a2al_fetch the path they need. The call is end-to-end encrypted and passes through no server.
4. Build a private (self-hosted) network for a group of machines
Section titled “4. Build a private (self-hosted) network for a group of machines”Situation: a few machines at home, several servers on a team, or an isolated test environment. They should find and reach one another, without traffic going to a public directory.
The first machine (seed node):
a2ald --listen :4121 --data-dir /var/lib/a2al/node-aNote its address, say 192.168.1.10.
Every other machine:
a2ald --bootstrap 192.168.1.10:4121 --data-dir /var/lib/a2al/node-bA non-empty --bootstrap skips public DNS and the beacons entirely; use a fresh --data-dir so an old peers.cache does not keep dialling public nodes.
Two nodes on one machine (for testing):
a2ald --data-dir ./node-a --listen :4121 --fallback-host 127.0.0.1
a2ald --data-dir ./node-b --listen :4122 --api-addr 127.0.0.1:2122 \ --fallback-host 127.0.0.1 --bootstrap 127.0.0.1:4121
a2al --api http://127.0.0.1:2122 resolve <an-AID-on-node-a>Identities, notes, rooms and sessions behave identically on a self-hosted network — same protocol, your directory. Details are in Private (Self-Hosted) Network.
5. Hand a task to a machine that is offline
Section titled “5. Hand a task to a machine that is offline”Situation: you want to hand work to another agent or machine, and it is not online right now — it has not been started, or it reboots overnight.
PAYLOAD=$(printf '%s' '{"job":"process_data","file":"s3://…"}' | base64 -w0)a2al note send <your-AID> <peer-AID> "$PAYLOAD"The other side collects it on return:
a2al note poll <peer-AID>Over MCP: a2al_mailbox_send / a2al_mailbox_list / a2al_mailbox_poll. A pending.mailbox: N in a tool result is the signal to look (list) then take (poll) — with no signal, there is nothing to poll for every round.
A note is not a chat: it is encrypted asynchronous delivery, not a live channel and not a delivery receipt. When you need back-and-forth, wait until both sides are online and use a chat; to transfer files, use a room.
Related pages
Section titled “Related pages”| Goal | Page |
|---|---|
| How to choose between the five channels | Choose the Right Channel |
| Running the daemon resident, and ports | Deploy with systemd |
| Every command and option | REST API |
| Common problems and what errors mean | Troubleshooting |