Reference
CLI reference
Every comity command, flag, exit code and config file.
On this page
The comity CLI signs you in, writes agent configuration into your repos, checks your setup and runs inside your agents' hooks. It needs Node.js 22 or newer.
npm i -g https://api.comity.so/cli/comity-cli.tgz
comity --versionRunning comity with no arguments shows a home screen: your account, the server, the current repo, which agents are set up there (✔ ready, ! partial, – missing) and the next command to run.
Global options
| Option | Effect |
|---|---|
--help, -h |
With no command: the command overview. After a command (comity init --help): that command's usage, options and examples. |
--version, -v |
Print the CLI version. comity version does the same. |
--no-update-check |
Skip the update check for this run. See Updates. |
Unknown commands exit with code 2 and suggest the closest match.
comity login
Signs in and stores the credentials on this machine.
| Option | Description |
|---|---|
--server <url> |
Comity server. Default https://api.comity.so, or COMITY_SERVER when set. |
--token <cmt_…> |
Use an existing token instead of the browser. For headless machines and CI. |
Without --token (and without COMITY_TOKEN), login uses a browser device flow:
- The CLI prints a short code and a URL, and opens the URL in your browser (unless
COMITY_NO_BROWSERis set). - You approve the code in the browser while signed in to Comity.
- The CLI polls until the server mints a personal token named
cli · <hostname>and saves it.
The CLI then verifies the token with GET /v1/me and prints the account, org and role:
A token must look like cmt_ followed by 43 base64url characters. A rejected token (revoked, expired, or issued by a different server) fails with token rejected by server.
comity login
comity login --server https://comity.internal.example.com
comity login --token cmt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcomity logout
Deletes the stored credentials file. If COMITY_TOKEN is set in the environment, the CLI warns that it keeps authenticating.
comity init
Writes Comity's hook, MCP and agent-instruction configuration into the current repository (the git top level; outside a git repo it writes into the current folder and warns).
| Option | Description |
|---|---|
--tools <list> |
Comma-separated agent ids, or all. Skips the question. Ids: claude_code, codex, cursor, copilot, gemini, windsurf, kiro, cline, roo, opencode, amp, droid, zed, continue, goose, junie, augment, omp. |
--yes, -y |
No question: use --tools, or the default claude_code,codex. |
--server <url> |
Server the MCP config points at. Default: the server you logged in to. |
In an interactive terminal without --tools or --yes, init lists every supported agent, grouped by how Comity reaches it (hooks + MCP, or MCP + instructions only). Agents found on this machine (an executable on PATH or a config folder in your home directory) are pre-selected; when none is found, Claude Code and Codex are. Space toggles, a toggles all, Enter confirms. Cancelling writes nothing (exit 130).
In a pipe, in CI, or with --yes, init sets up claude_code,codex unless --tools says otherwise. Every other agent is opt-in: name it in --tools, or use --tools all.
Files written per agent:
| Agent | Files |
|---|---|
claude_code |
.claude/settings.json (hooks), .mcp.json (MCP server comity) |
codex |
.codex/hooks.json (hooks), .codex/config.toml ([mcp_servers.comity]) |
cursor |
.cursor/hooks.json, .cursor/mcp.json, .cursor/rules/comity.mdc |
copilot |
.github/hooks/comity.json, .github/mcp.json (Copilot CLI), .vscode/mcp.json (VS Code) |
gemini |
.gemini/settings.json (hooks + MCP), GEMINI.md (Comity block) |
windsurf |
.windsurf/hooks.json, .windsurf/rules/comity.md (MCP is user-level: init prints the entry) |
kiro |
.kiro/hooks/comity.json, .kiro/settings/mcp.json, .kiro/steering/comity.md |
cline |
.clinerules/hooks/<Event> scripts (MCP is user-level: init prints the command) |
roo |
.roo/mcp.json, .roo/rules/comity.md |
opencode |
.opencode/plugins/comity.ts (plugin), opencode.json (MCP) |
amp |
.amp/plugins/comity.ts (plugin), .amp/settings.json (MCP) |
droid |
.factory/hooks.json, .factory/mcp.json, AGENTS.md (Comity block) |
zed |
AGENTS.md (or the instructions file Zed already reads; MCP is user-level: init prints the entry) |
continue |
.continue/mcpServers/comity.yaml, .continue/rules/comity.md |
goose |
.agents/plugins/comity/plugin.json + hooks/hooks.json, AGENTS.md (MCP is user-level) |
junie |
.junie/comity-hooks.json, AGENTS.md (hooks and MCP are user-level: init prints both) |
augment |
.augment/hooks/comity.sh + comity.cmd, .augment/rules/comity.md, personal .augment/settings.local.json (not committed) |
omp |
.omp/extensions/comity/index.ts (bridge extension), .omp/mcp.json (MCP server comity) |
init merges into existing files: it replaces only handlers whose command runs comity hook, only the comity MCP entry and only the marked Comity block of shared instruction files (AGENTS.md, GEMINI.md), keeps everything else, and is safe to re-run. No token is ever written to the repo. The exact contents, approvals and limits are on each agent's page.
After writing, init prints next steps per agent (trust prompts, approvals, user-level MCP entries to paste) and, inside a git repo, the git add / git commit command for the repo files that changed, so teammates get the same setup when they pull.
comity init
comity init --yes
comity init --tools claude_code,omp
comity init --tools cursor,gemini
comity init --tools all --yescomity status
Shows:
- Account: user, org, role, server (and whether it came from the environment or the config file).
- Plan: plan name, active developers this month and repos against the plan's limits, and who is not coordinated when over a limit.
- Repo: path, remote fingerprints, branch, HEAD and merge base with the default branch. A repo without a remote shows
(none — hooks are inactive here). - Your intents: your live intents in this repo with status, branch and claim count.
- Teammates online: other developers' live agents (
●active,○idle) with tool, branch and intent.
--json prints the same data as one JSON object (server, server_source, token_source, user, org, usage, repo, intents, teammates, plus *_error fields for sections that failed).
comity doctor
Checks the whole chain from config to a real hook round trip. Each warning or failure prints a › line with the fix.
| Check | What it verifies |
|---|---|
config |
Server and token are configured (and where from); the token has the cmt_ shape. |
server |
GET /healthz answers. Warns above 400 ms, because pre-edit checks that take longer fail open. |
token |
GET /v1/me accepts the token and it has the hooks:evaluate and mcp:tools scopes. |
git |
You are in a git repo that has at least one remote. Hooks are inactive in repos without a remote. |
<agent> hooks, <agent> mcp, … |
One group per agent that has Comity config in this repo or your user config (agents without any are skipped): hooks installed for every event, the comity MCP entry present and authenticating, the rules/instructions block current. Hooks from an older comity init with a different matcher (Claude Code before 0.4.1: no ExitPlanMode) warn "update available"; rerun comity init. Agents whose MCP entry lives in user-level config the CLI does not write (Windsurf, Cline, Zed, goose, Junie, Augment) warn until you add it. |
agents |
Warns when no agent is set up here at all. |
round trip |
Sends a session_start and session_end for a throwaway session to /v1/hooks/evaluate. Warns above 400 ms. |
CLI up to date |
Compares your version with the latest release. |
Exit codes: 0 all checks passed, 1 degraded (warnings), 2 broken (failures). --json prints {"result": "ok" | "warn" | "fail", "checks": [{"name", "level", "detail", "fix"?}]}.
{
"result": "warn",
"checks": [
{ "name": "config", "level": "ok", "detail": "server https://api.comity.so [file], token [file], /home/diego/.config/comity/config.json" },
{ "name": "codex hooks", "level": "warn", "detail": "missing SessionEnd", "fix": "run `comity init --tools codex`" }
]
}comity whoami
Prints the signed-in user, org (name and slug), role, server, and token name and kind, including whether the token came from COMITY_TOKEN or the config file. --json prints the GET /v1/me response plus server. Exits 1 when not logged in.
comity open
Opens the web dashboard (/dashboard, /dashboard/messages or /dashboard/conflicts) in your browser, in the org you are logged in to. The web address is the one you logged in through, or COMITY_WEB_URL. With COMITY_NO_BROWSER set, the URL is printed instead.
comity update
Fetches the release manifest (<server>/cli/latest.json) and, if a newer version exists, runs npm install -g <tarball url> and confirms that comity --version on your PATH reports the new version. --check only reports whether an update is available. comity update always fetches the manifest; it ignores the 12-hour throttle and any earlier "no".
If the install fails, the CLI prints the exact command to run by hand and the likely cause (npm not on PATH, files in use on Windows, EACCES permissions).
comity help
Without an argument, lists all commands. With one, shows that command's usage, options and examples (same as comity <command> --help).
Commands run by your agents
These exist for agent configuration files. You don't run them yourself.
| Command | Used by | Output |
|---|---|---|
comity hook --tool <tool> --event <Event> |
Every hook entry comity init writes (directly, or through a node -e launcher for hosts that run hooks through PowerShell on Windows and sh elsewhere), and the omp/OpenCode/Amp plugins |
Reads the host's hook JSON on stdin, calls /v1/hooks/evaluate, prints the host's native hook output. Exits 0, except 2 with the reason on stderr where the host blocks by exit code (Kiro, Windsurf). See Hook events. |
comity mcp |
Stdio MCP entries written by comity init ("command": "node" with a one-line launcher that runs comity mcp through the system shell, the same entry on every OS) |
A stdio MCP server. It forwards every message to <server>/mcp with your login's token and writes the responses (streamed events included) to stdout, one JSON-RPC message per line. See Any MCP client. |
comity mcp-headers |
Claude Code headersHelper, Codex http_headers_helper |
{"Authorization":"Bearer cmt_…"} |
comity auth-header |
omp MCP header "!comity auth-header" |
Bearer cmt_… |
mcp, mcp-headers and auth-header read COMITY_TOKEN first, then the stored login. mcp-headers and auth-header exit 1 when neither exists. comity mcp keeps running and answers every request with an error that says to run comity login, so your MCP client shows the reason. comity mcp writes only protocol messages to stdout. It logs errors to stderr, and with COMITY_DEBUG=1 it also logs each message it forwards.
Updates
Interactive commands (login, logout, init, status, doctor, whoami, open, and the home screen) check for a newer CLI at most once every 12 hours, with a 1.5-second timeout. The hook, mcp, mcp-headers and auth-header commands never check.
- In a terminal, the CLI asks
Update now? (Y/n). Answering no silences that version for 24 hours. - Otherwise it prints one line on stderr.
Turn checks off with --no-update-check, COMITY_NO_UPDATE_CHECK=1, or by running in CI (CI set). The result of the last check is cached in update-check.json next to the config file.
Files
| File | Contents |
|---|---|
Config: ~/.config/comity/config.json ($XDG_CONFIG_HOME/comity/ when set); Windows %APPDATA%\comity\config.json |
server, token, machine_id, data_mode, web_url. Written with owner-only permissions. |
update-check.json (same folder) |
Last update check and any skipped version. |
hook.log (same folder) |
One line per hook that failed open, rotated at 1 MiB. |
<os temp>/comity-spool/ |
Per-session hook state (deduplication, queued notices, workspace map cache). Pruned after 48 hours. |
machine_id is a random UUID. The server only receives a hash of it, and an HMAC of your worktree path keyed by it; raw local paths never leave your machine.
Exit codes
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Error (not logged in, server unreachable, doctor degraded) |
2 |
Usage error (unknown command or flag), or doctor found failures |
130 |
init cancelled at the question |
See Environment variables for everything the CLI reads from the environment.