Release notes

What’s new in Cempala.

Every Cempala release, newest first: what shipped, what got fixed, and what it turned out not to be able to promise. No marketing gloss, just the changes.

Current · v0.5.2 · macOS · Linux · Windows · every installer-selected binary run-verified

v0.5.2Aug 31, 2026Release on GitHub
Feature

The mailbox delivers

Handing a task to another agent used to record it and nothing more: nothing started that agent, and nothing told it. create_task now tries to start the assignee in the background and returns immediately.

  • The database that prompted this release had 77 messages sent and 77 unread, claim_task never once called, and the single mailbox task ever created still pending hours later. The reaper only sweeps running tasks, so it could not see that the assignment was there — it simply sat unread while whoever made it waited for work that was never going to begin.
  • create_task now tries to start the assignee in the background and hands your turn straight back. Where the launch succeeds the other agent gets going, and you collect the outcome with check_task whenever you are ready; where it does not, the result says whether the task was queued for a claim or failed outright.
  • Delivery runs under dispatch’s policy, by the same code — the same denylists in the same order, the trust boundary, the argv baseline, the wait ceiling and the network label. Work cannot reach an agent on easier terms by being assigned instead of dispatched.
  • The result says which actually happened. delivery: "dispatched" means the launch was attempted and the task is not waiting for a claim; read status to see whether it is running, completed or failed, and it carries the network enforcement that was applied — which matters most for Antigravity, where “no network” cannot be enforced at all and the result now says so. delivery: "queued" means Cempala started nothing, and names why: unassigned, not_requested, agent_not_dispatchable, cli_unavailable, self_assigned, nested_delivery, start_failed, or claimed_elsewhere.
  • Delivery goes one hop. An agent working a delivered task can still create tasks, but those are recorded rather than started. One handoff is a handoff; a chain that delivers every time it is delivered to spends real provider quota without bound.
  • The row is the unit of work. Because delivery runs on the task’s own row, that row is settled from the agent’s output whether or not the agent ever calls complete_task — and if it does call it, its own verdict stands. Every reconciliation path only writes a row still marked running, so the first writer to reach a terminal state owns it. The same guard means a claim_task that lands first wins, and nothing is spawned over it.
  • Work assigned to someone Cempala cannot start is still surfaced. Any MCP client can join the mailbox, but only the four mapped CLIs can be spawned, and nothing in MCP lets a server interrupt an agent that is not currently asking it something. So the reply to a call the agent did make now carries an inbox: its unread message count, the true number of tasks waiting for it, and up to ten of them described well enough to act on — id, description, folder, and who asked. It rides on every tool, not just the mailbox ones, on any call the agent identified itself on; it is absent when there is nothing waiting, so its presence is the signal.
  • Policy is now decided before the task row is written, and the row is inserted already carrying its verdict. A pending row is claimable the instant it exists, so recording first and judging afterwards published work whose denial had not been decided yet. Judging first removes that window rather than guarding it. An allowed verdict hands back a capability bound to the exact task, prompt, canonical folder and resolved command line it judged, so approved work cannot be swapped for something else after the fact.
  • Delivery was verified end to end against all four supported CLIs on a real machine: each picks up an assigned task and completes it with nobody claiming it by hand, each reporting the network enforcement its own argv actually imposes. Alongside that, 386 unit tests, the installer and uninstaller suites, six-target builds, and smoke tests on matching hardware. CI also moved off the retired Node 20 runtime.
v0.5.1Aug 31, 2026Release on GitHub
Fix

Progress heartbeats for long dispatches

A dispatch that ran longer than the caller’s own MCP timeout looked non-responsive, even though it had finished. The work was never lost — you just had to know to go looking for it.

  • MCP clients time out tool calls on a clock of their own: 60 seconds by default in the MCP SDK, which OpenCode inherits unless a per-server timeout is configured. A dispatch may legitimately wait up to 600. Nothing reconciled the two, so Cempala would run the target agent to completion, parse its result and write the task row while the caller had given up minutes earlier and reported the agent as unreachable. Both sides behaved exactly as documented, and the handoff still died.
  • A tools/call carrying a progressToken now receives a notifications/progress heartbeat every 10 seconds until the tool settles. This is the protocol’s own answer rather than a workaround: clients that reset their request timeout on progress — OpenCode does, for every MCP tool call — keep the request alive for as long as the work honestly continues.
  • Callers that send no token are unaffected, and get no notifications. Nothing is invented on their behalf; for those, ask for a short wait_seconds and poll check_task.
  • The heartbeat stops when the tool settles, and goes quiet if the client cancels. Its timer never holds the server process open, and a fast tool stops it before it can fire — so in practice only a waiting dispatch produces any traffic at all.
  • For a current client no configuration is needed, and no timeout field has to be added to an OpenCode MCP entry. One too old to send a progress token never starts the heartbeat, and still needs a longer configured timeout — or short waits and check_task polling. The fix carries an end-to-end test that drives the real stdio JSON-RPC surface: heartbeats must arrive before the response and strictly increase, and an equally slow dispatch sent without a token must stay silent for its whole run.
