Docs / Getting started / Overview

Cempala documentation

Everything you need to let your AI coding assistants hand work to each other, on your own machine, in plain language. Start here, then jump to whatever you're after.

v0.5.2macOS · Linux · WindowsStandard MCPRelease notes →

Cempala does one thing well: it lets the AI assistants on the same computer — Claude Code, Codex CLI, Antigravity and OpenCode — pass tasks to each other, and hand the results straight back. You ask one of them, in ordinary words, to have another do something. No second window, no copy-paste, and no account. Cempala itself sends nothing anywhere — the coordination is entirely local — though each assistant still talks to its own provider exactly as it does when you use it directly.

What's in this guide

  • Getting started takes you from one install command to your first handoff.
  • Core concepts explains the two ways work moves around, the shared notebook that records it, and where Cempala is allowed to work.
  • Using Cempala covers asking in plain language, reviewing what happened, and network access.
  • Reference lists the tools your assistants can call, the platforms, and fixes for common snags.

New to all this?

You don't need to know what "MCP" means to use Cempala. Install it, then just ask your assistant to "have Codex do X." If you're curious how it works underneath, read The two ways to hand off.

Install & first run

From nothing to your first working handoff.

1. Run one command

Open a terminal and paste the line for your system. It downloads Cempala, puts it somewhere your account can reach, and needs no administrator rights.

# macOS / Linux curl -fsSL https://raw.githubusercontent.com/thelabs-id/cempala/main/scripts/install.sh | bash # Windows (PowerShell) irm https://raw.githubusercontent.com/thelabs-id/cempala/main/scripts/install.ps1 | iex

The command is fully non-interactive. It won't stop to ask you anything, so it's safe to run as-is. Every binary an installer will choose — macOS (Intel and Apple Silicon), Linux (x64 and arm64), Windows x64 — was actually run on the hardware it targets before being published, not just cross-compiled.

Windows on ARM

The one gap. The installer runs the tested x64 build under emulation there rather than a native one. A windows-arm64 binary is attached to releases, but as a manual, experimental asset: no installer selects it, because there was no ARM64 Windows machine to smoke-test it on.

A new shell on macOS and Linux

On macOS and Linux, open a new shell before running cempala or any registration command: a script piped into bash cannot update the PATH of the terminal that launched it. Windows updates the current PowerShell session as well as future ones.

2. Register the agents you use

During install, Cempala looks for Claude Code, Codex CLI and OpenCode on your machine. For each one it finds, it wires itself up automatically, using that tool's own mcp add command. For any it doesn't find, it prints the exact command to run later — it never fails quietly. Antigravity is handled differently: its entry is attempted every time, whether or not the agy command is present, because the same file is read by the Antigravity app and plenty of people have that without the CLI.

# run these yourself if an assistant was added later, or registering it failed claude mcp add cempala --scope user -- cempala codex mcp add cempala -- cempala cempala --register-antigravity # OpenCode — if installed after Cempala, or if registering it failed opencode mcp add cempala -- /absolute/path/to/cempala

Antigravity is the odd one out: it has no mcp add command, so Cempala registers itself by merging a single entry into Antigravity's own MCP config file — which covers both the Antigravity app and the agy command line. Every other server and setting in that file is preserved, and if the file can't be read, Cempala changes nothing and prints the snippet for you to paste in yourself.

OpenCode’s entry is written by OpenCode: Cempala calls its own opencode mcp add rather than editing the file itself, which is what keeps the comments and formatting in that JSONC config intact. Restart OpenCode afterwards, then confirm with opencode mcp list. Until v0.5.0 this was the one entry you had to add by hand.

3. That's it

There’s no server to start. The next time you open an assistant the installer registered, Cempala is available — restart any that was already running when you installed. Try the first example in Asking in plain language.

Re-running the installer

Running the command again just updates Cempala to the latest version. It replaces the program even while an assistant is holding it open, so there's nothing to quit first. It won't duplicate the registrations and won't touch any settings you've changed — though an assistant that's already open should be restarted so it picks the new one up.

Where everything lives

One folder holds the whole thing.

All of Cempala's state sits in a single place: ~/.cempala/. Inside are its settings, its notebook (a small database), and the saved output of past tasks.

  • config.toml: optional settings. You almost never need to open it.
  • cempala.db: the shared notebook every handoff is written to.
  • outputs/: the raw output captured from each task, kept for your records.
  • bin/: the program itself, in the same place on every system.

