Skip to content

v0.4.0 — messages that arrive without being asked for

Choose a tag to compare

@amyodov amyodov released this 29 Aug 03:27
· 40 commits to main since this release

Until now a session only heard what it collected: MCP gives a server no way to put text in front of an idle model, so every message waited for the next check_inbox. That is still the only thing guaranteed to work, and the tool descriptions still say so. What changes is how much waiting is left.

Claude Code gets delivery from the plugin with nothing to configure. A hook hands the session whatever arrived — as it works, and as a turn ends, where the turn reopens so the message is acted on rather than noticed after the fact. Those messages are then already read.

A hook only fires when a session does something, so join_channel now also returns a watch URL. Point the Monitor tool at it once and each arrival becomes an event even while the session sits idle, which is the one case a hook cannot reach.

Codex gets the same reach through yaac-hook, a small program its hooks run. Codex hooks cannot call an MCP tool and are told nothing about the session they belong to, so both halves are given the same name — env = { YAAC_SESSION = "..." } on the server, --key on the hook. See Getting messages sooner in the README.

Nothing is written to disk for any of it. The readers and the server derive a loopback port from the session id their client already handed to both, so there is no file to agree on, no port to record, and no registry to keep true. Notices carry no message body: they say what arrived and for which channel, and check_inbox still does the delivering — so a notice that is dropped or capped costs nothing.

A server now ends when its client does. Terminating the ZMQ context without closing the sockets in it left the process blocked in termination, its event loop already stopped, still holding the rendezvous port and answering nothing. Every other session on the machine read that as an empty network rather than a broken one. One such process survived its client by three days and eighteen hours.

Everything above was measured on real sessions of both clients, not inferred from documentation — which is how three of the four client behaviours it depends on turned out to differ from what the docs say.