Your tools can talk to your pet

App announcements, new in 1.1 — a truthful per-app setup guide. Updated July 2026.

Anything on your Mac that can open a URL can hand the pet a message to pass along. When something finishes — a coding-agent run, a build, an important email — the pet perks up and announces it at your desk. If you stepped away, it sends a macOS notification instead, so you can leave the desk without watching a progress bar.

open "mochi://announce?source=myapp&text=All%20done"

That's the whole protocol. source is the app's name (lowercase letters, digits, dashes); text is one percent-encoded line. Each source appears in the menu bar under App announcements the first time it speaks, with its own mute toggle. Announcements are rate-limited (30 seconds per source, 12 per hour in total) so a runaway script can never turn the pet into a firehose. The mochi:// scheme is local — announcements never touch the network, and the app makes no request of its own.

Why the arrow points this way: macOS never lets one app read another app's notifications — there is no API for it, for good privacy reasons, and no Mac App Store app can offer it. So instead of Mochi (impossibly) spying on notification banners, your tools send to Mochi. The pet only ever hears what you deliberately wired up.

Claude Code — the full "waiting together" setup

This is the one we recommend: the pet takes up its watch beside a tiny terminal while Claude works, invites you to stretch on long waits, celebrates every finish (with a notification if you stepped away), and announces when Claude needs you. Add to ~/.claude/settings.json:

{ "hooks": { "UserPromptSubmit": [ { "hooks": [ { "type": "command", "async": true, "command": "open \"mochi://run/start?id=$(jq -r .session_id)\"" } ] } ], "Stop": [ { "hooks": [ { "type": "command", "async": true, "command": "IN=$(cat); open \"mochi://run/end?id=$(printf %s \"$IN\" | jq -r .session_id)&msg=$(printf %s \"$IN\" | jq -r '(.last_assistant_message // \"\") | .[0:160] | @uri')\"" } ] } ], "Notification": [ { "hooks": [ { "type": "command", "async": true, "command": "IN=$(cat); open \"mochi://announce?source=claude&text=$(printf %s \"$IN\" | jq -r '(.message // \"Needs your attention\") | .[0:120] | @uri')\"" } ] } ] } }

The msg= on run/end makes the away notification personal — it carries Claude's actual closing words ("Deployed the site, fixed 3 bugs") instead of a generic "done" (requires Mochi 1.1.1+; older versions simply ignore it). Overlapping sessions are tracked per session id — the pet celebrates quietly per run and fully when the last one lands.

Codex CLI (OpenAI)

The ChatGPT desktop app has no hooks (see below), but OpenAI's Codex CLI does: the notify setting runs a program when an agent turn completes. In ~/.codex/config.toml (user-level config only — project configs can't set notify):

notify = ["bash", "-lc", "open \"mochi://announce?source=codex&text=Turn%20complete\""]

Codex appends one JSON argument of type agent-turn-complete to the command, including the last-assistant-message — a small wrapper script can jq it into the announcement text if you want the actual message.

Gemini CLI (Google)

Gemini CLI has Claude-style hooks; AfterAgent fires after the final response. In ~/.gemini/settings.json:

{ "hooks": { "AfterAgent": [ { "hooks": [ { "type": "command", "name": "mochi-announce", "command": "open \"mochi://announce?source=gemini&text=Done\"" } ] } ] } }

Shortcuts — automations for everyone

Mochi requires macOS 26, and macOS 26 is where Shortcuts on the Mac finally gained real automation triggers. That means every Mochi user can wire events with no code at all:

The incoming-email trigger watches accounts set up in Apple Mail — which is also the honest workaround for apps that can't be wired directly (Outlook, Gmail: add the same account to Mail).

Apple Mail rules

Mail rules still support Run AppleScript as an action. Save this as mochi-announce.scpt in ~/Library/Application Scripts/com.apple.mail/ (the rule editor's script pop-up has "Open in Finder" to reveal that exact folder — scripts anywhere else won't run):

on perform mail action with messages theMessages do shell script "open 'mochi://announce?source=mail&text=Important%20mail%20arrived'" end perform mail action with messages

Then Mail → Settings → Rules → your conditions → "Run AppleScript". Test it with Message → Apply Rules first; after macOS updates, re-select the script in the rule if it stops firing (a known Mail quirk). If a rule feels fiddly, the Shortcuts email trigger above does the same job with no script.

Any script, build, or button

CI jobs, git hooks, Makefiles, cron, Stream Deck buttons, Raycast — if it can run a shell command, it can reach the pet:

# at the end of a long build make release && open "mochi://announce?source=ci&text=Release%20build%20green" # percent-encode arbitrary text safely msg=$(printf '%s' "Deploy finished: $VERSION" | jq -sRr @uri) open "mochi://announce?source=deploy&text=$msg"

What can't be wired (and why we won't pretend)

Some apps expose no automation surface at all — no hooks, no AppleScript, no URL callbacks. Nothing on macOS (Mochi included) can react to their events, because the system never shares one app's notifications with another:

Good to know

Wired up something fun — or found an app with a hook we missed? Tell us: ngoanlearning@gmail.com 🌱