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.