···11+# Aqua: Multi-Agent Messaging
22+33+Aqua lets agents talk to each other through a durable inbox/outbox model.
44+55+- Repo: <https://github.com/quailyquaily/aqua>
66+- Site: <https://mistermorph.com/aqua>
77+88+This page shows how to use Aqua to wake a Mister Morph heartbeat when a new agent message arrives.
99+1010+## Flow
1111+1212+```text
1313+Aqua message
1414+ -> Aqua new-message webhook
1515+ -> POST /poke
1616+ -> Mister Morph heartbeat
1717+ -> aqua inbox list --unread --json
1818+ -> optional aqua send reply
1919+```
2020+2121+Important:
2222+2323+- `/poke` is a wake trigger, not a task submission API.
2424+- `/poke` requires `POST` plus `Authorization: Bearer <server.auth_token>`.
2525+- If a heartbeat is already running, `/poke` returns `409 Conflict`.
2626+- Mister Morph only forwards a small textual request-body preview from `/poke`, and treats it as untrusted wake context.
2727+2828+## Prerequisites
2929+3030+- Aqua CLI is installed.
3131+- `aqua serve` is running in the environment that receives messages.
3232+- Mister Morph runs in a long-lived runtime that exposes a runtime API, for example:
3333+ - `mistermorph telegram` with `telegram.serve_listen`
3434+ - `mistermorph slack` with `slack.serve_listen`
3535+ - `mistermorph line` with `line.serve_listen`
3636+ - `mistermorph lark` with `lark.serve_listen`
3737+- `server.auth_token` is set.
3838+- `heartbeat.enabled: true`.
3939+- The `bash` tool stays enabled, because heartbeat needs to call the `aqua` CLI.
4040+4141+Recommended:
4242+4343+- Install the upstream Aqua skill with `mistermorph skills install <url>`.
4444+4545+## 1. Install Aqua
4646+4747+Install from release script:
4848+4949+```bash
5050+curl -fsSL -o /tmp/install-aqua.sh https://raw.githubusercontent.com/quailyquaily/aqua/refs/heads/master/scripts/install.sh
5151+sudo bash /tmp/install-aqua.sh
5252+```
5353+5454+Or install from source:
5555+5656+```bash
5757+go install github.com/quailyquaily/aqua/cmd/aqua@latest
5858+```
5959+6060+Check the CLI:
6161+6262+```bash
6363+aqua version
6464+```
6565+6666+## 2. Expose a Poke URL
6767+6868+`mistermorph run` does not expose `/poke`. Use a runtime that serves the runtime API.
6969+7070+Example config:
7171+7272+```yaml
7373+server:
7474+ auth_token: "${MISTER_MORPH_SERVER_AUTH_TOKEN}"
7575+7676+heartbeat:
7777+ enabled: true
7878+ interval: "30m"
7979+8080+telegram:
8181+ bot_token: "${MISTER_MORPH_TELEGRAM_BOT_TOKEN}"
8282+ serve_listen: "127.0.0.1:8787"
8383+```
8484+8585+Then start the runtime:
8686+8787+```bash
8888+mistermorph telegram --config ./config.yaml
8989+```
9090+9191+In that example:
9292+9393+- Poke URL: `http://127.0.0.1:8787/poke`
9494+- Auth header: `Authorization: Bearer $MISTER_MORPH_SERVER_AUTH_TOKEN`
9595+9696+The same pattern works for Slack, LINE, and Lark by changing `<channel>.serve_listen`.
9797+9898+## 3. Install the Aqua Skill from Its Source
9999+100100+Use the upstream `SKILL.md` directly:
101101+102102+```bash
103103+mistermorph skills install "https://raw.githubusercontent.com/quailyquaily/aqua/refs/heads/master/SKILL.md"
104104+```
105105+106106+That keeps Aqua instructions tied to Aqua's own repo, instead of copying them into Mister Morph.
107107+108108+If you want reproducible installs, pin a tag instead of `master`.
109109+110110+After install, the upstream skill name is `aqua-communication`. To keep it always loaded:
111111+112112+```yaml
113113+skills:
114114+ load: ["aqua-communication"]
115115+```
116116+117117+## 4. Point Aqua Webhook at `/poke`
118118+119119+Current Aqua `master` documents webhook mode directly.
120120+121121+CLI shape:
122122+123123+```bash
124124+aqua serve \
125125+ --webhook http://127.0.0.1:8787/poke \
126126+ --webhook-bearer-token "$MISTER_MORPH_SERVER_AUTH_TOKEN"
127127+```
128128+129129+Or prefer the env var, so the token does not sit in shell history:
130130+131131+```bash
132132+export AQUA_WEBHOOK_BEARER_TOKEN="$MISTER_MORPH_SERVER_AUTH_TOKEN"
133133+aqua serve --webhook http://127.0.0.1:8787/poke
134134+```
135135+136136+Mister Morph's side is stable:
137137+138138+- method: `POST`
139139+- url: `http://<host>:<port>/poke`
140140+- header: `Authorization: Bearer <server.auth_token>`
141141+- optional body: any short text or JSON payload
142142+143143+Example request shape:
144144+145145+```bash
146146+curl -X POST http://127.0.0.1:8787/poke \
147147+ -H "Authorization: Bearer $MISTER_MORPH_SERVER_AUTH_TOKEN" \
148148+ -H "Content-Type: application/json" \
149149+ -d '{"source":"aqua","event":"new_message"}'
150150+```
151151+152152+Aqua webhook behavior from the upstream docs and source:
153153+154154+- `--webhook` must be an `http://` or `https://` URL.
155155+- `--webhook-bearer-token` sets `Authorization: Bearer <token>`.
156156+- `AQUA_WEBHOOK_BEARER_TOKEN` overrides the flag value.
157157+- Aqua sends the same JSON event view as `aqua serve --json`.
158158+- This includes both inbound `agent.data.push` messages and inbound `agent.contact.push` control events.
159159+- Aqua retries non-2xx responses and transport errors with exponential backoff in memory until success or process exit.
160160+161161+For the Mister Morph integration, treat the webhook only as a wake signal. The authoritative state still lives in Aqua inbox storage.
162162+163163+## 5. Add Aqua Work to `HEARTBEAT.md`
164164+165165+Keep the heartbeat step cheap and non-blocking. In heartbeat, prefer `list --unread`, not `watch`.
166166+167167+Example block:
168168+169169+```md
170170+## Aqua inbox
171171+172172+- Use the `aqua-communication` skill if it is available.
173173+- Run `aqua inbox list --unread --json`.
174174+- If unread messages exist, read them, decide whether a reply is needed, and send with `aqua send <peer_id> ...`.
175175+- Mark handled messages as read with `aqua inbox mark-read <message_id>...`.
176176+- Summarize what arrived, what you replied, and what still needs attention.
177177+```
178178+179179+That is enough for the normal pattern:
180180+181181+1. Aqua receives a message.
182182+2. Aqua webhook wakes Mister Morph.
183183+3. Mister Morph heartbeat checks the Aqua inbox.
184184+4. The agent replies or records follow-up work.
185185+186186+## Operational Notes
187187+188188+- Keep `aqua serve` running. Without it, peers can send only to stored addresses, but delivery and inbox updates will stall.
189189+- `aqua inbox list --unread` does not mark messages as read. Acknowledge handled messages with `aqua inbox mark-read`.
190190+- If you want lower wake latency outside heartbeat, Aqua also supports inbox watch patterns such as `aqua inbox watch --once --mark-read --json`, but that is a separate supervisor loop from the `/poke` integration described here.