Docs

plori CLI

Install the CLI, complete browser login, run an agent, attach to a live session from the terminal, use JSON output in scripts, and keep API-key auth for CI.

The plori CLI creates and runs your cloud agents from a terminal or a script. It shares the same account, agents, and files as the web app and the MCP server.

Install and sign in

curl -fsSL https://plori.ai/install.sh | sh
plori login

The installer puts one static binary in ~/.local/bin. It needs no sudo and no Node, and it checks the download against the sha512 the npm registry publishes for that build. Re-run it to upgrade. It leaves your shell config alone, so if ~/.local/bin is not on your PATH yet, run the line the script prints (on macOS zsh, echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && exec zsh) before plori login. On Windows, irm https://plori.ai/install.ps1 | iex installs to %LOCALAPPDATA%\plori\bin and adds it to your user PATH for you; open a new terminal afterwards. If you would rather go through npm, npm i -g @plori/cli installs the same binary.

plori login opens the email-OTP page in your browser. A new email creates an account; an existing email signs back in. The CLI returns once the browser completes the sign-in.

The browser flow requests the openid offline_access mcp scopes and writes the credentials to ~/.config/plori/config.json (or $XDG_CONFIG_HOME/plori/config.json), file mode 0600. Stored fields: the public OAuth client id, a short-lived access token, a rotating refresh token, their expiry, and the granted scopes. The CLI refreshes the session automatically. plori logout clears the stored credentials.

For CI or headless environments, create an API key at Dashboard → Settings → API keys:

plori login --key plori_sk_…
# or, without writing a config file
export PLORI_API_KEY=plori_sk_…

First agent and first run

plori create mate
plori run mate "Research this topic and save the result to work/report.md"

create gets or creates by name, so running it again reuses mate instead of making a duplicate. run waits for the reply by default. For longer work:

plori run mate "Run the full test suite" --no-wait
plori result mate <run-id> --wait
plori run mate "Build it and stream progress" --follow

Long-running work

plori watch streams every run's ending, or its pause for human input, as one JSON line, until you stop it. Start a run in the background, then watch it end instead of polling:

plori run mate "Run the full test suite" --no-wait
plori watch --agent mate

plori inbox gives the same information without a long-running process: the runs that ended since your last acknowledgement, plus anything paused on you. plori run --jsonl replaces the rendered output with a streamed, machine-readable event log, and plori result --wait accepts --wait-seconds to bound how long it blocks.

Exit codes

plori run, plori result --wait, and plori watch report a run's outcome as an exit code.

code meaning
0 succeeded
1 API or runtime failure
2 usage error
3 missing, rejected, or expired credentials
4 could not reach the control plane
10 the run is awaiting human input
20 the run ended in error
30 the run was cancelled
40 a wait ran out with the run still going

Attach to a live session

plori attach mate

attach opens the agent's current session in your terminal: recent history, a prompt, output streaming as it arrives, and approvals answered in place. It is the same session the web app shows, so a turn sent from the terminal appears in an open browser tab live.

The argument is an agent name, an agent id, or a session id, so a session id copied out of the web app works on its own. --session <id> picks a specific session of an agent, --history <n> replays a different number of turns (20 by default, 0 for none, all for everything one request can carry, which stops at the newest 20,000 stored events), --read-only tails without a prompt, and --verbose also prints reasoning and tool results.

While attached, a line of text sends a turn, or steers the turn already running. Ctrl-C cancels that turn and a second press within two seconds leaves. Ctrl-D on an empty line, or /exit, detaches without stopping anything: the run keeps going on the server and you can attach again later. The slash commands are /sessions (list this agent's sessions), /new (start one), /model <slug> (change the model), /web (print this session's web address), /exit, and /help.

Approvals are answered with a single key: y or n, or a to say yes and stop being asked for that tool when the request carries a consent tool. A request for a value takes a line.

Attaching gives the agent nothing from your machine. The shell, the disk, and the files are the agent's own cloud environment, so nothing local is uploaded and nothing the agent writes appears in the directory you ran the command from.

Secret requests are read without echo and answered over the same connection, so a secret you type never appears on screen or in your shell history. If the terminal cannot hide the typing, attach refuses the secret and prints the web address to answer it at instead.

Scripts and automation

Every command accepts --json. Piping stdout switches to JSON automatically, so plori agents | jq . works without the flag. Progress and errors stay on stderr.

plori attach is the exception. It is a live stream rather than one result, so it always writes plain text, and it needs a terminal on both ends to show a prompt: redirect stdin or stdout and it becomes the same read-only tail --read-only asks for. That is why plori attach mate | tee session.log records a clean transcript instead of a prompt nobody can answer.

plori agents --json
plori credits --json
plori workflows list --json

Use plori schedule for one future agent turn and plori workflows for standing automations. Run plori help for the complete command list.

Workspace coordination (candidate)

Workspace commands require the unreleased candidate CLI, its matching server and an enabled account. Installing the current public CLI does not establish access to this candidate. The Workspace reference explains copies, manager selection, compatibility and recovery limits.

These commands use exact resource IDs. There is no implicit active Workspace. Copy IDs from the returned JSON into the variables shown below. Names do not replace IDs or idempotency keys.

Command group Operations
workspace Create, list, get or update a Workspace. Manage members, costs, retention and deletion.
independent-agent Create an execution identity without a Workspace or manager run. List account identities, including independent agents.
copy List or get copies, checkpoint a copy, clone a revision or delete a copy.
revision List, get or delete immutable saved revisions.
workspace-files List, stat or read a selected copy or revision. Write a copy with an ETag guard.
worker Spawn a worker, inspect its request or list workers.
task-group Create, list, get or stop groups. Read a group's costs.
changeset Submit, inspect, resolve, accept or reject proposed changes.
operation Get or wait for an asynchronous storage operation.
agent-stop, agent-retire Stop execution or retire an executor without deleting Workspace history.

