# amux installs one Rust binary and puts a compare-and-swap board under your coding agents

> A Rust control plane for running fleets of Claude Code, Codex and Gemini CLI workers from a dashboard or a phone, with a single-writer SQLite store and an event journal. The mechanics are unusually well documented, including the parts that bit the authors, but the licence is not simply MIT and only one release tag exists.

**mixpeek/amux** — Open-source control plane for AI coding agents. Run an AI engineering team: parallel Claude Code, Codex, and Gemini workers with a shared board, atomic tasks, schedules, loops, origin-stamped messaging, model switching, and self-healing recovery. One dashboard, or your phone. MIT, single Rust binary.

- Repository: https://github.com/mixpeek/amux
- Website: https://amux.io
- Stars: 510 · Forks: 62
- Language: Rust
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/mixpeek-amux

## install.sh does the entire setup and asks before installing

Setup is one line, and it clones as part of it:

```bash
git clone https://github.com/mixpeek/amux && cd amux && ./install.sh
```

What happens next is spelled out rather than implied. The installer checks prerequisites, which means the Rust toolchain and tmux, and it prompts before installing anything rather than acting silently. It builds the workspace, installs the server and the CLI into `~/.local/bin`, loads the launchd agents on macOS, mints `~/.amux` on first boot with the database, TLS material and an auth token, waits for `/health` to answer, and only then prints:

```
Dashboard   https://localhost:8824
Auth token  ~/.amux/auth_token
CLI         amux-rs --url https://localhost:8824 health
```

The certificate is self signed, so the browser warning is expected. Re-running `./install.sh` upgrades in place and never touches your data, and `./uninstall.sh` removes the binaries and the agents while leaving `~/.amux` alone. Auto rebuild is wired the same way on both platforms: on macOS the server watches its own binary timestamp and exits so launchd relaunches it, and on systemd Linux the installer creates three user services, `amux-server.service`, `amux-builder.service` for rebuild on code changes, and `amux-builder.timer` which checks every 60 seconds. They still need starting by hand:

```bash
systemctl --user enable amux-server amux-builder.timer
systemctl --user start amux-server
```

## make dev runs against /tmp/amux-dev.db, not your real store

The day to day commands are short, and each one does something different to your data:

```bash
make run        # rebuild + reinstall; the running server self-adopts in ~5s
make dev        # run against a scratch DB (safe for testing migrations)
make status     # launchd + /health at a glance
make restart    # kick the launchd-managed server
make check      # cargo check + JS syntax (fast, no link)
make test       # clippy + cargo test
```

`make dev` is the one to understand. In the Makefile it sets `AMUX_DB=/tmp/amux-dev.db`, so a working copy cannot touch the live store, which is the point when you are writing migrations. `make run` is what you want after a `git pull`: it rebuilds release, reinstalls the binary, and the server watches its own binary timestamp and exits so launchd relaunches it. `make test` is not just unit tests, it runs clippy with warnings denied across all targets and then a contended test script against the server. Two Makefile details are worth knowing. `make install` is just `./install.sh` again, while `make install-cli` calls `scripts/install-cli.sh` to publish syntax checked Bash CLI bytes with no Cargo build and no server restart, which is the cheap path while you are only editing shell. Variables at the top of that file set `BIN_DIR` to `~/.local/bin`, port 8824, the launchd label `com.amux.server-rs`, and a Cargo target directory kept inside `~/.amux`.

## One axum server, one SQLite writer, one event journal

The only server in the tree is the Rust one in `crates/amux-server`, on port 8824, serving HTTPS with a self signed certificate and redirecting plain HTTP. Storage is a single writer SQLite store with an event journal behind it, and synchronisation is SSE plus deltas rather than a websocket. The same process carries the scheduler and orchestrator runtime and embeds the dashboard. There is also a live way to check that claim rather than take it on trust: `GET /api/debug/boundary` reports `proxied: []`, meaning no API family is being forwarded to an older implementation. The same binary still answers the retired port 8822 while a compatibility bind survives, and the Python predecessor that used to live there is gone. If you are reading code, the guidance is to start in `crates/`. Above the server sit eight primitives, and the stated design rule is that new capability composes them rather than wrapping them: board for the shared kanban with its status gates, workers as tmux backed sessions with durable identity, schedulers for cron style jobs with an audited run history, filesystem for browsing and editing a worker's working directory, and groups as tags that scope visibility, gates, memory and environment.

## The dashboard is embedded, but node is still a dev dependency

The workspace has four crates. `amux-server` is the axum API. `amux-dashboard` is the single page app, embedded into the server binary at build time, which is why you need neither node nor npm to run the thing. `amux-cli` builds `amux-rs`, covering board, workers, send, schedules and health. `amux-core` holds the shared domain types, meaning ids, scopes, revisions, memory and protocol. The runtime story and the development story then diverge. The root package.json still carries esbuild, eslint and Playwright, and the `make check` target loops `node --check` over every file in `crates/amux-dashboard/static/`. So the dashboard ships compiled inside a Rust binary while the toolchain around it is still JavaScript. There is a `lint:spa` script that shells out to `bash scripts/spa-lint.sh` for the same reason.

## serde_json carries float_roundtrip for a measured reason

