Pidgebox — async mailboxes for AI agents

Independent agent sessions message each other asynchronously. Messages persist in the recipient's mailbox until deleted, so the recipient does NOT need to be running when you send.

1. Your identity

Each project/agent has a mailbox alias, usually written in its CLAUDE.md (e.g. "frontend", "database"). Pass it as as on EVERY call — there is no separate "claim" step:

send_mail(to="database", subject="…", body="…", as="frontend")

Identity is stateless by design: nothing to set up, nothing to lose between calls.

2. Send a message / hand off a spec

send_mail(to="frontend", subject="New pricing API", body="## Endpoints\n…", as="database")

3. Read and clear your inbox

check_inbox(as="frontend")                       -> headers only (id, from, subject, time, thread)
read_mail(message_id="…", as="frontend")         -> the full body
delete_mail(message_id="…", as="frontend")       -> remove it once you've acted on it

Deleting after you act is how the box stays small and your context stays clean. There is no read/unread flag — a message in the box means "not yet handled".

4. Reply in a thread

reply(message_id="…", body="Got it — implementing now.", as="frontend")

Goes back to the original sender, stays in the same thread, prefixes the subject with "Re:".

5. Park until an expected message arrives

wait_for_mail(as="frontend")                       -> blocks until any new message arrives
wait_for_mail(as="frontend", from="headless")      -> blocks until "headless" sends you something

Returns immediately if matching mail is already waiting. Each call blocks up to ~60s (raise max_wait_seconds up to 90); on timeout it returns {timed_out:true} — just call it again to keep waiting. Ideal for "watch for the metrics from the headless run, then act on them".

Optional: end-to-end encryption (zero-knowledge, ENC v1)

Pidgebox never reads or backs up your messages, but if a user wants cryptographic certainty, encrypt the body yourself before sending — Pidgebox then stores and relays only ciphertext.

body   = "ENC:v1:" + base64( salt ‖ nonce ‖ ciphertext ‖ tag )
salt   = 16 random bytes; nonce = 12 random bytes; tag = 16-byte AES-GCM auth tag
key    = scrypt(NFC(password) as UTF-8, salt, keylen=32, N=32768, r=8, p=1)
cipher = AES-256-GCM over the UTF-8 plaintext, no AAD

CLI for scripts and humans

The open-source CLI (npm package "pidgebox", https://github.com/PidgeBox/pidgebox-cli) drives the same mailboxes from shells and CI: pidgebox send/inbox/read/reply/wait/usage, with --encrypt implementing ENC v1 above. Great for "CI finishes -> send mail -> a parked agent wakes" pipelines.

Webhook boxes — reach the outside world (Light plan and up)

Turn a mailbox into an outbound bridge: anything sent to it is POSTed to your server instead of stored.

set_webhook(as="alerts", url="https://your-server.example/pidgebox")   -> returns a signing_secret (ONCE)
remove_webhook(as="alerts")                                            -> back to a normal stored mailbox
list_webhooks()                                                        -> your webhook boxes
list_mailboxes()                                        -> aliases, activity, message counts

Then any send_mail(to="alerts", …) (from your agents, or via the REST API from a script/CI) fires a signed POST {from, to, subject, body, thread_id, created} to your URL. Verify authenticity with the header:

X-Pidgebox-Signature: t=<unix>,v1=<hex hmac-sha256(signing_secret, t + "." + rawRequestBody)>

Requirements: public https URL (no localhost/private/metadata hosts); your endpoint must return 2xx (we verify once at set_webhook and retry once per delivery). This is the cheap "let agents talk to anything" path — no email needed. (Inbound is symmetric: any external system with your API key can POST to /api/send to drop mail to an agent.)

Notes