Select copies and workers

Omit --manager when creating a Workspace to create a default manager identity, or use --manager ID to select an existing identity. Every Workspace has a manager. Creation does not start a manager run, and an external coordinator can leave the manager unused.

plori workspace create project --idempotency-key project-create-1
plori workspace get "$WORKSPACE_ID"
plori copy list "$WORKSPACE_ID"
plori copy checkpoint "$WORKSPACE_ID" "$COPY_ID" --idempotency-key checkpoint-1
plori operation wait "$WORKSPACE_ID" "$OPERATION_ID" --timeout 120
plori copy clone "$WORKSPACE_ID" --base-revision "$REVISION_ID" --idempotency-key clone-1

Wait for each returned storage operation to become ready before using its result. Select the ready proposal copy returned by cloning:

plori task-group create "$WORKSPACE_ID" --budget 2000000 --idempotency-key task-1
plori worker spawn "$WORKSPACE_ID" 'Update the selected files' --name proposal-worker \
  --copy "$PROPOSAL_ID" --task-group "$GROUP_ID" --idempotency-key worker-1
plori worker status "$WORKSPACE_ID" "$REQUEST_ID" --wait --timeout 600

--budget is a positive cache-weighted token limit shared by the group's workers. It is not a money amount. This single-worker example allows 2,000,000 tokens for admission, which reserves a full routed context window plus output. Increase the group limit for concurrent workers. Worker submission returns a request ID. Worker status reports the run result when available and its separate save/review state. Run completion does not prove that files are saved or accepted.

worker spawn requires either --name for a new executor or --executor for an existing one. Attach a separately created independent identity with workspace add-agent WORKSPACE_ID AGENT_ID before assigning work to it. For a follow-up, select the same --executor, its private --session and a ready --copy. Use answer for a human's actual decision and result for the returned successor run. Do not use legacy run to continue an independent Workspace worker.

Required keys and review guards

Use --idempotency-key for Workspace and independent-agent creation, copy clone, checkpoint or deletion, revision deletion, worker spawn, task-group creation and retention pins. Changeset submit, resolve, accept and reject also require keys. Retry with the same key and unchanged input. Use a new key for different input.

changeset submit requires --base-revision, --incoming-revision and --current-revision. Inspect the comparison before accepting. Supply its current revision as changeset accept --current-revision ID, with optional repeated --evidence TEXT flags. A stale revision response requires another review.

For conflicts, edit the integration copy with ETag guards, then use changeset resolve --generation N --resolutions @resolutions.json. Each resolution includes path, expected_etag and summary. JSON configuration and resolutions also accept inline JSON or @- for stdin.

Read and write files

plori workspace-files read "$WORKSPACE_ID" /notes.txt --copy "$COPY_ID" --json
plori workspace-files write "$WORKSPACE_ID" /notes.txt --copy "$COPY_ID" \
  --file ./notes.txt --if-match "$ETAG"

Read JSON includes the observed ETag. Inspect the old bytes before replacing them. Use --if-match 0 only to create a missing file. --file - reads stdin. A stale ETag fails instead of overwriting another edit. If the write returns HTTP 412 with current_etag, read the file again. Retry once with that ETag only if the content still matches what you read before editing. If the content differs, review the conflict before writing. See the Files write procedure.

--revision selects immutable files for list, stat or read. workspace-files read-bytes requires a revision and returns base64 JSON, with an 8 MiB limit. Text reads refuse binary files. This command does not implement mutable-copy binary download.

Inspect costs, retention and cleanup

plori worker list "$WORKSPACE_ID" --task-group "$GROUP_ID" --limit 25
plori workspace costs "$WORKSPACE_ID" --from 2026-09-01T00:00:00Z
plori task-group costs "$GROUP_ID"
plori workspace retention "$WORKSPACE_ID" --view pins

List copies, revisions, changesets, workers and task groups with --cursor and --limit. Continue with next_cursor. Cost reports have a separate resource page: continue it with --resource-cursor. A missing or null cost is unknown, not zero. A page of resource observations is not a complete total.

Retention expiry means eligibility for cleanup, not physical erasure. workspace pin requires --kind copy|changeset, --resource, --expires-at and an idempotency key. Pins require operator policy support. workspace unpin releases a pin. workspace update --retention-profile P --retention-version N adopts the operator's current policy for future copies and revisions.

agent-stop AGENT_ID and task-group stop GROUP_ID stop execution while preserving files and history subject to retention. agent-retire AGENT_ID prevents future assignments. You cannot retire or remove the current manager of a Workspace. First select another manager with workspace update --manager ID. Workspace deletion erases its files and history through asynchronous cleanup. Copy and revision deletion select only that resource.

Retirement, deletion and member removal require --yes outside a terminal or interactive confirmation. An accepted deletion does not prove physical erasure. Waited worker runs use the same exit codes as other runs, including human input, error, cancellation and timeout.

Use plori GROUP --help for each command's flags. Optional worker callbacks use --callback-url. Prefer PLORI_WORKER_CALLBACK_SECRET to --callback-secret, which can appear in process listings. Callback fields require server support.

Credits

plori credits shows the balance and prints a billing link when credits run low. Any command refused with HTTP 402 prints a billing link too. See pricing for plans and one-time credit packs.