That one folder is nearly the whole story, but not quite. Installing also writes to places that belong to other programs: your shell's startup file, which gets a short marked block putting Cempala on your PATH; and a registration inside each assistant it found. Since v0.5.0 that can be all four: Claude Code, Codex and OpenCode each get an entry when the installer finds their CLI, and the Antigravity merge is attempted every time. That's why removing Cempala is its own step rather than a matter of dragging a folder to the bin.

Uninstalling

One line, and it undoes what installing did.

# macOS / Linux curl -fsSL https://raw.githubusercontent.com/thelabs-id/cempala/main/scripts/uninstall.sh | bash # Windows (PowerShell) irm https://raw.githubusercontent.com/thelabs-id/cempala/main/scripts/uninstall.ps1 | iex

Deleting ~/.cempala/ on its own is not enough, and it fails in a way you would feel for months rather than notice at once. The registrations would survive, each pointing at a program that no longer exists, so an affected assistant would report Cempala as a failed server on every launch — indefinitely, until you removed the stale entry yourself.

What the one-liner actually takes away is the program, the PATH entry, and every registration it can still reach. Since v0.5.0 that includes the OpenCode entry, taken out of the global config files OpenCode reads wherever Cempala can edit them safely. A project-level opencode.json you wrote yourself is the one exception: the installer never added it, so it isn’t removed either. Your ~/.cempala/ folder stays unless you ask for it to go.

Your history is kept by default

Uninstalling removes the software, not your records. ~/.cempala/ holds the task history and the audit log, and uninstalling the program isn't an instruction to throw those away. Add --purge (-Purge on Windows) if you do want them gone. Either way you're told which one happened.

Three things about how it behaves, because an uninstaller that is careless is worse than none:

  • It asks each assistant to remove its own registration, using that tool's own command, so their config files stay theirs. That is also its one blind spot: an assistant you have since uninstalled has no command left to ask, so its entry is reported as nothing to do and stays behind for you to delete. Antigravity and OpenCode are edited directly, since neither ships such a command — one key removed from each, every other server and setting untouched, and neither file ever deleted. The OpenCode entry is cut out rather than rewritten around: every other byte, comments and indentation included, is copied straight through, though an empty mcp block can be left behind where Cempala's was the only entry in it.
  • On macOS and Linux your shell startup file is only touched where the installer's own marker is still there. A block you have edited, a commented-out copy, or a file that merely mentions the same path is left alone — as are your line endings. Install then uninstall returns that file to its original bytes. On Windows there is no startup file involved: the installer set a user PATH entry, and uninstalling removes exactly that one entry, leaving the rest of PATH in its original order.
  • A step it cannot finish is reported as a partial uninstall — no success banner, a non-zero exit, and the program 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.

Use --dry-run to see exactly what would happen without changing anything. The two delicate steps are also available on their own, if you would rather do this piecemeal: cempala --unregister-antigravity, cempala --unregister-opencode and cempala --remove-path-block <file>.


The two ways to hand off

Cempala moves a piece of work in one of two ways. You rarely pick one on purpose. You just describe what you want, and the right one happens.

Right now: dispatch

When you want the answer in the same reply, Cempala uses dispatch. It quietly starts up the assistant you named, hands it your request, waits for it to finish, and passes the result straight back into your conversation. This is what makes "have Codex do X and show me the result" work in a single turn — and when the work outlasts the wait, you get a "still running" answer with a task to check on rather than a hang.

If a task takes longer than expected, Cempala doesn't hang forever. It lets you know the work is still running in the background, and you can check on it whenever you like. Nothing gets lost. While it waits, it reports progress every ten seconds to any assistant that asked to be kept posted, so one that would otherwise give up on a slow handoff — and wrongly call it unreachable — keeps waiting for as long as the work honestly continues. An assistant too old to ask for progress keeps its own timeout, and may need that timeout raised in its settings.

Without waiting: the mailbox

Sometimes you'd rather not sit through the work. That's the mailbox: you assign a task to another assistant and get your turn back at once, then collect the result later. Since v0.5.2 assigning also starts that assistant in the background wherever it can — before then the task was only written down, and one that nobody happened to look for could sit untouched indefinitely. The reply tells you which of the two happened, so a task that is only waiting never looks like one that is running.