v0.5.0Aug 14, 2026Release on GitHub
Feature

OpenCode auto-registration

OpenCode was the one supported agent that installing left alone. Cempala could already dispatch work to it, but making it call back required a manual config edit. Installing now covers all four: Claude, Codex and OpenCode whenever their CLI is on PATH, and the Antigravity config merge every time.

  • Registration runs the CLI’s own opencode mcp add cempala -- <bin>, exactly as Claude Code and Codex are registered. It is idempotent, so re-running the installer to upgrade re-points the entry instead of duplicating it, and it preserves the comments in the JSONC config it edits.
  • Uninstalling removes the entry again. OpenCode ships no mcp remove, so cempala --unregister-opencode edits the config directly: it cuts out the single mcp.cempala member and copies every other byte through — comments, indentation and line endings intact. Removal takes out that one member and preserves every other byte, though it can leave an empty mcp object behind; and a cempala entry you had written yourself beforehand is removed rather than restored.
  • All three files OpenCode reads are cleaned: opencode.json, opencode.jsonc, and the legacy config.json it still loads but no longer writes.
  • A config that cannot be scanned end to end is left untouched and reported, and an ambiguous one — duplicate mcp or cempala keys — is refused rather than half-cleaned.
  • Two defects in the shared registration code were fixed with it, both reachable from the existing Antigravity paths. A lock-contended unregistration told you to re-run cempala --register-antigravity — the wrong tool, and the opposite direction — in the one actionable line printed after a run that had already exited non-zero. And the “did our failed write damage this config?” check used a strict JSON.parse, which is false for any file containing a comment: its guarantee that a concurrent writer’s valid config survives was therefore inert for JSONC, and could have restored a pre-edit snapshot over someone else’s write.
  • Verified with type checking, 368 unit tests, the installer and uninstaller suites, six-target builds, and smoke tests on Linux (x64/ARM64), macOS (Intel/Apple Silicon) and Windows x64. The published binaries are byte-identical to the artifacts those smoke tests ran against.
v0.4.0Aug 14, 2026Release on GitHub
Feature

OpenCode MCP support

Cempala now supports OpenCode in both directions: OpenCode can use Cempala’s MCP server, and Cempala can dispatch work to OpenCode.

  • OpenCode can use Cempala’s MCP server and all eight Cempala tools.
  • Cempala can dispatch work through opencode run, with optional model selection.
  • OpenCode JSONL output is parsed into task status, results, and retained logs.
  • When network access is disabled, OpenCode dispatches use an explicit tools-only policy. That policy does not claim to sandbox direct network access from Bash.
  • OpenCode is now part of the default agent configuration and database seed data, with end-to-end protocol coverage.
  • The release passed type checking, unit tests, install and uninstall tests, six-target builds, and smoke tests on Linux, macOS, and Windows.
v0.3.0Aug 11, 2026Release on GitHub
Feature

It can be uninstalled now

Cempala can be removed properly, which it could not be before. Nothing else changed. The release exists because the old advice — delete the folder — was wrong in a way you would have felt for months.

  • Deleting ~/.cempala/ was never enough, and the documentation used to say it was. Installing writes to four places and three of them belong to other programs: the PATH, and a registration inside Claude Code, Codex and Antigravity each. Remove only the folder and those three survive, each pointing at a binary that no longer exists — so every launch of every agent CLI reports cempala as a failed server, indefinitely, until you remove them yourself.
  • One line now reaches all of them, on macOS, Linux and Windows: the binary, the PATH entry, and the three registrations. Those go out through each CLI's own mcp remove command, so their config files stay theirs to own; only Antigravity is edited directly, because it ships no such command — one key removed, every other server and setting left alone, and the file never deleted. That routing is also the limit: a CLI you have since taken off your PATH has no command left to ask, so its entry stays until you delete it.
  • Your history is kept by default — the ~/.cempala/ folder survives the uninstall. It holds the task history and the audit log, and uninstalling the software is not an instruction to discard the record of what it did. --purge removes that too, and says so first.
  • On macOS and Linux the PATH block is removed only where the installer's own marker comment is still present. A block you have edited, a commented-out copy, or a file that merely mentions the same path is left untouched — as are your line endings and a missing final newline. Install then uninstall returns a startup file to its original bytes. Windows has no startup file in the picture: the user PATH entry is matched exactly and dropped, and the rest of PATH is written back in its original order.
  • A step that cannot be completed is reported as a partial uninstall rather than dressed up as a success: no success banner, a partially-uninstalled one instead, a non-zero exit, and the binary deliberately kept so you can fix the cause and re-run. --purge is refused outright in that case, so a system left half-undone is never also stripped of its database. --dry-run prints exactly what would happen and changes nothing.
  • Two flags support this and can be run on their own if you would rather do it piecemeal: cempala --unregister-antigravity and cempala --remove-path-block. The uninstaller delegates its two most delicate steps to them, so CI compiles a real binary to test against rather than a stub that would prove nothing.
  • For this release, a local rebuild covered all six build targets, and the five published binaries reproduced exactly — identical SHA-256 digests.
