Loom keeps your agents on track.

Set up Loom and connect more computers

loom setup signs you in, provisions your stores, writes ~/.loom/stores.toml and configures your coding harnesses (when stores.toml already holds your credentials for the server it skips the sign-in), and loom login signs in on another computer without touching any harness.

loom setup#

Run it once per computer after installing the CLI:

loom setup

What it does#

  1. Finds your harnesses. It looks for the codex, claude and opencode executables, shows what it found with all selected by default, and lets you opt out. If none is found, loom setup stops at once with no supported harness found on this machine (looked for: codex, claude, opencode). Install one and re-run. (exit 2); it asks nothing and writes nothing. On such a computer use loom login instead. Selecting a harness that is not installed, for example --harness claude with claude absent, also fails with not installed on this machine: claude. ... (exit 2).
  2. Signs you in, unless it already holds your credentials. If ~/.loom/stores.toml has a section with a store_key for the server setup resolved (see Choosing the server), it skips steps 3 to 6, prints Using your existing Loom stores for <server>; run loom login to sign in again. (for a server other than https://loomcloud.ai the command reads loom login --base <server>) and goes straight to the harnesses. Nothing is requested from the server and stores.toml is not rewritten, so a store created on the server since then is not added; run loom login for that. A section counts for a server when its web_origin is that server; a section with no web_origin counts for https://loomcloud.ai only. A section without a store_key, or one recorded for another server, does not count, and setup signs in as described below. loom login never skips: it always signs in.
  3. Asks for your email address and consent. First your email address, then it shows the Privacy Policy and Terms of Service as links and requires you to type I agree at Type 'I agree' to accept the Privacy Policy and Terms of Service:. There is no flag that bypasses this.
  4. Sends a sign-in code. It prints If that address can receive mail, a sign-in code is on its way., then asks for the code at the hidden prompt Verification code (hidden):. The code never goes on the command line.
  5. Waits for provisioning. It polls the server every 2 seconds for up to 120 seconds. A single status request that times out is treated as "still provisioning" and polling continues. On a first sign-in the CLI keeps waiting until all the starter stores (coding, loom_demo and kanban) exist, so one run gives you every one of them; you do not need to run loom login a second time to get kanban. While it polls the command prints nothing. If the 120 seconds pass first, the command stops with provisioning is taking longer than expected; run login again with the same email to check status -- it is safe to retry (exit 2).
  6. Writes ~/.loom/stores.toml. New sections are merged by name; an existing section is never rebound to a different store, and a top-level default is added only if none exists. If the server's list has two sections with the same name, the first (the oldest store) is kept, the other is skipped and a warning goes to stderr (see Re-running and updating). The file is written atomically with user-only permissions. See What stores.toml holds.
  7. Installs and verifies each selected harness from the plugin marketplace of the server you signed in to (<server>/loom-plugins.git; on the hosted service that is https://loomcloud.ai), then prints a per-harness result and the restart each one needs.

On a sign-in the line Loom store(s) coding, loom_demo, kanban configured in /home/<you>/.loom/stores.toml. (the full path of your stores.toml) is printed once the stores are written (a setup that skips the sign-in prints the Using your existing Loom stores line instead and no configured in line); with a harness it is followed by one result row per harness (loom login prints it last). The CLI prefixes its messages with loom setup: or loom login:; the examples here omit the prefix.

With a harness present and --harness given (tested for claude and codex against a private server), the run ends with one result row per harness, for example:

Loom store(s) coding, loom_demo, kanban configured in /home/<you>/.loom/stores.toml.

claude    installed and verified
          Claude Code: start a new session so the Loom MCP server picks up the new store entry; an already-running session will not see it until restarted.

From v0.672, installed and verified for Claude Code also means claude mcp list shows the Loom MCP server connected, and for Codex that its uv command is found; if the plugin is installed but its MCP server is not running (typically uv not on PATH), the row is FAILED -- ...its MCP server is not running (<reason>)... and the other harnesses are unaffected. See Claude Code. If claude mcp list does not answer within 30 seconds the row stays verified and carries a note that the start could not be confirmed.

For Codex the note reads: restart the CLI (or run codex again) so it re-reads ~/.loom/stores.toml, then re-trust this workspace if Codex prompts for it.

When several harnesses are installed and you pass no --harness, the prompt comes before the email prompt:

Select your harness:
Detected harnesses: codex, claude
Install Loom for all of these? [Y/n or comma-separated names]: 

Sign-up is open on the hosted service and on a private server: anyone who can receive the email code and accepts the Terms gets an account.

Options#

OptionMeaning
--harness codex, --harness claude, --harness opencodeSelect a harness without the prompt. Repeat to select several.
--jsonOn success, print exactly one JSON result on stdout; prompts and progress go to stderr. A failure prints one JSON object on stdout, {"status": "error", "detail": "<message>"} (exit 2), or {"status": "cancelled", "detail": "<message>"} for a cancellation such as declined consent (exit 1); the same message also goes to stderr. Closed input and Ctrl-C (below) print no JSON. For loom login the success JSON is {"path": "<full path to stores.toml>", "status": "ok", "store_names": ["coding", "loom_demo", "kanban"]}. For loom setup it has stores_toml_path (not path), store_names, harnesses, harness_results (one object per harness with ok, verified, action, error, restart and more) and status, which is ok or, with exit status 3, partial. Neither contains keys.
--base URLThe server to talk to. For loom setup it also decides where the plugins come from: <server>/loom-plugins.git.
--mode privateRun the private single-host server lifecycle instead (see below).

hosted-setup is an older spelling of loom setup and behaves identically. Neither accepts --help yet: loom setup --help prints loom setup: unknown argument '--help' (exit 2). A later release answers loom setup --help.

Choosing the server#

For loom setup the server is chosen in this order:

  1. --base.
  2. The server recorded in ~/.loom/stores.toml, when the file has exactly one store section and that section has a web_origin.
  3. The LOOM_WEB_BASE environment variable.
  4. https://loomcloud.ai.

The recorded server in step 2 matters on a computer whose stores.toml holds only one pasted section, for example a single [kanban] section from a private server. After a normal sign-in the file has three sections, so a re-run uses steps 3 and 4 unless you pass --base. The server that wins is used both for sign-in and for the plugin install. If the recorded web_origin is not a valid server address, setup stops before asking anything:

stores.toml section '<name>' has an invalid web_origin

(exit 2, with the loom setup: prefix). loom login has no recorded-server step: it uses --base, then LOOM_WEB_BASE, then https://loomcloud.ai. https is required, except that plain http is accepted for a private-range IP address (10/8, 172.16/12, 192.168/16, 100.64/10, fc00::/7).

loom setup --base https://loom.example.com

Exit status#

CodeMeaning
0OK
1Cancelled (for example you declined consent)
2Error (including no supported harness found, and no terminal to prompt on)
3Partial result: something was not fully set up
130Interrupted with Ctrl-C

Automation should read the exit code before the JSON payload.

Over plain http (a private server addressed by IP) the plugin marketplace is not served, so loom setup completes the store setup, skips the Claude Code and Codex plugin install, prints Plugins need an https server: the Loom plugin marketplace is not served over http, so the claude/codex plugin install was skipped. Your store is set up. and exits 3. The harness row reads claude skipped (plugins need an https server), and in the JSON result that harness has action: "skipped" and ok: false, with status: partial. With --json the message goes to stderr.

If a harness already has a loom marketplace installed from a different server, setup does not change it: that harness shows FAILED -- <harness>: the existing Loom marketplace comes from <source> but this setup is for <server> ... so nothing was changed, followed by the commands to remove it deliberately and add it again with loom setup --base <server>. The exit status is 3 and the stores are still written.

When a harness fails to install or verify (tested with a stand-in harness), the exit status is 3, stderr shows a row such as claude FAILED -- <reason> followed by the restart note, the JSON status is partial, and stores.toml is still written.

Not tested with a genuine mid-install failure on a real harness; only a stand-in harness was used.

Re-running and updating#

Setup is idempotent. Running it again re-discovers your harnesses, upgrades or configures each selection independently, and re-verifies it; a failure in one harness does not hide the others.

loom login always asks for your email address, consent and a fresh sign-in code, even when stores.toml already has the sections. loom setup asks only when stores.toml holds no credentialed section for the server it resolved (step 2 above); otherwise it keeps your stores and only re-checks the harnesses. When a sign-in runs against an existing file, the file is not rebound: a section bound to a different store is never replaced:

stores.toml already binds [kanban] to a different store; refusing to replace it. Remove or rename that section first.

That refusal exits with status 2. It also applies when the incoming section carries no store line while your existing section is bound to a store. Remove or rename the conflicting section, then run the command again.

If your account lists two stores that would get the same section name, the command keeps the first (the oldest), leaves the other out of the configured in line and of the JSON store_names, prints this warning on stderr, and still exits 0:

Warning: store <handle> was not configured locally: its section name [<name>] is already used by another of your stores and it needs a distinct alias.

After setup#

Follow the printed restart instructions, then start a fresh agent session. The per-harness steps are:

HarnessAfter setup
CodexRestart the CLI so it re-reads ~/.loom/stores.toml; re-trust the workspace if prompted.
Claude CodeStart a new session; a running session will not see the new store entry.
OpenCodeRestart OpenCode, or reload its MCP servers.

loom login: connect a second computer#

loom login runs the same sign-in and provisioning flow but installs nothing in any harness:

loom login

Use it to:

  • bring the same stores to another computer: install the CLI there, run loom login with the same email address, and enter the new code. You get the same stores and the same keys as on the first computer;
  • restore access after logout or after losing ~/.loom/stores.toml.

The prompts come in this order: email address, consent (the Privacy Policy and Terms of Service as links, then Type 'I agree' to accept the Privacy Policy and Terms of Service:), the line If that address can receive mail, a sign-in code is on its way., then Verification code (hidden):. It accepts --json and --base URL with the same meaning as above (the server is --base, else LOOM_WEB_BASE, else https://loomcloud.ai; loom login does not read stores.toml to pick it), prints the same success line as loom setup, and merges into an existing stores.toml: your other sections and a different default are preserved. Then run loom setup on that computer if you also want a harness configured.

What stores.toml holds#

After a first sign-in ~/.loom/stores.toml has mode 0600 on POSIX systems, default = "coding", and the sections [coding], [loom_demo] and [kanban]. Each section has endpoint, store (named u<id>_<name>), namespace_scheme (loom-8), server_key, store_key, description and web_origin (the server you signed in to). The two key values are credentials: never print or share them.

Logging out#

loom logout --params '{"section":"NAME"}'

Run it once per section; the other sections stay in stores.toml. loom logout alone fails with missing a required argument: 'section' (exit 2), and --store is rejected.

Logging out of the default section also removes the top-level default line. The other sections stay, and no default is set until the next loom login. If the account no longer has a coding store on the server (for example you dropped it), loom login does not add a default again and every loom command fails with `must set top-level default = "<store>" ; add the line default = "kanban" (or another section you have) to stores.toml yourself. Logging out of a section that is not configured prints {"status":"error",...,"detail":"no store named 'X' is configured in stores.toml; nothing to log out of"}` and exits 3.

Private server setup#

Not verified: which action runs when --action is omitted, so pass it explicitly.

Troubleshooting#

  • loom setup: unknown argument: that verb accepts only the options listed above.
  • No harness detected: loom setup exits 2 without asking anything. Install Claude Code, Codex or OpenCode, open a new terminal and re-run, or use loom login if you only need the stores.
  • CERTIFICATE_VERIFY_FAILED on a private server: trust the server certificate first; see Connect clients.
  • Trial capacity is currently full. Please try again later. (exit 2): the hosted service has no room for new trial accounts right now. It is the same message the website shows; try again later.
  • provisioning is taking longer than expected (exit 2): the server was still creating your stores after 120 seconds. Run the command again with the same email; it is safe to retry.
  • Code never arrives or expired: start loom setup (or loom login) again and use only the newest code. If the server throttled the request you get the too many sign-in code requests message above instead of waiting for a code.
  • that code or link is not valid (exit 2) with a correct code: use the newest code only; an older code stops working when you request another. Against a server older than v0.674, roughly 8 code requests in a few minutes also made a correct code fail this way, with no mention of the throttle: wait 5 minutes, request one code and use the newest. A v0.674 server says too many sign-in code requests instead.
  • no input available (stdin is closed or not a terminal); run it from an interactive terminal (exit 2): setup or login needs to prompt (email, consent, code) but its input is closed or is not a terminal, or you pressed Ctrl-D. It is one line, not a traceback. Run it from an interactive terminal; when stores.toml already holds your credentials for the server, loom setup needs no email or code prompt.
  • loom setup: interrupted; anything already sent to the server may have completed. Re-running loom setup is safe. (exit 130; loom login says the same with its own name): you pressed Ctrl-C. Nothing is written to stores.toml before the sign-in finishes; re-run the same command.
  • too many sign-in code requests for this address; wait a few minutes and run it again (exit 2): the server throttled the code request and sent no email. Wait a few minutes, then run it again and use only the newest code.
  • Never put a code, grant or credential in a command line, a log or a public issue.