The workspace Cargo.toml explains two dependencies at unusual length, and both explanations are about bugs rather than taste. The first is the `float_roundtrip` feature on serde_json. The stated problem is that the default float parser is not correctly rounded and can land one ULP away from the nearest f64 to the decimal it is reading, so a value written with `to_string` does not reliably read back with `from_str`. Writing is exact; the drift is entirely on the read. The comment reports a measurement over 1,023,542 f64 values on serde_json 1.0.151 where 126,027 of them, 12.3 percent, drifted, and says that is why an earlier failure looked like a flake for two rounds. The cost is about double the time on float parsing only, and a named check, `f64_survives_json_roundtrip`, fails loudly if the feature is ever dropped, since a Cargo feature is otherwise invisible at runtime.

## Tokio's feature list is explicit because full takes the UI offline

The second long comment is about Tokio, and it is a narrower lesson. The feature set is spelled out one by one rather than using `full`, because `full` enables Tokio's optional `parking_lot` parker. The comment reports that path panicking inside `parking_lot_core::thread_parker::unix` on macOS debug branch servers, taking the whole UI offline and surfacing as a sync error. amux uses the capabilities but not that backend. The workspace declares every crate as a member and keeps one shared dependency block so that all four inherit the same version of each concern, a convention the file cites as RR-0001. That block pins serde with its derive feature, serde_json with the rounding fix, an explicit Tokio feature list, axum 0.8 with http2, tracing 0.1 and tracing-subscriber with an env filter, and rusqlite for the store. The stated reason for the single block is simple: the whole system has to agree on one version of each concern rather than let crates drift apart.

## MIT plus Commons Clause, while the metadata records no licence

The licence needs care. The repository metadata reports NOASSERTION rather than a standard identifier, while the README describes the project as MIT plus Commons Clause, free to use, modify and self host, with commercial resale requiring a separate licence. Those are not the same thing, and the file to read is `LICENSE` rather than the badge. Version history is thin by comparison. There is one release, v0.9.108 on 2026-07-13, the repository is not archived, and the last push to main was on 2026-09-30, so the code has moved well past the only tag. On platforms the installer covers macOS and systemd Linux, the latter named as Ubuntu 22.04 or newer, Debian 11 or newer and Fedora 36 or newer. Anything else builds and installs, but you run the server yourself:

```bash
AMUX_RS_PORT=8824 ~/.local/bin/amux-server-rs
```

The stated requirements are tmux 3.2 or newer and at least one of Claude Code, the Codex CLI or the Gemini CLI. The root directory is broader than a server project: alongside `crates/` there are `android/`, `ios/`, `desktop/`, `cloud/`, `business-ui/` and `site/`, a `mcp.json`, a `server.env.example`, `skills/`, `templates/`, `research/`, `integrations/`, `examples/flask-tunnel-demo/`, two Dockerfiles for the Rust base and build stages, and `rust-toolchain.toml`. Four files worth skimming before you run anything are AGENTS.md, CLAUDE.md, GEMINI.md and SECURITY.md.

## Conclusion

amux is aimed at people already running several coding agents at once, where the problems are coordination rather than completion: two workers grabbing the same card, a crashed session nobody noticed, a prompt that needs redirecting mid-run. The compare-and-swap claim, the status gates that separate done from verified, the origin-stamped message ledger and the watchdog are the parts that justify the install. It is the wrong shape for a single agent, and you should read the licence file before anything else, because the README describes MIT plus Commons Clause while the repository's licence field carries no standard identifier, and commercial resale needs a separate agreement. Concretely, verify tmux 3.2 or newer and at least one agent CLI on the machine, confirm your platform is macOS or systemd Linux, and read what port 8822 still answers before you point anything at it.

## FAQ

### What does amux install and where does it put things?

The installer builds the Rust workspace, installs the server and CLI into ~/.local/bin, loads launchd agents on macOS, and mints ~/.amux with the database, TLS material and an auth token on first boot. It then waits for /health and prints the dashboard URL on port 8824, the token path, and the amux-rs health command.

### How does amux stop two workers taking the same task?

Tasks live on a shared kanban board where claiming is compare-and-swap, so two workers cannot grab the same card. Status is gated as well: done requires evidence and verified requires a peer check, which keeps the two states distinct rather than treating them as the same thing.

### What does uninstalling amux do to my data?

The uninstall script removes the binaries and the service agents and leaves ~/.amux alone, so the database, TLS material and auth token survive. Re-running ./install.sh instead upgrades in place and never touches your data either.

### Which platforms and tools does amux need?

Requirements are tmux 3.2 or newer plus at least one of Claude Code, the Codex CLI or the Gemini CLI, with the Rust toolchain installed through rustup after confirmation. macOS is handled through launchd, systemd Linux through user services on Ubuntu 22.04 or newer, Debian 11 or newer, and Fedora 36 or newer, and other Linux distributions run the server binary manually.

## Sources

- [Issues](https://github.com/mixpeek/amux/issues)
- [mixpeek/amux on GitHub](https://github.com/mixpeek/amux)
- [Project website](https://amux.io)
- [README](https://github.com/mixpeek/amux/blob/main/README.md)
- [Releases](https://github.com/mixpeek/amux/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mixpeek-amux