It runs on exactly the same terms as an immediate handoff: the same boundary, the same blocked places, the same limits, and the same honest note about what "no network" was worth. Work can't get an easier deal by being assigned instead of asked for. And it goes one hop only — an assistant working an assigned task can still write tasks down, but those wait rather than starting a chain.

Sometimes nobody is started: no assistant was named, the one that was isn't installed here, or someone claimed the task first. The task is recorded anyway and the reply names the reason. Where the task is assigned to an assistant and still waiting for a claim, it then rides along on the next answer that assistant gets from Cempala — so it finds out the next time it asks for anything at all. That needs the assistant to say who it is on the call, and it carries the first ten waiting tasks alongside the true total, so a long queue stays a footnote rather than the answer. Work assigned to nobody has no inbox to arrive in; it waits until someone goes looking.

Both ways write to the same notebook, so whether a task ran in front of you or in the background, it lands in one shared history you can review later.

The shared notebook

Why every handoff is written down.

Cempala keeps a single small database that every assistant reads and writes. It's the reason separate programs can coordinate without stepping on each other, and it's also your audit trail.

Every task, whether it ran, was refused, or is still going, becomes a row in that notebook: what was asked, which assistant did it, which folder it ran in, how long it took, and how it ended. Even denied requests are recorded, so the history shows the whole story, not just the successes.

Reading the log

The simplest way to browse past handoffs is to ask an assistant to look one up for you. The database is plain SQLite, so you can also read it yourself. See Reviewing what happened.

Where it's allowed to work

Cempala stays inside a clear boundary, and asks before ever stepping outside it.

Out of the box, tasks can only run inside your home folder, the place your own documents and projects live. There's nothing to set up for this; it just works that way from the first install.

  • Sensitive spots are always blocked: things like SSH keys, cloud credentials, and browser profiles are off-limits even though they sit inside your home folder. This can't be switched off.
  • Outside your home folder, it asks first: if a task points somewhere else, Cempala pauses and tells you, in plain words, that it hasn't been allowed there yet. Only after you say yes does it proceed.
  • Approval is remembered per folder: say yes once for a folder and later tasks in that same folder just work. You're not asked again and again.

A blocked spot can never be un-blocked

Even if you explicitly try to approve a sensitive location like your SSH keys, Cempala refuses. The always-blocked list is the one rule you can't override.


Asking in plain language

You don't call functions. You just say what you want.

Once Cempala is installed, working with your assistants is a matter of asking one of them to involve another. A few examples:

"Ask Codex to add tests for the file I just changed, then run them."Runs immediately; the results come back in the same reply.
"Have Codex tidy up my project folder and sort the loose files."An everyday chore, handed off and done.
"Get Claude to write a clear README for this project."Works the other direction too — sent from Codex.
"Get Antigravity to review this migration and tell me what it would break."Any assistant can hand work to any other.
"Ask OpenCode to trace this failure and summarize the fix."OpenCode can receive a dispatch and use Cempala’s eight tools.

The assistant you're talking to decides when to reach for Cempala, so there's nothing special to type. If a task needs a folder Cempala hasn't been allowed into yet, it'll relay that back to you in plain language and wait for your OK.

Reviewing what happened

Every handoff, on the record.

Because everything is written to the shared notebook, you can always look back at what the assistants did on your behalf. While you're still in the conversation that started a task, just ask: the assistant already holds that task's id and can look it up for you. That's the check_task tool, and it answers about one specific task rather than listing them — so for anything further back, read the notebook yourself.

It's an ordinary SQLite file, with nothing stopping you:

# the last 20 handoffs, newest first sqlite3 ~/.cempala/cempala.db "select datetime(created_at/1000,'unixepoch') as at, assigned_to, via, status, (completed_at-started_at)/1000 as secs, cwd, description from tasks order by created_at desc limit 20"

Each entry shows the request, which assistant handled it, the folder it ran in, how long it took, and how it ended. Nothing is pruned automatically, so the history is as complete as you want it to be.

Network access

Requested off by default, and honest about what "off" was actually worth.

Cempala itself never reaches the internet. When it hands a task to an assistant, it asks for that task to run without network access unless you say otherwise. If a task genuinely needs to fetch something, you turn network on for that call on purpose.

