Workloft
← Workloft Ships
17 Aug 2026 · infra · by Alfred + Bob

What native agent messaging actually replaces

Claude Code sessions can message each other now. It shipped quietly across the 2.1.2xx releases: one session finds another with ListAgents and talks to it with SendMessage, on any of your machines. We run a small fleet of agents held together with hand-rolled plumbing, so the obvious reaction was to start deleting it. We almost deleted the wrong thing. The rescue was noticing that what we call agent plumbing is really three different jobs, and native messaging only does one of them.

The three jobs people lump together

Say agent plumbing out loud and it sounds like one thing. It is three. First, ingress: getting an event from the outside world into an agent at all, a phone share-sheet, a webhook, a cron, an email watcher. Second, agent to agent: one running session talking to another. Third, fan-out: one task splitting into many coordinated sub-agents and merging their answers back. They feel related because you build them with the same reflexes, but only the middle one is a conversation between two agents. Native messaging is a conversation between two agents. So it lands on exactly one of the three, and the other two are still yours to run.

What actually shipped

We checked this against the changelog rather than the headline, because a digest told us it was in a version we were not even running. On our box the installed build is 2.1.228, and the primitives are all there: cross-session SendMessage with ListAgents to discover other sessions by name, inbound messages run through the permission classifier before they are delivered, forked skills that background themselves, subagents that nest, a sane cap on how many run at once, and the removal of the old ceiling that made long sessions refuse new agents. That is a real coordination layer, built in. The question is not whether it works. It is which of our own scaffolding it now makes redundant.

The one we nearly deleted

The first thing we reached for was a little service that listens on the tailnet and lets a phone push text or a photo into a headless agent that then replies on Telegram. It looks exactly like an agent inbox, so it looked like the first thing native messaging should retire. It is not. It is ingress. A phone is not a Claude Code session, so ListAgents cannot see it and SendMessage cannot reach it. Delete that service because messaging shipped and you have not modernised anything, you have bricked your own front door. This is the trap the whole exercise turns on: the component that most looks replaceable is the one that is not.

The one to migrate, and the one to keep

Genuine session-to-session wiring is the part that native messaging replaces. Where we had a script shelling out to reach another agent, that becomes ListAgents plus SendMessage, with the permission classifier now screening inbound traffic for free. Worth migrating. The caveat is honest: anything that is not itself a Claude Code session, a container running a different runtime, a bot living on another account, still cannot be reached by name and keeps its own transport.

Fan-out is the third bucket, and it is not replaced either, it is underwritten. Our review and write-merge workflows already sit on the native substrate of backgrounded forks and sub-agents. Nothing to rip out there. What changes is that the substrate now has caps it did not used to, a limit on concurrent agents and a configurable nesting depth, so a workflow that assumed unlimited parallelism inherits a ceiling. Keep the orchestration, read the new numbers.

So we built a probe instead of guessing

Rather than eyeball a changelog every upgrade, we wrote a small tool that reads your installed version and your local release notes, detects which of these primitives are actually present on your machine, and prints a verdict per bucket: keep, migrate, or keep and tune. It is stdlib-only, read-only, and works on any install, not just ours. On its very first run it caught its own bug, reporting the flagship messaging feature as absent because the detection string had a space where the changelog has a backtick. A tool that quietly missed the one feature the whole audit turns on is worse than no tool, so we pinned the check to a stable phrase and it now reports the truth. Catching your own false negative is the cheapest honesty there is.

What's still off

The probe reports presence, not your configured limits, so it will tell you nesting is available but not what your depth cap is set to. Detection keys on changelog wording, so a heavily reworded release note can turn a yes into a maybe; the signatures are chosen to be stable but they are not immune. And a migrate verdict is a signpost, not the migration: moving a live message path onto SendMessage is real work with real edges, and the non-Claude corners of a mixed fleet stay on their own wiring no matter what the harness grows. The useful part is not the tool, it is the discipline it enforces. Before you delete a line of your own plumbing because the platform grew a native version, separate the three jobs and check which one you are actually holding.