v0.2.0Aug 11, 2026Release on GitHub
Feature

A third agent, and a fourth thing to admit

Cempala now hands work to Antigravity as well as Claude Code and Codex CLI — in either direction, through the same eight tools. Adding it also surfaced a guarantee Cempala cannot make, so it stopped pretending otherwise.

  • Antigravity joins as a dispatch target. Ask for it by name and Cempala runs Google's agy CLI headless and returns the result inline, exactly as it does for the other two. Antigravity can also call Cempala's eight tools itself, so work moves in either direction. Nothing about the tool surface changed to accommodate it — it arrived through standard MCP, which is what the protocol was for.
  • Registration happens during install. Antigravity has no mcp add command, so Cempala merges an entry into the MCP config file its app and CLI both read. Every other server and top-level key in that file is preserved, and a file that cannot be parsed is left untouched with the exact snippet printed for you to paste. The step is re-runnable on its own with cempala --register-antigravity.
  • A no-network request cannot be enforced for Antigravity, and the result now says so. agy exposes no argv-level network switch — its reach is governed by permissions in your own agy settings, which Cempala neither reads nor writes. Rather than borrow a word it cannot back up, the enforcement field gained a fourth value, not_enforceable. Codex still reports sandboxed and Claude tools_only. The handoff still runs; it simply does not claim a protection that was never applied.
  • Shell commands are auto-denied in Antigravity's headless mode unless you add an allow-rule in its own settings. File edits work out of the box. Cempala will not pass --dangerously-skip-permissions to work around it — that flag is rejected at config load time, and this is exactly the case it exists to refuse.
  • A run that announces it did nothing is no longer reported as a success. Every path that settled a task read stderr only once the run had already failed, so an agent that exited cleanly while explaining on stderr that its tool had been auto-denied came back completed with an empty result, its one line of explanation thrown away. That explanation is now read, and the task recorded as failed with the reason attached. The match stays deliberately narrow: an empty answer on its own still counts as completed, because a prompt whose whole effect is a file edit can legitimately return no prose, and failing that would be its own misreport.
  • Dispatched work lands in the folder you asked for. agy resolves relative paths against its own workspace rather than the process working directory, so a handoff could quietly write into its scratch folder instead of your project. The baseline now anchors it to the working directory Cempala had already validated.
  • The binary moved to ~/.cempala/bin on every platform, Windows included — deliberately out of AppData, which some agent clients cannot see from the processes they spawn. Re-running the installer now replaces it in place even while an agent is holding it open, and leaves exactly one PATH block in the startup file your shell actually reads.
v0.1.0Jul 30, 2026Release on GitHub
Release

First release

A local MCP server that lets Claude Code and Codex CLI hand work to each other on one machine, in plain language, instead of you carrying output between two windows.

  • Eight MCP tools: send_message, check_messages, create_task, claim_task, complete_task, dispatch, check_task and approve_path. dispatch returns a result inline in the same turn, or running with a task id when the work outlasts the wait; the mailbox leaves work for the other agent to claim when it is ready. Both write to one shared SQLite notebook, so the two paths share a single audit log.
  • Every result that got as far as running reports which network enforcement actually applied, rather than flattening the difference into a reassuring default — sandboxed for Codex, where the OS blocks egress, and tools_only for Claude, whose Bash can still reach the network after its web tools are removed.
  • Work is confined to your home directory unless you explicitly approve a path, and a baseline denylist covering SSH keys, cloud credentials, browser credential stores and more cannot be weakened by editing config. Every call is written to an audit log.
  • Published for Windows x64 on the day, and only that. The macOS and Linux binaries cross-compiled cleanly and their installer was written and ready, but no target shipped until the binary had actually been run on the hardware it targets — a full MCP handshake, all eight tools advertised, a message round-tripped through SQLite. A cross-compile that succeeds proves nothing about the artifact. The other four were verified on real machines shortly afterwards and added to this release, which now carries all five.
  • Windows on ARM is the one gap: the installer fetches the x64 build, which runs under emulation. A native windows-arm64 binary compiles but is not published, because there was no ARM64 Windows machine to run it on.

Upgrading. Re-run the installer. It is idempotent, and it replaces the binary in place even while an agent is holding it open — then restart any session that was already running so it picks up the registration.

Get the current Cempala.

One line to install, on any of the three platforms. Or read the docs to see how the handoff works before you commit to anything.