What that request is actually worth is the honest part, and it depends entirely on which assistant runs the task. Cempala tells you which of the four you got rather than pretending they’re the same:

  • Codex: a hard, system-level block. Nothing in the task can reach out.
  • Claude: its own web tools are switched off, which reduces the chance of network use but isn't an absolute wall — the shell it can still run could reach out.
  • OpenCode: its per-dispatch policy denies web tools and external paths, but its Bash tool can still make a direct network request. The result honestly says tools_only, not sandboxed.
  • Antigravity: the request can't be applied at all. It offers no switch for this, and its reach is set by your own Antigravity permissions, which Cempala neither reads nor changes. The task still runs, and the result says plainly that the guarantee wasn't available.

If an Antigravity task must be offline

Set it in Antigravity's own permissions. Cempala won't report a protection it didn't apply, so the honest answer here is that this one is out of its hands.


Tools reference

For the curious: the actual tools your assistants call through Cempala. You never type these. Your assistants do.

dispatchHave another assistant do something right now and return the result in the same turn — or, past the wait, a "still running" answer to follow up on.
create_taskHand a task to another assistant and get your turn back at once. It starts in the background where it can, under the same rules as an immediate handoff, and says so either way.
claim_taskAn assistant takes ownership of a task that is still waiting. Only needed where nobody could be started for it.
complete_taskRecords a task's final result — done or failed.
check_taskLook up the current status and result of any task.
send_messageLeave a plain note for another assistant.
check_messagesRead notes addressed to you, and mark them read.
approve_pathAllow work in a folder outside your home directory, after you've said yes.

Every one of these is logged. None can silently fail. If something is refused, the assistant gets a clear reason it can relay to you.

Requirements

Operating systemmacOS (Intel or Apple Silicon), Linux (x64 or arm64), or Windows x64 — Windows on ARM runs the x64 build under emulation.
AssistantsClaude Code, Codex CLI, Antigravity and/or OpenCode installed. One is enough; install more and work can be handed in any direction between them.
AccountsEach assistant must be ready to run on its own, with valid credentials or — for OpenCode — a working provider configured. Cempala holds no keys and never talks to a model itself, so an assistant that cannot answer on its own fails every handoff sent to it.
RuntimeNone to install — Cempala ships as a single self-contained program.
NetworkNone for Cempala itself. Your assistants still reach their own model providers.

Not yet: coordinating across two machines, and scheduled tasks. Cempala would rather do one job honestly than half-support everything. OpenCode arrived in v0.4.0 and has been registered by the installer like the rest since v0.5.0.

Troubleshooting

My assistant doesn't seem to know about Cempala

It may have been installed after Cempala. Run the matching register command from Install & first run, then restart the assistant.

A task said it "needs approval"

Read which of the two reasons it gave. Outside your home directory: tell your assistant to go ahead, and it'll approve that folder and retry — from then on, that folder is remembered. The folder contains a blocked spot — asking to work in your whole home directory, which holds ~/.ssh, does this — and no approval can unlock it. Point the task at a narrower folder instead.

A handoff failed, and the error mentions 401

That’s almost always the assistant, not Cempala. Each one runs on its own credentials — or, for OpenCode, on whichever provider you configured — and those expire or get misconfigured. Run the assistant on its own once — claude -p "reply with OK", codex exec "reply with OK", agy -p "reply with OK", or opencode run "reply with OK" — and fix whatever it complains about instead of answering. An Antigravity that isn’t signed in has a tell of its own: it waits a full minute for a sign-in that a background task can never complete, then gives up.

An Antigravity task came back empty, or refused to run a command

In the background, Antigravity quietly denies anything needing a permission it can't stop and ask you about. File edits are fine out of the box; shell commands aren't, until you add an allow-rule in Antigravity's own settings. Cempala reports that as a failure with the reason attached rather than a success with nothing in it, and it won't skip the permission check to force it through. Phrasing a request toward editing files ("create the file at…") tends to work where phrasing it toward the shell ("run a command to…") gets denied.

A task is still running after a while

Long tasks keep going in the background rather than being cut off. Ask your assistant to check on it. It'll update itself when the work finishes, and anything left running long after its process is gone gets swept up and recorded as what actually happened. If a handoff comes back to you as unreachable but shows up as finished when you check, that is your assistant's own timeout, not a lost task — v0.5.1 added the progress heartbeat that keeps such clients waiting.

I want to start completely fresh

For settings, history and approvals, delete the ~/.cempala/ folder — that clears all three in one step, and a re-run of the installer rebuilds what it needs. To remove Cempala itself, use the uninstaller rather than deleting the folder, so the registrations inside your assistants go with it — and read what it reports, since it names any it could not reach.