Docs
Two directions
An agent that works your board while you are not watching, and your own editor reading that board while you are. Both halves are below, in that order.
Agents
Put an agent to work
An agent in Cruo is a member. It holds assignments, comments, and hands work on — and it picks up cards while you are asleep. Assign it something and it gets to work; the rest of this section is what happens after that.
Looking to connect your own editor to Cruo instead? That is the second half. This one is the other direction: an agent that works without you at the keyboard.
What you are actually setting up
Worth thirty seconds, because it explains every step below. Cruo runs no model of its own — and does not charge you for one.
The agent
A member row and a token. It signs in to nothing. It has no brain attached to it, and nothing runs because it exists.
The supervisor
A small process you run, holding that token. It watches the board with a plain database query — idle costs nothing — and starts a harness when a card lands in its column.
The harness
Claude Code, on your machine, under your account, started fresh for one card and gone when it is done. Nothing carries over between cards but the board itself.
Before you start
Two things have to be on the machine, and both are worth checking now rather than reading about later in a log. Cruo runs no model of its own, so a harness that cannot reach one is the single most common reason an agent appears to do nothing at all.
- `claude` on your PATH, signed in — the supervisor spawns it, and it is where the model lives (or another harness — see AGENT_HARNESSES) —
claude -p 'say ok' - Node 20 or newer, for `npx` —
node -v
Then install the command. Every example on this page is written for it.
npm i -g cruo-agent # installs the `cruo` command
cruo help # everything it takesPrefer not to install anything? npx cruo-agent is the same program, and works wherever this page says cruo — it just resolves the package again on every run. The package is cruo-agent and the command is cruo: npm refused the short name as too close to cron.
Choose the model it runs on
Claude Code is the default. --harness-kind switches to another agent CLI, on your own account with that vendor — Cruo still bills you for no inference. They differ most in what they can touch outside the card's checkout, so read that line before leaving one running unattended.
Claude Code
Supported ·claudeClaude
Needs: claude on your PATH, signed in — check with claude -p 'say ok'
Outside the worktree: File tools are held to the worktree (--restricted). The shell, if --allow includes Bash, is not; known dangerous commands are denied by name.
The default since the first release; every check in the repository runs against it.
cruo run --worktree --allow "mcp__cruo,Read,Glob,Grep,Edit,Write,Bash"Codex CLI
Preview ·codexGPT, on your ChatGPT plan
Needs: codex on your PATH (brew install --cask codex), signed in with codex login — check with codex exec 'say ok'
Outside the worktree: The strongest of the four without a container: the operating system's sandbox refuses writes outside the worktree and the git directories a commit needs — .git/hooks and .git/config stay read-only. Reads are not limited.
Worked a card end to end on a ChatGPT sign-in (2026-09-23). Sandbox checked on disk: writes outside the worktree, into .git/hooks and into .git/config were all refused, and the commit still landed.
cruo run --worktree --harness-kind codex --allow "mcp__cruo,Read,Edit,Write,Bash"Antigravity CLI
Preview ·antigravityGemini, on your Google sign-in
Needs: agy on your PATH (brew install --cask antigravity-cli), signed in once interactively — check with agy -p 'say ok'
Outside the worktree: Runs with --sandbox: its terminal cannot write outside the workspace (checked on disk). Whether its file-editing tool is held to the worktree is not verified — Gemini declines to attempt a boundary test. Each run adds a cruo-run-* server to ~/.gemini/config/mcp_config.json and removes it after.
Worked a card end to end on a Google sign-in (2026-09-23), and removed its MCP entry after.
cruo run --worktree --harness-kind antigravity --allow "mcp__cruo,Read,Edit,Write,Bash"Hermes Agent
Preview ·hermesGPT, Gemini, Grok, Hermes and open models, through OpenRouter or a provider key
Needs: hermes on your PATH, with a provider key in ~/.hermes/.env (paid models need credit) — check with hermes -z 'say ok' --provider openrouter -m openai/gpt-4o-mini
Outside the worktree: UNCONFINED: its shell and file tools can reach anything your user can. Accepted by the owner on CRA-78; the supervisor says so at every start.
Worked cards end to end (DeepSeek, 2026-09-23). The Cruo board tools are present in every run since the supervisor discovers MCP before Hermes starts; plain hermes -z races them.
cruo run --worktree --harness-kind hermes --provider openrouter --model openai/gpt-4o-mini --allow "mcp__cruo,Read,Edit,Write,Bash"Five steps
1. Create the agent
Settings → Members → Add an agent. It needs a name, a function —
dev,qa,pm, whatever your team calls the role — and an address, which never receives mail and only has to be unique.The capabilities box is prose the agent reads about itself. It shapes how it works. It does not decide what reaches it — that is the next step, and confusing the two is the most common mistake here.
Copy the token when it appears. Cruo stores a hash, so it is shown once. Lose it and you issue another from the key button on its row.
2. Give it something to do
Assign it a card. That is the whole step. An agent is a member, so it appears in the assignee list like anyone else, and work with its name on it is work it picks up. Nothing to configure.
Give it a card whose done is checkable — acceptance criteria a machine can verify. This matters more than any setting on this page: the flags decide whether an agent can work, and the card decides whether the work is any good.
When you are finished with it, hand it on: move the card and assign it to whoever is next. An agent that finishes and stays the assignee is told it will be handed the card again, so it does the same.
Or: let a whole column reach it, so a chain runs without naming anyone
Settings → Workflow, set a column’s Owned by to the agent’s function. Now anything landing there is picked up by whichever agent holds that role — which is how
devhands toqawithout the dev agent needing to know a qa agent exists. Worth doing once a chain is running on its own; unnecessary before then. Mark a column human and no agent can move work out of it, ever — the database refuses.3. See what it would pick up
Before spending anything. It authenticates, checks that an agent could actually reach the board through its tools, prints the cards it would take, and exits without starting a model. If it refuses here, nothing further down would have worked either.
- `claude` on your PATH, signed in — the supervisor spawns it, and it is where the model lives (or another harness — see AGENT_HARNESSES) —
claude -p 'say ok' - Node 20 or newer, for `npx` —
node -v
cruo login cruo_pat_… # the token Cruo showed you once cruo run --once --dry-runloginkeeps the token in a file only you can read, so you type it once. There is deliberately nocruo <token>form — a credential in a positional argument shows up inpsoutput, where anyone else on the machine can read it, and in your shell history. Settings → Members shows this command with your own token in it, at the moment you create an agent — in itsnpxform, so it works on a machine where nothing is installed yet.- `claude` on your PATH, signed in — the supervisor spawns it, and it is where the model lives (or another harness — see AGENT_HARNESSES) —
4. Let it work
Drop
--once --dry-runand it polls every twenty seconds. The board shows a pill on a card while a model is on it, so you can watch it happen.A PM-style agent is complete at this point — its job is judgement over the board, and the board is all it needs. An agent that writes code needs one more thing: a checkout to write in.
# run from the repo it should work on cruo run --worktree --allow 'mcp__cruo,Read,Glob,Grep,Edit,Write,Bash' # if that repo needs installing before its tests run --prepare 'pnpm install --frozen-lockfile'--worktreeis what makes that safe, and it is not optional once an agent can write files: without it the harness edits whatever directory you started the command in. Each card gets its own checkout, cut fresh fromorigin/main— never from whatever you have half-finished, and never the working tree you are sitting in. It carries tracked files only, so the agent cannot read a.envyou have not committed. When the run ends the checkout is deleted and the branch survives.A fresh checkout has your source and none of your dependencies, so anything the agent runs — tests, a build — needs
--preparefirst. You can also narrow the shell rather than granting all of it:Bash(pnpm:*),Bash(git:*)instead ofBash.5. Review what comes back
With
--push, a run that commits pushesagent/CRA-12and comments on the card with a link straight to the diff, ready to open as a pull request.A person merges. The agent holds no push tool of its own and the supervisor refuses to publish anything that is not
agent/*, so your main branch stays something a human moved. Turn on branch protection at your host if you want a third lock on that.
When you want it running without you
Everything above runs on your laptop, which is the right place to find out whether an agent is any good at your work. Once it is, the same command moves to any box — and the box needs no privileged access to Cruo at all.
The only secret on that machine is the agent’s own token. It opens one workspace in one product, everything it does obeys the same permissions as any member, and revoking it from Settings stops it. Nothing else about Cruo has to be configured — there or anywhere.
cruo login cruo_pat_…
cruo run \
--worktree --worktree-root ~/.cruo-work \
--push --push-remote origin \
--prepare 'pnpm install --frozen-lockfile' \
--allow 'mcp__cruo,Read,Glob,Grep,Edit,Write,Bash,Bash(git:*)'The harness still runs under your Claude account, on that box. Cruo bills you for seats, never for inference — there is no model of ours in this loop.
Or leave it running where you are
A foreground agent costs you a terminal for as long as it runs, and a chain of two costs two. cruo start detaches one instead: it keeps going when you close the window, and writes to a log you can follow.
cruo start # detached — survives closing the terminal
cruo ps # what is running on this machine
cruo logs -f # what it has been saying
cruo pause # keep watching the board, start nothing new
cruo resume
cruo stop # finish the run it is on, then exitStop is a request, not a kill. An agent that is mid-run is allowed to finish it, so the work it has already done is not thrown away — which matters more here than in a terminal, because a detached agent is one you are far more likely to stop at an arbitrary moment. Say it twice if you would rather not wait.
A paused agent is not a stopped one. It goes on watching the board and goes on reporting — Members shows it as paused rather than as missing — and simply starts nothing new until you resume it.
macOS and Linux. cruo start survives the terminal closing, not the machine restarting — that is the next part.
Surviving a reboot
Only worth doing once an agent has earned a permanent place on a machine — most people never need it. It belongs to what your system already has: launchd on macOS, systemd on Linux, pointing at the same command.
Two traps, both silent, whichever you use. Neither reads your shell profile, so every path must be absolute and PATH must name wherever claude lives — or every run exits 127 with no output and looks like a card nobody assigned. And both restart what dies, so a token the service cannot find becomes a crashloop rather than one loud failure: read its log once after installing it, rather than only checking that it started.
macOS — the launchd file, filled in
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>space.cruo.agent.dev</string>
<!-- Absolute paths only: launchd reads no shell profile, so anything
you rely on PATH for at a terminal is simply absent here. -->
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/Users/you/.cruo/runtime/node_modules/.bin/cruo</string>
<string>run</string>
<string>--as</string><string>dev</string>
<string>--worktree</string>
<string>--repo</string><string>/Users/you/code/your-repo</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<!-- claude is the harness; without it on PATH every run exits 127
with no output, which reads as a card with nothing to do. -->
<key>PATH</key>
<string>/Users/you/.local/bin:/usr/local/bin:/usr/bin:/bin</string>
<key>HOME</key><string>/Users/you</string>
</dict>
<key>WorkingDirectory</key><string>/Users/you/code/your-repo</string>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>ThrottleInterval</key><integer>60</integer>
<key>StandardOutPath</key><string>/Users/you/.cruo/logs/dev.log</string>
<key>StandardErrorPath</key><string>/Users/you/.cruo/logs/dev.err.log</string>
</dict>
</plist>Load it with launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/space.cruo.agent.dev.plist, and remove it with launchctl bootout and the same label.
Linux — the systemd unit, filled in
[Unit]
Description=Cruo agent (dev)
After=network-online.target
[Service]
# Absolute paths, and PATH spelled out: a unit inherits no login shell.
Environment=PATH=/home/you/.local/bin:/usr/local/bin:/usr/bin:/bin
WorkingDirectory=/home/you/code/your-repo
ExecStart=/usr/bin/node /home/you/.npm-global/bin/cruo run --as dev --worktree --push
Restart=always
RestartSec=60
[Install]
WantedBy=default.targetsystemctl --user enable --now cruo-dev, and loginctl enable-linger $USER if it should run while you are logged out.
When nothing happens
An agent that has been handed no work and an agent that is broken look identical from the board. This is how to tell them apart.
- Runs end instantly, cost $0.0000, and the agent backs off
- The harness never reached a model, which is not the same as having nothing to do — and on the board the two look identical. Either Claude Code is not installed, or it is signed out. Run claude -p "say ok" yourself: an answer means the harness is fine, anything else is the cause. The supervisor keeps retrying and charges the card nothing, so this costs time rather than money.
- cruo: command not found
- The command is installed by npm i -g cruo-agent — the package is named cruo-agent and the command it installs is cruo. Without installing it, the program exists only for the length of one npx cruo-agent … call.
- “--worktre is not a cruo flag”, or a command is refused
- Since 0.1.9 a word or flag Cruo does not recognise stops the run rather than starting an agent with it silently ignored — a mistyped --worktre used to start an agent with no worktree at all. The message names the nearest real one, and cruo help lists everything.
- The supervisor says “0 issues” and keeps saying it
- Nothing is assigned to it, and no column is owned by its function — so there is nothing to hand it. Assign it a card. Note that an agent which has already commented on a card since the card last changed considers itself finished with it, and will not pick it up again until someone touches the row.
- It picks up a card and only comments
- Its tools are the board and nothing else. That is the default and it is right for a PM agent, whose work is judgement over Cruo data. A Dev agent needs --worktree and a widened --allow.
- It commits nothing, three times, then stops
- Three unproductive runs set a card aside for a human. Usually the brief has no acceptance criteria, so there is nothing for the agent to know it is finished against.
- Invalid token for Cruo projects
- Tokens open one product. The same message comes back for an unknown token and for a real token belonging to another product, deliberately — naming the other would confirm to whoever holds it that it is live. Check you took it from Projects.
Members shows whether a supervisor is alive at all, next to each agent — running, paused, stopped on purpose, or simply not heard from. If it says nothing has ever run, the process is not started, and no amount of workflow configuration will change that. On the machine itself, cruo ps answers the same question about processes rather than about agents.
Model Context Protocol
Connect Cruo to your agent
Three endpoints over Streamable HTTP. Bring a personal access token and any MCP client — nothing to install, nothing to run.
Three endpoints, three tokens
Cruo does not serve one combined MCP server. Each product has its own endpoint and its own token, so a credential you give an agent for your mindmaps cannot read every issue and file as well. A token presented to another product’s URL is refused.
Cruo Projects
Mint at Cruo Projects → Account → Developer
https://mcp.cruo.space/projects
Issues, projects, comments, labels and workspace members.
Cruo Drive
Mint at Cruo Drive → Settings
https://mcp.cruo.space/drive
Files and folders in your own drive — this token opens your drive, not your workspace's.
Cruo Mindmap
Mint at Cruo Mindmap → Settings
https://mcp.cruo.space/mindmap
Boards, cards and the connectors between them.
Setup
1. Mint a token
In the product you want to connect — the list above says where. Copy it immediately: Cruo stores a hash, not the token, so it is shown once and cannot be retrieved later. If you lose it, revoke it and mint another.
2. Add it to your client
Claude Code
One command per product.
-s userregisters it everywhere rather than in the current project only.claude mcp add --transport http -s user cruo https://mcp.cruo.space/projects \ --header "Authorization: Bearer cruo_pat_…"Codex CLI (OpenAI GPT)
A config file rather than a command: Codex documents no
mcp addform for an HTTP server. The token comes from an environment variable, which keeps it out of a file people share. Their docs, checked 2026-09-23.# ~/.codex/config.toml [mcp_servers.cruo] url = "https://mcp.cruo.space/projects" bearer_token_env_var = "CRUO_PROJECTS_TOKEN" # then, in the shell Codex runs from: # export CRUO_PROJECTS_TOKEN="cruo_pat_…"Gemini CLI (Google Gemini)
--scope usermatters: Gemini CLI’s default is the current project only. Their docs, checked 2026-09-23.gemini mcp add --transport http --scope user \ --header "Authorization: Bearer cruo_pat_…" \ cruo https://mcp.cruo.space/projectsGrok Build (xAI Grok)
Registers it for your user. Grok also reads an existing
.mcp.json, so the config below works there too. Their docs, checked 2026-09-23.grok mcp add --transport http cruo https://mcp.cruo.space/projects \ --header "Authorization: Bearer cruo_pat_…"Hermes Agent (Nous Research)
Hermes’ user guide puts this in
~/.hermes/config.yaml; its reference page namesmcp_config.yaml. Use the one your version reads. Hermes runs GPT, Gemini, Grok and open models alike, so it is also one way to use any of them. Their docs, checked 2026-09-23.# ~/.hermes/config.yaml mcp_servers: cruo: url: "https://mcp.cruo.space/projects" headers: Authorization: "Bearer ${CRUO_PROJECTS_TOKEN}" # then: export CRUO_PROJECTS_TOKEN="cruo_pat_…", and /reload-mcpCursor, VS Code, and anything else that reads an MCP config
The same shape everywhere — a URL and a header. This is also the
.mcp.jsonform Claude Code accepts if you prefer a file to a command.{ "mcpServers": { "cruo": { "type": "http", "url": "https://mcp.cruo.space/projects", "headers": { "Authorization": "Bearer cruo_pat_…" } } } }All three at once
Three separate entries and three different tokens. Swapping any two gets a refusal.
{ "mcpServers": { "cruo": { "type": "http", "url": "https://mcp.cruo.space/projects", "headers": { "Authorization": "Bearer cruo_pat_…" } }, "cruo-drive": { "type": "http", "url": "https://mcp.cruo.space/drive", "headers": { "Authorization": "Bearer cruo_pat_…" } }, "cruo-mindmap": { "type": "http", "url": "https://mcp.cruo.space/mindmap", "headers": { "Authorization": "Bearer cruo_pat_…" } } } }Clients that only speak stdio
Some clients cannot reach a remote server directly, or will only do so over OAuth. Bridge with
mcp-remote. Support here differs per client and changes quickly, so treat this as the fallback to try rather than the recommended path.npx mcp-remote https://mcp.cruo.space/projects --header "Authorization: Bearer cruo_pat_…"3. Reconnect the client
/mcpin Claude Code,/reload-mcpin Hermes, or restart Codex, Gemini CLI or Grok. Cruo’s endpoint is stateless and cannot push a tools-changed notification, so a client keeps the tool list it cached until you reconnect it — including after Cruo ships new tools.
Read-only, when that’s enough
Every endpoint has a /readonly twin that serves the reading tools and nothing else. Point an agent there when it should be able to look but not change anything — the writing tools aren’t hidden, they aren’t registered, so calling one is an unknown-tool error.
https://mcp.cruo.space/projects/readonly
https://mcp.cruo.space/drive/readonly
https://mcp.cruo.space/mindmap/readonly
Worth being precise about what this is: it restricts the endpoint, not the token. The same credential still reaches the full surface at the ordinary URL. It protects against an agent doing something you didn’t intend — not against whoever holds the token deciding to.
{
"mcpServers": {
"cruo-drive-readonly": {
"type": "http",
"url": "https://mcp.cruo.space/drive/readonly",
"headers": {
"Authorization": "Bearer cruo_pat_…"
}
}
}
}What to ask it
The agent acts as you, with your permissions — not as an integration with its own access. Anything it does shows up under your name, and anything you cannot see, it cannot either.
Projects
“What is assigned to me and still open? Move the two I finished to In Review.”
Reads and writes as you, under the same permissions — an agent cannot see a project you cannot.
Projects
“Summarise CRA and file issues for anything in the notes that has no ticket yet.”
Issues created this way carry your name, and the board shows them like any other.
Drive
“Find last quarter’s report in my drive and pull the revenue table into a new note.”
Reads file contents directly; large or binary files come back as a short-lived link.
Mindmap
“Turn this transcript into a board — one tree per decision, loose ideas off to the side.”
Cards are placed by the same layout code the app uses, so the result opens looking deliberate.
When it doesn’t work
- 401, “Invalid token for Cruo …”
- Usually the right token at the wrong path — tokens open ONE product. The message is deliberately the same for an unknown token and a real token for another product, so it cannot tell you which. Check the URL matches where you minted it.
- 401, “This token has been revoked.”
- It was revoked in that product's settings. Mint another.
- 429, with a Retry-After header
- Rate limited: 240 requests a minute from one address, 120 a minute per token. A refused credential counts far more heavily, so a loop of bad tokens is cut off after ten. Wait the number of seconds given.
- The tools don't appear after editing the config
- The client has to reconnect — /mcp in Claude Code. Cruo's endpoint is stateless and cannot push a tools-changed notification, so a client keeps the list it cached until you reconnect it.