coordination for Claude Code teams
Reference

Commands

Everything the mai CLI does. Install it with npm install -g telemai or prefix each command with npx telemai. Run commands from inside the repository unless noted. Configuration lives in ~/.mai; set MAI_HOME to put it elsewhere.

On the host machine

mai host [--tunnel | --cloudflare-token <token> --public-url <url>] [--port <n>] [--image <ref>] [--no-fetch] [--telemetry | --no-telemetry]

Runs the server and Postgres for this repo in Docker (a compose project under <MAI_HOME>/host), builds the dependency graph from the repo's origin/main, and prints the server's build. Keep the terminal open while a tunnel is in use.

FlagEffect
--tunnelOpens a Cloudflare quick tunnel. No account needed; the hostname changes on every start, so teammates need fresh invites after a restart. For trials.
--cloudflare-token <t> --public-url <url>Runs a named Cloudflare tunnel on your own domain, the stable mode. Map the hostname to the server's port in the Cloudflare dashboard.
(no tunnel flag)The server is reachable only on this machine. Fine for trying Telemai alone.
--port <n>The local port the server listens on (default 4000).
--no-fetchDon't git fetch origin every 30 seconds for the graph. The graph then follows origin/main as of whenever you last fetched by hand.
--image <ref>Run a specific server image, for example ghcr.io/emaiiii/mai-server:<version>. The default matches the CLI's version; mai host warns when the two differ.
--telemetry / --no-telemetryOpt this host in to, or out of, the daily telemetry ping. Off until you pass --telemetry; the setting sticks until you change it. See telemetry & privacy.

mai host status

The server's health, its build (version and commit), the graph's ref and commit, the last commit the safety net scanned, and the tunnel address.

mai host stop [--purge]

Stops the containers. --purge also deletes the database volume: every event, decision, claim and engineer for this project is gone.

mai invite <email> [--expires <hours>] [--server <url>] [--public-url <url>]

Mints a single-use invite for one engineer and prints it as a mai://… string. Good for 24 hours unless --expires says otherwise (up to 14 days). The admin token comes from the host config written by mai host, or from MAI_ADMIN_TOKEN. --server and --public-url override the local and public addresses from that config.

mai revoke <email>

Refuses that engineer's tokens everywhere (hooks, MCP, channel) and closes their channel. A new invite lets them back in.

On every engineer's machine

mai join <invite> [--team <name>] [--name <n>] [--force]

Redeems an invite and writes your tokens and the server address to ~/.mai. --team is required on the first join and kept on a re-join; --name defaults to your git user.name. Joining again as an existing engineer, with a fresh invite, rotates your tokens, so it retires a leaked one. --force replaces a ~/.mai that already exists; it is refused while mai start is running on it. For a second identity on one machine, set MAI_HOME instead.

mai own <path> [<path> ...]

Declares your team's areas. Paths are relative to the repo root; the longest matching prefix wins. A path another team owns is refused. Other leads are notified (ownership_declared).

mai disown <path> [<path> ...]

Removes areas again. Each path must match an area exactly as declared; a path that is merely inside an area is refused. Other leads are notified (ownership_removed). Existing claims are untouched.

mai start [-- <claude args>]

Launches Claude Code at the repo root with the Telemai plugin, your lead agent, agent teams, the mai MCP tools and the channel. Run it in a real terminal. Anything after -- is passed to Claude Code.

mai status

Is the host up, and what build is it running? The graph's commit, your team, your areas, the claims that touch you, whether a lead session is running, and whether this machine is the host. Exits with status 1 when the host is down, and says so plainly with a note that your side keeps working.

mai log [--type <t>] [--team <n>] [--since 2h|30m|3d|<iso>] [--limit <n>]

The shared log, oldest first: team, type, a CRITICAL marker where it applies, and a one-line gist. Other teams' escalations are never shown. Types you can filter on:

TypeMeaning
file_editedA worker edited a file (hook or shell).
contract_changedAn exported API changed; breaking marks the ones that matter. Source is hook or merge (the safety net).
schema_changedA new migration file. Always critical.
claim_placed, claim_releasedA team took or gave up a temporary hold on files.
task_statusA worker's task was created, completed, or the worker went idle.
announcementA lead told the other leads what it's doing.
decision_recordedA lead logged its engineer's decision.
escalationYour own team's open or resolved escalations.
ownership_declared, ownership_removedmai own and mai disown.

mai claims [<path> ...]

Every team's active claims, yours marked. With paths, only the claims under them.

mai escalations [--all]

Your team's open escalations: what your lead is waiting on you to decide. Answer in the lead chat. --all includes resolved ones.

Environment

VariableWhereEffect
MAI_HOMEAny machineWhere the CLI keeps its config instead of ~/.mai. Useful for running two engineers on one machine.
MAI_ADMIN_TOKENHostThe admin token for mai invite and mai revoke when it isn't in the host config.
MAI_TELEMETRY_URLHostWhere mai host --telemetry sends the daily ping, instead of our collector. mai host writes the chosen address into the server's environment; empty means no ping.