Contents
CLI Reference
The parel CLI deploys agents and works with them from a terminal or CI. It needs Node.js 22 or later. Run parel COMMAND -h to see the flags of any command.
npm install -g @parel/cli parel --version parel --help
| Task | Commands |
|---|---|
| Log in and settings | login, whoami, config |
| Deploy and release | deploy, run, try, versions, deployments, promote, rollback, agents |
| Run and watch | instances, sessions, send, chat, steer, logs |
| Workspace settings | secrets, provider-keys, api-keys, capabilities, billing |
There is no channels command: declare channels in agent.yaml or use the HTTP API.
# Log in
Create an API key in Settings → API keys, then run parel login. It checks the key with the server and saves it, together with the server URL, in ~/.parel/config.json (readable only by you). It asks for the key, or takes it from --key or from stdin.
parel login # API key: pk_your_key_here # Logged in. https://api.parel.sh pk_your...here parel login --key pk_your_key_here echo "$PAREL_KEY" | parel login parel whoami parel config set --server https://api.parel.sh --key pk_your_key_here parel config show
parel whoami shows the server, the start of the key, and whether the key works (authenticated, invalid_key or unreachable). parel config set writes the server or key into the saved file without checking them; parel config show prints the file with the key shortened. In CI, skip the file and set PAREL_API_KEY instead.
# API key scopes
Every API key has one of three scopes. The server checks it on each request, so a command fails with a 403 when the key isn't allowed to do what it asks.
| Scope | What it allows |
|---|---|
| Read | List and read only: agents, versions, instances, sessions, messages, logs, billing. Can't deploy, start sessions, send messages or chat. |
| Write | Everything Read allows, plus deploy, promote and roll back, change agents and instances, create sessions, send, chat and steer. Keys get this scope unless you pick another. |
| Admin | Everything Write allows, plus creating and deleting API keys, setting model provider keys and secrets, and changing billing. |
Commands that need an Admin key: api-keys create and delete, provider-keys set, unset and delete, secrets set and unset, and capabilities setup. Listing API keys, provider keys and secrets works with any key.
# Server, output and environment
| Flag or variable | Description |
|---|---|
| --server URL | Use this server for one command. Every command that calls the server accepts it. |
| PAREL_SERVER | Server to use when there is no --server flag. It wins over the server saved by parel login. |
| PAREL_API_KEY | API key to use. It wins over the key saved by parel login. |
| --json | Print one line of JSON instead of tables and text. Errors are printed as a JSON object with an error field. Every command has it except chat. |
| PAREL_JSON=1 | Same as --json, for every command. |
| NO_COLOR=1 | Turn off colors. They are also off when the output isn't a terminal. |
Without --server or PAREL_SERVER, the CLI uses the server saved in ~/.parel/config.json, or https://api.parel.sh if none is saved. It refuses plain http:// except for localhost and 127.0.0.1.
# Exit codes
| Code | Meaning |
|---|---|
| 0 | Success. |
| 1 | A problem on your side: a bad or missing flag, a file that doesn't exist, not logged in, an insecure server URL, or a network error. |
| 2 | The server answered with an error, or the turn ended with an error. |
| 3 | No reply before the timeout (send, run, try). The session keeps going; its id is in the output. |
| 4 | Not ready: capabilities doctor or --require-ready found a missing key or secret. |
# parel deploy
Deploys an agent.yaml. The file must have agent.name: a new name creates the agent, an existing name adds a new version and makes it live. Sessions that follow the live version switch to it at their next turn.
parel deploy agent.yaml # Deployed: my-agent v1 agt_a1B2c3D4e5F6 # Same name again: a new version, live right away parel deploy agent.yaml # Deployed: my-agent v2 agt_a1B2c3D4e5F6 # Staged: uploaded, not live parel deploy agent.yaml --no-activate parel deploy agent.yaml --require-ready --secret E2B_API_KEY=e2b_your_key
| Flag | Description |
|---|---|
| --no-activate | Upload a new version without making it live. Try it with parel try --version, then make it live with parel promote. The first version of a new agent is always live. |
| --require-ready | Run capabilities doctor first and stop with exit code 4 if a key or secret is missing. |
| --secret NAME=value | Value for one ${NAME} reference, used instead of the environment variable. Repeat the flag for more names. The name must appear in the file. |
| --json | Print the server's answer as JSON: agent id, version, whether it is live, the names of uploaded secrets, and a result for each declared channel. |
Secret values travel with the deploy. For every ${NAME} in model.config or in a plugin's config, the CLI takes the environment variable with the same name (or the --secret NAME=value flag) and uploads it encrypted, stored for this agent only. Names you don't have locally are looked up in the secrets already stored for this agent or the workspace. If one is missing everywhere, the deploy fails and says what to set.
--no-activate) of an existing agent never sends secret values: the new version uses the values already stored. If a referenced secret isn't stored yet, the CLI stops before deploying and prints the parel secrets set command to run. --secret can't be combined with --no-activate.# parel run
Deploy, send and wait in one command, for scripts: it deploys the file and makes it live, opens a new session, sends one message and prints the reply.
parel run agent.yaml -m "What's trending today?" echo "Summarize this" | parel run agent.yaml --stdin --require-ready --timeout 180 --json
| Flag | Description |
|---|---|
| -m, --message TEXT | The message to send. |
| --stdin | Read the message from stdin. |
| -t, --timeout SECONDS | How long to wait for the reply, in seconds (default 120). Exit code 3 when it runs out. |
| --require-ready | Run capabilities doctor first and stop with exit code 4 if a key or secret is missing. |
| --secret NAME=value | Value for one ${NAME} reference, used instead of the environment variable. Repeat the flag for more names. The name must appear in the file. |
| --json | Print a JSON result: session id, status, the reply text, tool calls and any error. |
# parel try
Runs one throwaway turn on a temporary instance, so it doesn't touch any instance's sandbox, instance store or vars; it sees only the agent's default vars. With --version it runs that version, even one that isn't live, without changing what is live. For a conversation, use parel chat.
parel try my-agent -m "Say hi" parel try my-agent --version v4 -m "Run the new prompt" --json
| Flag | Description |
|---|---|
| -m, --message TEXT | The message to send (required). |
| --version VERSION | Version to run: v4, 4 or a version id. Without it, the live version. |
| -t, --timeout SECONDS | How long to wait for the reply, in seconds (default 120). Exit code 3 when it runs out. |
| --json | Print a JSON result: session id, status, the reply text, tool calls and any error. |
# parel send
Sends one message, waits for the reply and prints it. With --agent it opens a new session every time; pass --session to continue one. With --async it returns as soon as the message is accepted.
parel send --agent my-agent -m "Summarize this repo" parel send --session <session-id> --stdin < notes.txt parel send --agent my-agent -m "Start the job" --async parel send --agent my-agent -m "Return JSON" --json
| Flag | Description |
|---|---|
| --agent NAME|ID | Agent name or id. Opens a new session in the agent's main instance. |
| --session ID | Id of an existing session to continue. |
| -m, --message TEXT | The message to send. |
| --stdin | Read the message from stdin. |
| --async | Don't wait for the reply: print the session id and exit. With --json, the server's answer is printed too. |
| -t, --timeout SECONDS | How long to wait for the reply, in seconds (default 120). Exit code 3 when it runs out. |
| --json | Print a JSON result: session id, status, the reply text, tool calls and any error. |
# Versions, promote and rollback
Every deploy adds a numbered version, and one version is live at a time. promote and rollback only change which version is live; nothing is uploaded.
parel versions list my-agent # * marks the live version parel deployments list my-agent # when each version went live parel promote my-agent --version v4 # v4, 4 or a version id parel rollback my-agent # back to the version live before parel rollback my-agent --to v2
# parel agents
Every command accepts an agent's name or id. update deploys a file as a new live version of that agent, whatever agent.name the file has. rename keeps the id, versions and sessions. get prints the agent as JSON.
parel agents list parel agents list --json parel agents get my-agent parel agents update my-agent --file agent.yaml parel agents rename my-agent new-name parel agents delete my-agent
# parel instances
An instance is a long-lived copy of an agent with its own state (sandbox, instance store) and its own vars. Every agent has a main instance; a session opened with --instance KEY creates that instance the first time. Keys are 1 to 64 characters of lowercase letters, digits, dots, dashes and underscores, starting with a letter or digit.
parel instances list my-agent parel sessions create my-agent --instance customer-a # first use creates it parel instances vars my-agent customer-a --set CUSTOMER=Acme --set LANGUAGE=German parel instances vars my-agent customer-a # no --set: clear all vars parel instances pin my-agent customer-a --version v3 parel instances unpin my-agent customer-a # follow the live version again parel instances reset my-agent customer-a parel instances delete my-agent customer-a
vars sets the values for ${var:NAME} references and replaces the whole set each time. pin holds the instance on one version until unpin. reset wipes the instance's state but keeps its sessions. delete fails while the instance still has live sessions. Default vars shared by all instances have no CLI command yet; see the agent.yaml reference.
# parel sessions
create opens a session; add --instance to use a named instance. list shows the 20 most recently active by default. Its --agent filter takes the agent's name or id, and --status takes running, ready, suspended, completed, error, timeout, provisioning, initializing or terminated. messages prints the conversation.
parel sessions list parel sessions list --agent agt_a1B2c3D4e5F6 --status running --limit 50 parel sessions create my-agent parel sessions create my-agent --instance customer-a parel sessions get <session-id> parel sessions messages <session-id>
# parel chat
A chat in your terminal, streamed over WebSocket. --agent (name or id) opens a new session; --session continues one. It needs a Write key. Tool calls and their results show up as short [tool] and [result] lines.
parel chat --agent my-agent parel chat --session <session-id> # Inside chat: $ hello ▸ Hi! How can I help? $ /messages # print the conversation so far $ /help # list the session's slash commands $ /quit # exit
/messages, /quit and /exit are handled by the CLI. Any other /name goes to the session: /help lists the session's commands, plugins add their own (for example /compact from memory-rolling-summary), and an unknown name prints a warning and is sent as a normal message.
# parel logs
Prints a session's events (turns, steps, commands, snapshots) and its log records (model calls, tool calls and other runtime records), oldest first. It reads every page of events; a session keeps a window of recent events, and the output says when older ones are gone. With --json it prints {events, logs}.
parel logs <session-id> parel logs <session-id> --json
# parel steer
Sends a message into the turn that is running: the model sees it at its next step instead of after the turn ends. If no turn is running, the message starts one. It is the same as POST /sessions/ID/messages with injectInFlight: true.
parel steer --session <session-id> "Focus on AI posts only"
# parel secrets
Named values that agent.yaml uses as ${NAME}. Names are UPPER_SNAKE_CASE. A value is shared by the whole workspace unless you pass --agent with an agent name or id; an agent's own value wins over the workspace value. set reads the environment variable with the same name unless you pass --from-env OTHER_NAME or --stdin. list shows names, scope and a masked preview, never the full value. Setting and removing need an Admin key.
parel secrets list parel secrets set E2B_API_KEY # value from $E2B_API_KEY parel secrets set GH_TOKEN --from-env GITHUB_TOKEN printf '%s' "$TOKEN" | parel secrets set GH_TOKEN --stdin parel secrets set E2B_API_KEY --agent agt_a1B2c3D4e5F6 # this agent only parel secrets unset E2B_API_KEY parel secrets unset E2B_API_KEY --agent agt_a1B2c3D4e5F6
Values that parel deploy uploads from your shell are stored for that one agent. Use secrets set for values several agents share, for channel connections, or when CI doesn't have the variable.
# parel provider-keys
Your workspace's own model keys. PAREL doesn't supply model keys, so an agent's model needs a key here, or an apiKey in its model.config. The provider name is the agent's credential provider: anthropic, openai, or the credentialProvider you set for a compatible endpoint, such as openrouter or deepseek (lowercase letters, digits and dashes). Setting a provider again replaces its key. set needs exactly one of --from-env or --stdin. Changes need an Admin key.
parel provider-keys list parel provider-keys set anthropic --from-env ANTHROPIC_API_KEY parel provider-keys set openrouter --from-env OPENROUTER_API_KEY parel provider-keys set deepseek --stdin < deepseek.key parel provider-keys unset deepseek # by provider name or key id parel provider-keys delete pvk_a1B2c3D4e5F6 # by key id
# parel api-keys
Lists, creates and deletes the workspace's API keys. create prints the new key once, so save it right away. Creating and deleting need an Admin key.
parel api-keys list parel api-keys create ci-deploy parel api-keys create dashboards --scope read parel api-keys delete key_a1B2c3D4e5F6
--scope read|write|admin picks the new key's scope; without it the key gets Write. list shows each key's scope. You can also create keys under Settings → API keys in the console.
# parel capabilities
Checks, before you deploy, that an agent has the keys and secrets it needs. list and explain work offline from a built-in list: model.anthropic, model.openai, sandbox.e2b, memory.rolling-summary, budget.cap, security.basic, system.static, steering.immediate and subagent.
parel capabilities list parel capabilities explain sandbox.e2b parel capabilities doctor agent.yaml parel capabilities doctor agent.yaml --secret E2B_API_KEY=e2b_your_key --json parel capabilities setup model.anthropic --from-env ANTHROPIC_API_KEY parel capabilities setup sandbox.e2b --from-env E2B_API_KEY
doctor reads an agent.yaml without deploying it. It checks the model key and every ${NAME} reference against your shell, --secret flags and the workspace's stored keys and secrets (values stored for a single agent aren't checked), and exits with code 4 when something is missing. setup stores the one key a capability needs: a provider key for model.*, or a workspace secret named E2B_API_KEY for sandbox.e2b. It needs an Admin key and exactly one of --from-env or --stdin.
# parel billing
plan shows your plan and this month's usage: steps, connection-days, overage, spend cap, and whether the limit was reached. summary shows total tokens and an estimate of model spend, which you pay to your model providers directly.
parel billing plan parel billing summary