The Qoren command line
Install the Qoren CLI, sign in from your terminal, and drive environments, agents and jobs from scripts and CI with JSON output and clear exit codes.
On this page
- Before you start
- Install the CLI
- Sign in
- Check who you are signed in as
- Sign out
- Use more than one login
- Use interactive mode
- Read output in a script
- Exit codes
- Follow long-running work
- Choose a size and a region
- Set environment variables
- Run the CLI in CI
- Call an endpoint that has no command
- Frequently asked questions
qoren does from a terminal what the console does in a browser: create environments, deploy and message agents, read logs, and check what you are spending. Use it when you want to script your fleet, run it from CI, or simply stay in the terminal you already have open.
The CLI is not a side door. It sends every request through the same gate the console uses, which checks who you are and what your plan allows. So it can do exactly what your account can do in a browser, and nothing more. For the full list of commands and flags, see the Qoren CLI command reference.
Before you start#
- Node.js 20 or newer.
- A Qoren account on a plan that includes API access: Ultimate, Business or Enterprise (a free trial of one of them counts). The CLI signs in with an access token, and tokens are API access, so on Starter, Pro or with no plan every command is refused and exits with code 4. The web console works on every plan. See plans and the free trial.
Install the CLI#
npm install -g @qoren/cli
qoren --versionThe package puts one command on your path: qoren.
Sign in#
- Run
qoren login. Your browser opens a Qoren page titled Connect the Qoren CLI. If it does not open, the terminal prints the link to visit. - Check the page. It shows who you are Signing in as, the Token name, and the local address it is Returning to.
- Click Authorize. Nothing is granted until you do. If your plan does not include API access, the page says so instead and links to an upgrade.
- Back in the terminal, the CLI checks that the new token works, stores it, and prints who you are signed in as.
The CLI waits up to five minutes for you to approve. If you take longer, run qoren login again. The token it creates shows up in the console under Settings, CLI tokens, named cli unless you choose a name:
qoren login --name laptopOn a computer with no browser, create a token in the console instead (see create and revoke access tokens) and paste it. The prompt does not echo what you type:
qoren login --tokenCheck who you are signed in as#
qoren whoamiIt prints the profile, the server, your account, your organization, where the credential came from (the config file or QOREN_TOKEN) with the first characters of the token, and whether the server accepted it. If the token is fine but your plan does not include API access, the status says so and names the plans that do. The token itself is never printed, so the output is safe to paste into a bug report.
Sign out#
qoren logout # forget the current profile
qoren logout --all # forget every profile on this computerSigning out only deletes the copy on this computer. The token still works until you revoke it under Settings, CLI tokens.
Use more than one login#
Each login is stored as a named profile, so you can keep several side by side and pick one per command:
qoren login --profile work
qoren env ls --profile work
QOREN_PROFILE=work qoren env lsThe most recent login becomes the default.
Use interactive mode#
Run qoren with nothing after it and it opens full screen: your environments, agents, jobs, a chat pane and your account, all on the keyboard. qoren tui does the same thing explicitly.
| Key | What it does |
|---|---|
tab, shift+tab | Next or previous section |
1 to 5 | Jump to Environments, Agents, Jobs, Chat or Account |
arrow keys, j, k | Move within a list |
enter | Open what is selected |
r | Refresh |
? | Every key for the section you are in |
q or ctrl+c | Quit |
Two things it does that a single command cannot. When you message an agent, the reply streams in as the agent writes it, naming the tool it is running. And when a region cannot run the size you asked for, it offers you the closest region that can, instead of telling you which flag to add.
Interactive mode uses the same account and the same plan limits as the commands. Anything it cannot do yet, the commands still can.
Read output in a script#
Every command takes --json. In that mode stdout carries only the result, as JSON. Progress, notes and warnings go to stderr, so piping into another tool is always safe, even for commands that follow a long job.
qoren env ls --json | jq -r '.[].name'
qoren agent ls --json | jq -r '.[] | select(.status != "running") | ._id'Errors are structured in --json mode too, written to stderr:
{
"error": "No active subscription.",
"detail": null
}When the server sent a structured refusal, detail carries it. A plan without API access, for example:
{
"error": "Your Pro plan does not include API access. It is included on the Ultimate, Business and Enterprise plans. Personal access tokens, the CLI and the SDK need one of them: upgrade at https://qoren.sh/pricing. The web console keeps working on every plan.",
"detail": {
"code": "api_access_required",
"plan": "pro",
"plans": ["Ultimate", "Business", "Enterprise"],
"upgradeUrl": "https://qoren.sh/pricing"
}
}Colour switches off by itself when output is not a terminal, and with --no-color or the NO_COLOR variable.
Exit codes#
| Code | Meaning | What to do |
|---|---|---|
| 0 | Success | Nothing |
| 1 | The request failed | Read the error message; it came from the server |
| 2 | The command was typed wrong | Check the arguments and flags with --help |
| 3 | Not signed in, or the credential was refused | Run qoren login, or check QOREN_TOKEN |
| 4 | The plan does not allow this: no active plan, or a plan without API access | Choose or upgrade a plan in the console, then run it again |
Keeping 3 and 4 apart from 1 lets a CI job tell "my token was revoked" from "that environment does not exist" from "the plan does not cover this". Two commands also exit 1 on their own result: qoren agent exec when the command it ran exits non-zero, and qoren agent doctor when the checkup needs attention or fails.
Follow long-running work#
Creating an environment, deploying an agent, resizing, removing and messaging are all jobs: the server answers straight away with a job id and does the work in steps. By default the CLI follows the job and prints one line for each step as it starts, so a deploy that takes minutes shows where it has got to. If the connection drops for a moment, it prints reconnecting… once and keeps waiting.
To get the job id back immediately instead, add --no-wait, then follow the job later:
JOB=$(qoren env create --name staging --size s-1vcpu-2gb-70gb-intel --no-wait --json | jq -r .jobId)
qoren jobs watch "$JOB"qoren jobs ls lists recent jobs with how many steps are done, qoren jobs get <id> prints every step and the error if one failed, and qoren jobs cancel <id> asks a running job to stop (a step already running finishes first).
Choose a size and a region#
--size takes the size's slug, the value in the slug column of qoren account options. Today the four plan sizes are:
| Size | Slug |
|---|---|
| Light | s-1vcpu-2gb-70gb-intel |
| Standard | s-2vcpu-2gb-90gb-intel |
| Heavy | s-2vcpu-4gb-120gb-intel |
| Max | s-4vcpu-8gb-240gb-intel |
Your plan sets the largest size you may use. See environment sizes for how many agents each one holds and what it costs.
Leave --region off and the platform picks a region that can run the size you asked for. Name a region and it is pinned: a region you chose is never swapped for another. If it cannot run that size, the create is refused, and the message names the closest region that can plus the sizes your region does have. Run the command again with --auto-region to accept the suggested region, or with one of the listed sizes.
qoren env resize is refused the same way when the environment's region cannot run the new size. An environment cannot change region, so pick one of the sizes the message lists. Resizing only goes up, and it restarts the environment, so its agents are unreachable while it runs.
Set environment variables#
| Variable | Effect |
|---|---|
QOREN_TOKEN | The token to use. The config file is not read at all |
QOREN_API_URL | The server to talk to (default https://qoren.sh) |
QOREN_PROFILE | Which stored login to use |
XDG_CONFIG_HOME | Where the config file lives |
NO_COLOR | Turn colour off |
When several apply, QOREN_TOKEN wins, then --api-url, then the named profile. Stored logins live in ~/.config/qoren/config.json (or $XDG_CONFIG_HOME/qoren/config.json), readable only by your user.
Run the CLI in CI#
Create a token for the pipeline under Settings, CLI tokens (see create and revoke access tokens), store it as a secret, and expose it as QOREN_TOKEN. It overrides any stored login, so a pipeline never picks up a developer's profile by accident.
- name: Deploy the agent
env:
QOREN_TOKEN: ${{ secrets.QOREN_TOKEN }}
run: |
npm install -g @qoren/cli
qoren agent create --env "$ENV_ID" --template deploy-bot --name "Deploy bot" --jsonBranch on the exit code when you need to:
qoren agent create --env "$ENV_ID" --template deploy-bot --name "Deploy bot"
case $? in
0) echo "deployed" ;;
3) echo "The Qoren token is missing, revoked or refused" ; exit 1 ;;
4) echo "The Qoren plan does not cover this (no plan, or no API access)" ; exit 1 ;;
*) echo "The deploy failed" ; exit 1 ;;
esacCall an endpoint that has no command#
The CLI has commands for what people do most, not for every endpoint. qoren api reaches any other one with the same credential and the same rules, and prints the raw JSON answer:
qoren api GET fleetSummary
qoren api GET machines --query limit=5
qoren api POST agents --data @agent.json
cat agent.json | qoren api POST agents --data @-The path is relative to the API root, so agents, not /api/mg/agents. To script in TypeScript instead of shell, use the Qoren SDK, which the CLI itself is built on.
Frequently asked questions#
Where is my token stored?
In ~/.config/qoren/config.json, or under $XDG_CONFIG_HOME/qoren when that is set, written so only your user can read it. It is a bearer token, so treat the file like a password. If you set QOREN_TOKEN, the file is not read at all.
How do I cut off a computer I no longer have?
Open Settings, CLI tokens in the console and revoke that token by name. Revoking does not touch your other tokens. Anything using the revoked token is refused within about 30 seconds.
Can the CLI do things the console cannot?
No. Both go through the same gate with the same account, so the CLI is bounded by exactly the same plan limits and permissions. Some operator-only endpoints are closed to both, and the CLI has no commands for them.
Which plans can use the CLI?
Ultimate, Business and Enterprise, which include API access. On Starter or Pro the console does everything the CLI does; upgrade on the pricing page to script it. A plan change reaches a token that is already in use within about 30 seconds.
Does it work in CI without a browser?
Yes. Create a token under Settings, CLI tokens, set it as QOREN_TOKEN, and add --json so the job can read the output. No login step or browser is involved.
Why does deploying an agent take minutes?
Deploying installs and configures the agent on its environment in a series of steps. The CLI prints each step as it starts, so you can see where it is. Add --no-wait if you would rather not watch.