Ayo keeps a small team, five or fewer, in sync without anyone leaving their terminal or their coding agent. You ping a teammate, it lands where they already are (a native notification, their inbox, or dropped into their agent's next turn), and their reply lands back in yours. Nobody alt-tabs, nobody loses their place.
Every ping carries your git context automatically (repo, branch, changed files), so "the auth endpoint is live" arrives carrying where and what changed. Git and your existing tools stay the source of truth. Ayo never calls an LLM, and it forgets your 1:1 pings on purpose. It is a sidechannel, not a second inbox to keep up with.
npm install -g @ayo-dev/cli
ayo init # login, pick a sound, wire your agents, then ping yourself to prove it worksayo init ends by pinging you, so you see the toast and hear your sound in under
a minute, no teammate required. Then ayo team create prints a join code, and
the rest is ayo <name> "...".
You are deep in the backend, Maya is deep in the UI, and she has been blocked on your auth endpoint for an hour. It just went live. So you alt-tab to Slack, find the channel, type the message, and lose your place. When she sees it twenty minutes later, she alt-tabs out of her own flow to ask which branch. Two people out of flow to move one sentence.
Your agent can write the endpoint. It cannot tell Maya she is unblocked. Only you know that, the moment it becomes true. Ayo carries that one sentence to her, context attached, without either of you leaving the terminal:
ayo maya "auth endpoint is live, you're unblocked" # lands where she is: a toast, or her agent's next turn
ayo team "schema changed, pull before you build" # tell everyone
ayo maya --urgent "prod deploy is red" # break through heads-downOr, from inside Codex or Claude Code, since you are probably already in there:
"Ayo Maya that the endpoint's live."
- Ping with context. A message carries your repo, branch, and changed files automatically, so "can you look?" arrives with the what.
- Respect focus. Heads-down holds non-urgent pings for the inbox; urgent breaks through.
- Answer your own agents. When your agent hits a fork it should not take alone (deploy to prod, pick an approach), it asks you and waits, instead of guessing and moving on.
- Bring the outside in. Point CI, cron, a script, or GitHub at a webhook and the events that need you show up in your terminal instead of an email you will not read.
- See the board. One pane: who is online, who is heads-down, which handoffs are still open.
- Hand off when you need to.
ayo handoffsends your branch, changed files, and blocker, plus a link that even someone not on Ayo yet can open and reply from. - Agent-native. An MCP server lets your agent ping, hand off, read your inbox, and ask on your behalf.
When you do need to put your work in someone else's hands, ayo handoff maya "the deploy is yours" mints a shareable page rendering your branch, changed
files, diff stat, and the blocker. That page is for the teammate who has not
installed Ayo yet: they can read the context and reply right from it with no
account. The page carries a join code naming you as the inviter, so replying
can become joining. Their answer lands in your terminal.
Handoffs only attach the full diff when you pass --with-diff, since a diff can
carry uncommitted secrets. --no-code shares context without granting join
access, and --no-link skips the link.
An agent should not deploy to prod, spend money, or pick between two approaches on its own. With the MCP server installed, it can ask you and wait:
# your agent, mid-task, calls request_approval and blocks on:
# "Retry queue: exponential backoff or fixed interval?"
ayo agents # the questions waiting on you, oldest first
ayo answer 1 backoff # it unblocks and keeps goingThe ask reaches you wherever you are (it pierces your own heads-down, because a blocked agent is your work), and your answer routes back as the tool's result. If you never answer, the agent gets a clean timeout and proceeds on its stated default, so nothing hangs forever.
Attention should not only come from people. ayo webhook create mints a
revocable webhook URL so any system can turn an event into an Ayo:
ayo webhook create --label ci --to wilson # one curl becomes an Ayo
curl -X POST https://…/v1/hooks/<token> -d '{"text":"build failed on main"}'
ayo webhook create --github # HMAC-verified GitHub webhookThe --github webhook maps the moments that actually need you (a review requested,
an @mention in a PR thread, a review submitted on your PR) to an Ayo for the
matching handle, where your Ayo handle is your GitHub login. Inbound automation
always respects focus and never breaks through heads-down.
ayo board is a glanceable HUD you leave up in a pane: who is online, who is
heads-down, which handoffs are open, and recent team activity, updating live.
⚡ Hack Midwest 3/4 online ● live
──────────────────────────────────────────────────────
● wilson 2m ayo@feat/auth "wiring oauth"
● maya now web@main "deploy is dead"
○ kenny 18m — offline
──────────────────────────────────────────────────────
⤷ open handoffs
maya → team deploy broken, need eyes unclaimed 6m
──────────────────────────────────────────────────────
recent
now maya ▸ we're cooked, all hands
2m wilson ⤷ shipped auth
It shows team activity only, broadcasts and handoffs. Your 1:1 pings and replies
stay private in ayo inbox.
ayo mcp install registers Ayo's tools with Codex, Claude Code, and Cursor, so
your agent can ping, hand off, read, and ask for you: send_ayo, read_inbox,
share_context, create_handoff, request_approval, team_status,
set_status, resolve_ayo. Just ask:
"Ayo Kenny that the deploy's cooked." "Hand this off to Maya with a summary of where I'm stuck." "Check my Ayo inbox and summarize anything urgent."
It shares your CLI identity, so you log in once.
Ayo is not another chat app. It is local infra, so your machine receives Ayos no matter where you are: Codex, Claude Code, the terminal, the browser, whatever.
Relay ─▶ local Ayo daemon (ayod) ─▶ OS notification + local inbox ← always on, real-time
─▶ agent hooks surface unread at turn/session boundaries
─▶ MCP / CLI read & reply on demand
- The daemon receives. A tiny background service holds one realtime
connection per team you're on and pops a native notification the instant an
Ayo arrives, whichever team it came from. No
watchpane to babysit. - The agents surface it.
ayo hooks installmakes Claude Code (SessionStart+UserPromptSubmit) quietly drop your unread Ayos into the model at natural breakpoints, so the ping feels native when your agent picks back up. Codex'snotifygets a toast fallback. - You reply on demand. "check my Ayos" inside the agent, or
ayo inbox.
It is honest about what it knows: sent is not delivered is not notified is
not read. A toast firing tells the sender your machine buzzed, not that you
looked.
Set it up step by step instead of ayo init
ayo login # GitHub device flow
ayo daemon install # install ayod (your receiver) as a login service
ayo mcp install # use Ayo from inside Codex & Claude
ayo hooks install # surface unread Ayos in-agentayo daemon install registers ayod as a launchd (macOS) or systemd
--user (Linux) service that starts on login and survives reboots. When
something looks off, ayo doctor checks the relay, the daemon, your agent
wiring, and fires a test toast.
Try it solo on one machine (no teammate)
The local relay has a dev stub that lets you be two people with no second laptop
and no GitHub account. AYO_DIR keeps each persona's files separate.
# Terminal 1: local relay (dev stub on)
cd packages/relay && npx wrangler dev --local --port 8787
# Terminals 2 & 3: run in each first:
export AYO_RELAY_URL=http://127.0.0.1:8787
alias ayo="node $(git rev-parse --show-toplevel)/packages/cli/dist/ayo.js"
# Terminal 2: you
export AYO_DIR=/tmp/ayo-you
ayo login --handle you && ayo team create "Self Test" # copy the join code
ayo daemon start # your receiver
# Terminal 3: your alter ego
export AYO_DIR=/tmp/ayo-pal
ayo login --handle pal && ayo join <CODE>
ayo you "does this actually work?" # Terminal 2 gets a native toastOr run scripts/demo.sh for a scripted walkthrough.
- Not a chat app. No threads, no reactions, no history to scroll. Handoffs show on the board and pings live in your inbox until you read them. If you want a conversation, you already have one open somewhere.
- Not a feed. It is a sidechannel for the moment something needs a human, not a stream you have to stay on top of. Quiet is the default.
- Not zero-infra. It needs the hosted relay (or your own, it is a Cloudflare Worker you can self-host) and a background daemon on macOS or Linux.
- Not fully branded on macOS yet. The clickable, logo'd notification needs a signed and notarized helper (in progress). Until then macOS shows a standard toast. Windows and Linux already carry the Ayo icon.
| Package | What it is |
|---|---|
@ayo-dev/cli |
The ayo command plus the ayod background daemon |
@ayo-dev/mcp |
MCP server exposing the Ayo tools to Codex/Claude |
@ayo-dev/core |
Shared message schema, wire protocol, and types |
relay |
Cloudflare Worker + Durable Object: realtime fanout, one DO per team |
- The Ayo protocol · the wire contract: message schema, HTTP API, WebSocket frames, delivery states
- Auth setup · MCP setup · Follow-ups
pnpm install
pnpm -r build
pnpm dev:relay # local Worker + Durable Object via wranglerContributions are welcome: a bug report, a fix, a notification path on a platform I got wrong, or a new agent host for the MCP server. Ayo is opinionated and has a few load-bearing properties (truthful output, the relay as the only identity boundary, no LLM calls, a sidechannel not a second inbox); see CONTRIBUTING.md for how to run it locally and what fits. Open an issue first for anything touching the relay or the wire protocol.
Found a security issue? Please report it privately through SECURITY.md.
MIT
