Skip to main content
Two commands work without a terminal to draw into, so they are safe in pipelines and scripts where the TUI would refuse to start. cortex exec is the headless one: an autonomy ceiling, machine-readable output, turn and time limits, and a non-zero exit when anything goes wrong. cortex run is the one you type yourself: one prompt, one streamed answer, with sessions and sharing. This page covers which of the two to reach for, how autonomy works when there is nobody to answer an approval prompt, the output formats and what the result document contains, the limits you should always set, and the exit-code contract that a script has to respect. For pipeline recipes, see the CI cookbook. Both create a Cloud session unless CORTEX_COMPUTER or CORTEX_SSH_HOST selects another host. See Cloud, This PC, and SSH.

cortex exec

Give it a prompt

Autonomy

There is nobody to ask in a headless run, so the run’s authority has to be decided before it starts. --auto is that decision:
Start at read-only and raise the level only as far as the task genuinely needs. A review job never needs write access. In this build cortex exec accepts read-only and high only: --auto low and --auto medium stop the run before anything is submitted, with --auto low/medium (client risk thresholds) is not supported by the Code service contract. No turn was submitted. You can narrow the run further, independently of the level, by naming the tools it may use:
Tool names are case-sensitive, and --list-tools prints what a given run actually has. --enabled-tools and --disabled-tools are accepted only alongside --list-tools; on a run that submits a turn they stop it first, with --enabled-tools is not supported by the Code service contract. No turn was submitted. To narrow what a real run may do, set --auto and the [permission] table. See Tools the agent uses and Permission policy.
--skip-permissions-unsafe is declared on cortex exec but refused: it stops the run with --skip-permissions-unsafe is not supported by the Code service contract. No turn was submitted. It is also declared as conflicting with --auto, so the two cannot be passed together. There is no flag that removes permission checks from a headless run. Set the autonomy level you want, and pin the rest with the [permission] table.

Hooks are not approvals

A hook cannot stand in for your consent. No hook can approve a tool call, and adding a hook does not make a run more permitted than its policy allows. A hook is not a way to stop one either: hooks belong to a plugin and do not fire around the tool calls a run makes. What a headless run may do is decided by --auto, the tool allow and deny lists, and the permission policy, before the first turn. See Hooks and Permission policy.

Output formats

-o / --output-format:
--input-format selects how the prompt is fed in. It takes text, the default; stream-jsonrpc for the JSON-RPC protocol; and stream-jsonl for one JSON object per line, one line per turn, with no envelope or ids and the connection held open between turns. --response-format is accepted only as text, which is what it already is, and --output-schema is refused outright. When you need a validated result document, use -o json with --json-schema.

Add context

Limits

A turn is one complete request and response cycle with the model. Both defaults exist so a runaway run eventually stops, but in automation you should set them yourself: they are the difference between a failed job and a runner that hangs.

Other flags

A further set of flags is declared on cortex exec but refused before a turn is submitted, each with <flag> is not supported by the Code service contract. No turn was submitted.: --skip-permissions-unsafe, --output-schema, --max-tokens, --frequency-penalty, --presence-penalty, --stop, --logprobs, --n, --best-of, --user, --suffix, --spec-model, -i/--image, and --response-format or -r/--reasoning-effort with anything but their default. cortex exec --help lists what is declared; this page tells you which of it runs.

cortex run

cortex run streams a formatted answer into your terminal and understands sessions. It is the one to use when a person is reading the output.
cortex run also declares a set of flags it refuses before submitting a turn, each with <flag> is not supported by the Code service contract. No turn was submitted.: --share, --title, --port, --add-dir, --schema, --max-tokens, --retry, --no-cache, -t/--temperature, --top-p, --top-k, --seed, --frequency-penalty, --presence-penalty, --stop, --logprobs, --n and --best-of. --attach <URL> has its own message, --attach is not supported by this runtime. No local session was started. Sampling, retries and sharing are therefore not available from cortex run on this build. Global options that matter in a script: --color, -L/--log-level, --debug, -c/--config KEY=VALUE (repeatable) and -p/--profile.

Read the result

cortex run --format json prints one document:
Those four booleans are there so a parser can tell the cases apart: a run can fail, be interrupted, or be truncated, and they are not the same thing. cortex exec -o json prints the same idea with its own field names, including subtype, is_error, duration_ms and num_turns, so read the document your command actually produced rather than assuming a shared shape. Continuing a session across invocations is a matter of keeping the id:

Exit codes

A non-zero exit is the contract. Do not wrap a failing run in || true, or you have built a pipeline that cannot fail. Headless runs also fail closed when the coding service cannot be reached: the run prints The coding service is temporarily unavailable, exits non-zero, and never falls back to running a model locally.

Practices worth keeping

  1. Start at read-only and raise autonomy only when the task needs it.
  2. Always set --timeout and --max-turns in anything unattended.
  3. Use a JSON format whenever something downstream parses the output.
  4. Keep the transcript. -o stream-json ... | tee run.jsonl is your audit trail.
  5. Pass credentials through the environment, never on the command line. See Sign in to the CLI.