Official command-line interface for the orq.ai API.
Manage prompts, agents, deployments, knowledge bases, evaluators, and the rest of the orq.ai platform from your terminal, CI, or scripts. Works against orq.ai SaaS out of the box and against self-hosted deployments with a single flag.
npm install -g @orq-ai/cliRequires Node.js 14 or newer. The matching native binary is downloaded automatically for your platform; no postinstall scripts or network downloads at runtime.
curl -fsSL https://cli.orq.ai/install.sh | shInstalls a raw binary to ~/.orq/bin/orq, verifies it against the release's published per-asset .sha256, asks before adding the install directory to your shell profile (declining is fine — PATH just stays unset), and then runs orq setup to get you authenticated. Pass flags after -s --:
# pin a version
curl -fsSL .../install.sh | sh -s -- --version v0.1.0
# custom install dir (must be writable by the current user)
curl -fsSL .../install.sh | sh -s -- --install-dir /usr/local/bin
# just install: no profile edit, no setup
curl -fsSL .../install.sh | sh -s -- --no-modify-path --no-setup
# the pre-release line instead of stable
curl -fsSL .../install.sh | sh -s -- --channel rcORQ_CLI_VERSION, ORQ_CLI_CHANNEL and ORQ_CLI_INSTALL_DIR still work as equivalents of --version, --channel and --install-dir. --channel and --version together are an error, but an exported ORQ_CLI_CHANNEL is ambient config and is ignored rather than rejected when --version pins a release — that is the combination orq update passes. A checksum mismatch aborts the install, as does any failure to fetch the checksum other than a 404; releases published before the checksum assets existed simply skip verification with a notice.
Grab a binary for your platform from the Releases page. Assets are named orq-<os>-<arch>[.exe].
Requires Go 1.23 or newer:
git clone https://github.com/orq-ai/orq-cli.git
cd orq-cli
make build
./bin/orq --versionorq setup # sign in, pick a project, wire up your coding agentsThat is the whole first run. It signs you in, asks which project to work in when the workspace has more than one, creates an API key scoped to that project (reused on later runs), and wires your coding agents to orq. After that:
orq status # verify identity, workspace and project
orq workspace list # see available workspaces
orq prompts list # run any generated command
orq doctor # diagnose auth, config, and endpoint reachabilitySetup authenticates the machine; wiring agents is orq connect:
orq setup # sign in, create the key, then offers to connect
orq connect # wire every detected agent through the gateway
orq connect codex kimi # specific agents
orq connect codex gateway # one capability: gateway, otel, skills or mcp
orq connect claude otel # trace the sessions you start yourself, not only orq launch ones
orq connect claude mcp skills --local # this project only (mcp and skills have a project scope)
orq connect --dry-run # show the files that would change
orq disconnect codex # remove exactly what connect wroteAn interactive orq setup ends by offering to connect the agents it detects, so one command still takes a new machine to working. Non-interactive runs stop after the key and print Next: orq connect — in CI, compose the two: orq setup --no-input --api-key "$KEY" && orq connect codex.
Between signing in and creating the key, setup asks which project to work in. It skips itself automatically at zero or one project — there is nothing to choose — and never offers to create one. --project <id|key|name> pre-answers it for a non-interactive run; --no-project skips it and leaves the session unscoped. An --api-key run skips it entirely, since there is no session for a project choice to narrow.
Supported coding agents: codex, opencode, kimi, kilo, pi. claude is not offered persistent gateway wiring: it has no provider config and routes purely through environment variables, so orq launch claude routes its model calls for that session. It also receives skills, mcp and otel.
Connect handles four capabilities: gateway, otel, skills and mcp. Name none and it writes the ones the agent can take. orq connect claude mcp writes the orq MCP server's URL into the agent's own config and nothing else — no key, no header, no bearer variable — and the agent logs in to that server itself; the command prints its login step. pi has no MCP support at all and says so rather than reporting a wire. orq connect claude otel installs the orq-trace plugin through Claude Code's own plugin manager, from the public orq-claude-plugin marketplace, so every session Claude Code runs is captured as a trace in your workspace and claude plugin update keeps it current. It writes no key either: the plugin posts with the ORQ_API_KEY your shell exports, and the command says so when your shell exports none. orq disconnect claude otel uninstalls the plugin and leaves the marketplace, which the other orq plugins share. --global (the default) writes machine-wide, --local writes to this project: mcp goes into the agent's project config file (.mcp.json, .codex/config.toml, opencode.json, kilo.json, .kimi-code/mcp.json), and skills into ./.claude/skills for Claude Code and ./.agents/skills for every other agent — the two directories npx skills uses, anchored at the directory you run from. Add the directories it writes to .gitignore; connect names them, and the links point into ~/.orq. gateway and otel are machine-wide whatever the flag says. --local is refused from your home directory, where the config it would produce would follow you into every session started from home. A bare orq disconnect removes both scopes; a local install made from another directory is counted and left for a --local run from there. Codex loads its project config only for a repository marked trusted in ~/.codex/config.toml; connect prints the line to add.
orq connect --status emits the abbreviated installed bundle version only when
skills is requested and a selected agent has a recorded permanent link visible
in the current global or local view. orq doctor shows the same version in its
skills check, and orq doctor -o json returns the full value at
checks[id=skills].details.version.
Connect also registers orq as a model provider for kimi, codex, opencode, kilo and pi, so their own LLM calls can route through the orq AI Gateway and show up in your traces. The provider is registered as an available option, never the agent's default — setup cannot guarantee ORQ_API_KEY is exported in every future shell, and an agent whose default points at a provider with no credential fails on every run. The exception is kimi, which fills its default_model only when the config has none. orq launch <agent> remains the way to get orq as the default for a session.
| Agent | Connect writes | Route through orq by |
|---|---|---|
kimi |
[providers.orq] + the model list into ~/.kimi-code/config.toml |
just running kimi (default filled when absent) |
codex |
a self-contained profile at $CODEX_HOME/orq.config.toml (default ~/.codex/) |
codex --profile orq |
opencode |
provider blocks merged into ~/.config/opencode/opencode.json |
picking an Orq AI Gateway model in the picker |
kilo |
provider blocks merged into ~/.config/kilo/kilo.json |
picking an Orq AI Gateway model in the picker |
pi |
an orq provider merged into $PI_CODING_AGENT_DIR/models.json (default ~/.pi/agent/) |
pi --model orq/<model>, or the /model picker |
claude |
nothing — claude has no provider concept, only all-or-nothing env routing | orq launch claude |
copilot |
nothing — copilot's BYOK provider is env-only, one model per session | orq launch copilot |
gemini |
nothing — gemini reads a config home, not a provider registry | orq launch gemini |
Models come from the live gateway catalogue (enabled chat models with tool calling), keyed by their canonical ref. The default the agent opens with is chosen from that ranking. orq setup sends no model call of its own: a probe would bill your credits and open a trace in your workspace to prove something you did not ask to have proven. Your first agent request is the test.
Your API key is not written into an agent config, with one exception — those configs reference the ORQ_API_KEY environment variable. A gateway key minted from a browser login lives in the server-keyed ~/.orq/sessions/<host>.json; a saved API-key profile lives in ~/.orq/credentials.json. Setup also writes the effective key to ~/.orq/env, which it offers to source from your shell profile (~/.orq/env.fish for fish). These credential files are mode 0600.
The exception is kimi: version 0.34 reads a provider credential only as a literal in config.toml, ignoring both ${ORQ_API_KEY} interpolation and an env_key indirection, so ~/.kimi-code/config.toml holds the key itself. Setup writes that file mode 0600.
The key setup mints is scoped to the project you chose in the step above. That is what the coding agents use for model calls, so a config file another program reads — ~/.kimi-code/config.toml included — can no longer reach the rest of the workspace. It does not scope the agents' MCP tools: those authenticate to the orq MCP server over OAuth, independent of the API key.
Setup flags: --workspace <key> (activate a workspace), --project <id|key|name> (pre-answer the project step), --no-project (skip the project step, leave the session unscoped), --api-key <key> (use this key instead of logging in and creating one), -i (revisit inferred workspace and API-key choices), --no-input (never prompt; missing values become errors).
Connect and disconnect take agents and capabilities as arguments, plus:
| Flag | Effect |
|---|---|
--api-key <key> |
Use this key for the run; it is not saved |
--dry-run |
Show the files that would change, write nothing (connect only) |
--yes |
Act on every detected agent without asking |
--status |
Print what is wired on this machine and exit (connect only) |
Re-running the wiring after installing a new agent is just orq connect <agent>; it reuses the key setup saved rather than creating another. Not to be confused with orq agents, which manages Orq Agents in your workspace; connect wires the coding-agent CLIs on this machine.
Every provider config resolves to one absolute path, so the gateway has no project-versus-home scope to choose; --global and --local act on mcp and skills only.
Two ways in. A browser login is an account on a server and sees every workspace
that account can; a profile is one saved API key. --profile selects a profile
and nothing else.
orq auth loginWalks you through a browser device-authorization flow, stores the login in
~/.orq/sessions/<host>.json (my.orq.ai.json for the hosted service), and
picks an active workspace. Re-running orq auth login refreshes it. Sign out
with orq auth logout.
A second server is a second login, selected the way every other command selects a server:
orq auth login --server https://orq.acme.internal
orq --server https://orq.acme.internal prompts list
orq server set https://orq.acme.internal # make it the defaultexport ORQ_API_KEY=sk_live_...
orq agents listFor several keys, save each as a profile and pick one per call, or persist the pick:
orq auth profile add ci --api-key-file ci.key # `-` reads the key from stdin
orq --profile ci agents list
orq auth profile use ci
orq auth profile current
orq auth profile clearThe key is read from a file rather than typed as an argument: a secret on the
command line lands in your shell history and in ps. Omit --api-key-file on
a terminal and the CLI prompts for it without echo.
While a profile is in force the login session is not consulted: --workspace
has no effect and orq whoami reports the profile. --profile "" turns a
persisted pick off for one call.
orq workspace list # list workspaces available to the active identity
orq workspace use <key> # switch active workspace (persists in the session)
orq status # current user + active workspace + active project + server + credential in use (alias: orq whoami)Projects organize resources within a workspace. Selecting one narrows the session, not just the display: reads and creates are both scoped, with no per-command flag needed.
orq projects list # list projects in the active workspace
orq projects use <project> # select the active project, by id, key or name (persists in the session)
orq projects use # no argument at a terminal opens a picker; otherwise prints the active project
orq projects use --clear # unset the active projectSelecting a project exchanges the session's access token for one scoped to it — POST /v2/auth/access-token takes the project_id and returns a token whose projects claim carries only that project. The server enforces the scope on both reads and creates: orq agents list goes from 112 agents workspace-wide down to the 9 that belong to the selected project, and orq agents create with no --project-id lands there.
For a single invocation without switching the session, pass --project <id|key|name> (env ORQ_PROJECT) on any command. Under an explicit API key there is no session token to narrow, so --project fills the command's own --project-id instead — an explicit --project-id always wins over it. Resolution order, highest first: the command's own --project-id, --project/ORQ_PROJECT, the session's active project, the workspace's default project.
orq switch [workspace] [project] walks both selections in one command. Switching workspaces clears the active project, since a project belongs to the workspace it was chosen in — orq workspace use <other> does the same, and orq workspace use on the workspace already active leaves the chosen project alone, because it only ever writes the workspace. orq switch has no such exemption: naming a workspace tells it to rewrite both halves, so orq switch <already-active> re-runs the project selection too.
Without a terminal, orq switch needs both halves named — orq switch <workspace> <project>. It rewrites your whole identity, so guessing at either half would replace a deliberately chosen project with the workspace default and report success. To move workspace alone, use orq workspace use <workspace>, which leaves the project untouched and re-asserts rather than failing when given no argument. Neither restriction applies at a terminal, where both commands open a picker.
orq doctor
orq doctor -o json # machine-readable
orq doctor --fix # chmod the credential paths the permissions check flags (Unix; exits 1 if a repair fails)doctor reports:
- CLI binary + runtime (version, orq API version, platform/arch)
- Active profile or session file path
- Resolved
api_base_url,v1_base_url,auth_base_url,profile_base_urlwith their source (flag, profile, env, config, default;v1_base_urlandprofile_base_urlmay also report session or derived) - Auth status (authenticated / misconfigured / missing / invalid / unreadable), user email, active workspace
- Reachability probes against each endpoint
- Bootstrap token freshness
- Credential file permissions under
~/.orq(Unix only) — group- or other-accessible paths only; a clean tree is not reported. Symlinked paths are judged on their target, and the finding names that target as well as the path under~/.orq.--fixchmods them (0600 files, 0700 directories); without it doctor only reports. A--fixrun that could not repair something exits1; a run that only reports findings exits0. On Windows--fixis rejected — the bits it repairs do not exist there.
orq agents list # table at a terminal, TOON when piped
orq agents list --output-format toon # TOON
orq agents list --output-format json # JSON (or the -o json shorthand)
orq agents list --output-format yaml # YAML
orq agents list --columns id,display_name # pick table columns
orq agents list -j 'data[].display_name' # JMESPath queryPersist a new default:
orq default-format jsonorq traces thread is the one command where -o takes a different set of
formats: xml (the default, a readable render), markdown, json, yaml
and toon. It refuses -o table — a conversation is nested (messages holding
content parts, tool calls, reasoning) and has no columns to lay out.
-o is also the only way to ask it for a format. Neither ORQ_OUTPUT_FORMAT
nor the config file reaches it: both state a standing default for every command
in a shell or on a machine, so one of them naming json would swap out the
render a person came to read, and xml and markdown are not values the rest
of the CLI accepts at all — a config file naming either fails every command,
this one included. Ask this command with -o.
-o json on stdout is the only stability-guaranteed machine contract; its
shape follows the orq API response behind the command. The table a terminal
gets, and TOON, are presentation-only and may change rendering between
releases. Exit codes are 0 success, 1 failure, 130/143 on
SIGINT/SIGTERM, and errors go to stderr. The full contract, including how
command/flag removals are announced, lives in
CHANGELOG.md. The command surface itself is tracked in
surface.json, which CI keeps in lockstep with the code so
surface changes are always a reviewed diff.
| Command | Purpose |
|---|---|
orq setup |
First-run onboarding: auth, API key, coding agents |
orq auth login |
OAuth device login |
orq auth logout |
Revoke refresh token, clear local session |
orq auth whoami |
Show current identity (alias: orq whoami) |
orq auth sessions |
List saved logins, one per host |
orq auth profile add|list|current|use|clear |
Save and select API-key profiles |
orq workspace list |
List workspaces |
orq workspace use <key> |
Switch active workspace |
orq projects list |
List projects in the active workspace |
orq projects use [project] |
Switch active project, by id, key or name (--clear unsets it) |
orq status |
Show active user, workspace, project, server and the credential in use (alias: orq whoami) |
orq switch [workspace] [project] |
Switch active workspace and/or project in one command |
orq doctor |
Diagnose config, auth, reachability (--fix repairs loose credential permissions) |
orq update |
Update this binary to the latest release (--check reports only) |
orq version |
Print the CLI version, the orq API version it was built against, and the install method |
orq request <method> <path> |
Raw API escape hatch (uses configured auth) |
orq server list |
List OpenAPI-registered servers |
orq completion bash|zsh|fish|powershell |
Generate shell completions |
orq default-format <json|yaml|toon|table> |
Persist a default output format |
orq launch <agent> |
Launch a coding agent routed through the AI Router (see Launch) |
orq orqi |
Run orqi, the orq.ai assistant, installing it on first use (see orqi) |
Use --help on any group for the full surface (inputs, body fields, examples):
orq agents orq identities orq rerank
orq annotations orq images orq responses
orq audio orq knowledge-bases orq router
orq chat orq memory-stores orq router-guardrail-rules
orq chunking orq models orq router-policies
orq completions orq moderations orq router-routing-rules
orq contacts orq prompts orq tools
orq datasets orq remote-configs
orq deployments orq embeddings
orq evaluators orq feedback
orq files orq human-evals
orq human-review-sets
Deleting requires confirmation. Generated delete commands prompt before
acting, and refuse to run when there is no terminal. Pass --force to skip the
prompt — scripts and CI need it:
orq datasets delete <id> # asks first
orq datasets delete <id> --force # required in CIorq launch <agent> starts a coding-agent CLI preconfigured to route model calls through the orq.ai AI Router — one command, no manual env or config wiring. Authenticate first with orq auth login (or export ORQ_API_KEY). Claude Code can use its own login for model calls with --no-gateway.
orq launch claude # Claude Code, with model calls through the orq AI Router
orq launch claude --no-gateway # ...on your own Anthropic login instead
orq launch claude --no-otel # ...without capturing the session in your workspace
orq launch codex # OpenAI Codex CLI
orq launch opencode # OpenCode
orq launch kilo # Kilo CLI (OpenCode fork)
orq launch kimi # Kimi Code
orq launch pi # Pi Coding Agent
orq launch copilot # GitHub Copilot CLI
orq launch gemini # Gemini CLIThe agent CLI itself must be installed — each subcommand prints an install hint when it is missing. All requests appear in your orq.ai traces and logs like any other gateway traffic.
Launch follows the workspace you are in now. If ORQ_API_KEY holds the key orq setup minted and you have since run orq workspace use <other>, launch uses the workspace you switched to for that run and says so, rather than silently running against the one the key was minted for. Nothing on disk changes: the agent's own config, ~/.orq/env and credentials.json are untouched, and orq connect stays the only thing that repoints an agent. A key you exported yourself still wins outright — its workspace is unknowable, so CI and bring-your-own-key setups are unaffected.
Agents stay pinned to whatever orq connect wired them against. orq connect --status names that workspace per agent, and orq doctor says so too when it differs from your active one, with the commands to move it.
The orq MCP server is wired by default, per session, using the agent's native mechanism; --no-mcp declines. No credential is written — the agent authenticates to that server itself — and the wire is skipped when orq connect has already written a persistent entry for that agent, so a session entry cannot shadow it. Point elsewhere with ORQ_MCP_URL. Exception: pi has no built-in MCP support (extensions only), so nothing is wired there. MCP tool calls share the free plan's daily request quota with model calls; --no-mcp is how you keep the quota for model calls.
orq's skills are linked into the agent's skills directory under the directory you launch from (./.claude/skills, ./.agents/skills) for the session only, and under your home directory when launched from there; nothing is installed permanently. Opt out with --no-skills. ORQ_SKILLS_URL pins your own plugin zip instead, which claude then fetches with --plugin-url.
orq launch claude routes Claude Code's model calls through the orq AI Router and picks no model for it, so a /model choice survives a restart. Gateway routing and session tracing are on, like MCP and skills:
- Tracing turns on Claude Code's metrics and logs export to
<host>/v2/oteland loads theorq-traceplugin for that session only, through--plugin-dir. The plugin ships inside the binary and writes the session's spans; Claude Code's own trace exporter stays off so it does not create duplicate session spans. The plugin itself is never installed into~/.claude, and its hooks neednodeon PATH. If you already haveorq-traceinstalled and enabled, the launcher uses your copy instead of loading a second one.--no-otelleaves the session uncaptured. To capture the sessions you start yourself, install the plugin permanently withorq connect claude otel; the launcher then uses that copy. --gatewayexplicitly selects the default routing through<host>/v3/anthropic, where usage bills to the workspace the launcher names.--no-gatewaykeeps model calls on your own Anthropic login. No model is forced; the threeANTHROPIC_DEFAULT_*_MODELtiers let/model opus|sonnet|haikuresolve to gateway refs when routing is on.
With default routing and tracing the same call is recorded twice, once as a router row and once in the session trace, with different trace ids, so summing cost across both double-counts. --no-otel keeps one copy.
| Flag | Description |
|---|---|
--model <id> |
Gateway model id, e.g. anthropic/claude-sonnet-5-5 |
--models <list> |
Extra model ids: comma-separated or JSON array (opencode, kilo, kimi, pi) |
--base-url <url> |
Override the gateway base URL |
--no-fetch-models |
Skip fetching the enabled-model catalog |
--mcp |
Wire the orq MCP server (workspace tools) into the agent — the default |
--no-mcp |
Do not wire the orq MCP server for this session |
--no-skills |
Do not link orq's skills into the agent for this session |
--gateway |
claude only: route model calls through the orq AI Router, onto workspace billing — the default |
--no-gateway |
claude only: keep model calls on your own Anthropic login |
--otel |
claude only: capture the session as a trace in your workspace — the default |
--no-otel |
claude only: do not capture this session |
-p, --prompt <text> |
One-shot prompt, mapped to the agent's own syntax |
--dry-run |
Print the resolved command and env (key redacted) without launching |
There are two layers of flags. Global orq flags such as --profile and --server must appear before the agent name — either side of the launch word works, so orq launch --profile acme --server https://orq.acme.internal kimi and orq --profile acme launch kimi both select the profile and host. Once the agent name appears, those global flags belong to the agent and are forwarded verbatim. Launcher-specific flags in the table above (--model, --mcp, --dry-run, etc.) are recognized at the start of the agent's arguments; after the first agent-owned argument, everything goes to the agent untouched. A leading -- ends launcher-specific parsing explicitly:
orq launch claude -- --resume
orq launch codex -- exec --full-auto "fix the build"
orq launch codex --dry-run --sandbox read-only # --sandbox is codex's; put launcher flags firstThe agent runs directly on your machine, with full access to your filesystem, shell, and network — the same access it has when you start it yourself. ORQ_LAUNCH_NON_INTERACTIVE=1 suppresses every prompt, including the login prompt.
Sandboxed execution is not available in this version.
| Variable | Purpose |
|---|---|
ORQ_GATEWAY_URL |
Gateway base URL for all agents except claude and gemini (OpenAI-shaped router) |
ORQ_ANTHROPIC_BASE_URL |
claude gateway base URL (Anthropic-native endpoint), honoured with default gateway routing |
ANTHROPIC_MODEL |
passes through to claude. With --no-gateway, a provider/model_id gateway ref triggers a warning because Anthropic will reject it |
ANTHROPIC_DEFAULT_OPUS_MODEL / _SONNET_ / _HAIKU_ |
gateway refs the /model tiers resolve to with gateway routing |
ORQ_CODEX_BASE_URL / CODEX_MODEL |
codex overrides |
ORQ_OPENCODE_BASE_URL / OPENCODE_MODEL / OPENCODE_MODELS |
opencode + kilo overrides |
ORQ_KIMI_BASE_URL / KIMI_MODEL / KIMI_MODELS |
kimi overrides |
ORQ_PI_BASE_URL / PI_MODEL / PI_MODELS |
pi overrides |
ORQ_COPILOT_BASE_URL / COPILOT_MODEL |
copilot overrides |
ORQ_GEMINI_BASE_URL / GEMINI_MODEL |
gemini overrides (Gemini-native endpoint) |
orqi is the orq.ai assistant in your terminal: ask it to investigate a failing agent, check workspace health or explain the platform, and it answers using your workspace's own tools, models and skills.
orq orqi # interactive session
orq orqi "why did my agent fail today?" # one-shot
orq orqi --install # install or reinstall, then exitThe first run installs it, after asking, by running the orqi repo's own installer. It lands in
~/.local/bin (or $ORQI_INSTALL_DIR) and the session starts straight away, whether or not
that directory is on your PATH yet. Under --no-input nothing is installed and the command
prints the one-liner instead. When orqi is already installed, --install reinstalls into that
binary's own directory rather than the default, so a copy from Homebrew or a source build is
updated in place instead of being shadowed by a second one.
orqi reads the login session this CLI maintains, so orq auth login is all the setup it needs.
orq's own global flags go in front of the command word, and orqi's go behind it:
orq --profile staging orqi "why did it fail?" # --profile is orq's
orq orqi --version # --version is orqi'sThat split is the whole rule. Nothing typed after orqi is read as one of orq's flags, so a
prompt opening with --workspace or --verbose reaches orqi as words rather than being eaten,
and any flag orqi grows later works without orq having to hear about it. The two exceptions are
--help and --install, which orq answers itself; a leading -- ends orq's parsing explicitly,
so orq orqi -- --install sends --install to orqi.
--no-input refuses rather than installing, so a script that needs both does it in two calls:
orq orqi --install # unconditional, prompts nobody
orq --no-input orqi "summarise today" # fails loudly if the first call did not runorqi publishes macOS (arm64, x86_64) and Linux x86_64 builds; on anything else the command says so and stops.
| Variable | Purpose |
|---|---|
ORQ_API_KEY |
API key for headless/CI auth. Any active profile outranks it because the profile is the selected credential |
ORQ_PROFILE |
Default profile (same as --profile). A selected profile's API key and server both outrank ambient ORQ_API_KEY and ORQ_SERVER values |
ORQ_SERVER |
The orq host (same as --server). Used when no active profile supplies a server, and drives every command — auth (auth login, whoami, workspace), the generated API commands, and the URLs orq setup writes and orq launch injects: router, anthropic and MCP |
ORQ_API_BASE_URL |
Deprecated spelling of ORQ_SERVER, honored for one release. The matching --api-base-url flag on auth, workspace and doctor is deprecated the same way |
ORQ_V1_BASE_URL |
Override v1 API base URL (advanced/local dev) |
ORQ_PROFILE_BASE_URL |
Override profile endpoint (advanced/local dev) |
ORQ_CLI_VERSION |
Version to install via install.sh |
ORQ_CLI_CHANNEL |
Release line for install.sh: stable (default) or rc |
ORQ_CLI_INSTALL_DIR |
Install directory for install.sh |
ORQ_CLI_QUIET |
Set to 1 to run install.sh without its banner, info block, progress bar and next-steps epilogue. Its ! warnings and errors still print. What orq update uses |
ORQ_WEB_BASE_URL |
Web app base URL used for the links orq setup prints |
ORQ_NO_SPLASH |
Suppress the orq setup banner |
ORQ_NO_UPDATE_CHECK |
Suppress the update notice and the version check behind it |
.env and .env.local files in the current directory are loaded automatically.
orq version prints the CLI version, the orq API version the build was
generated against, and the install method it was installed through; -o json
gives cli, api_version and install_method. orq --version remains the
compact CLI-version line used by installers and scripts.
The CLI's version is its own — it does not track the orq API version, which is
why the API line has to be reported rather than read off the tag. --channel rc
installs the pre-release line, built from the staging API schema.
orq update replaces this binary with the latest published release through the
install method it was installed with: an npm install runs npm install -g @orq-ai/cli@<version>, an install.sh install re-runs the installer pinned to
that same version, which verifies the release checksum and swaps the binary in
atomically. An rc build follows the rc line rather than being moved onto the
older stable release. A binary that
arrived some other way is refused rather than overwritten, with both commands
printed so you can pick. orq update --check reports the versions and changes
nothing.
Both versions are named on stderr before the install starts (Updating orq 8.0.0 -> 8.5.2 (npm)), and the child is kept quiet. npm's output is captured
and printed only if npm fails, so a successful update loses changed 2 packages in 2s and a failed one still shows npm's own diagnosis. install.sh runs with
ORQ_CLI_QUIET=1, without the banner, the info block, the progress bar and the
next-steps epilogue it prints for a first install; its ! warnings and errors
still come through as they happen.
At most once a day, after a command finishes, the CLI also checks the npm
dist-tag for its release line and caches the answer. When a newer version
exists, later runs print a single stderr line before the command's output,
telling you to run orq update — at most three times per 24 hours, so the
notice stays a nudge rather than a fixture of every command. The only request
is a GET of the public registry.npmjs.org dist-tags document: no version,
platform or identifier is sent anywhere. Nothing is printed when ORQ_NO_UPDATE_CHECK or
CI is set, when output is piped, when -o requested a machine
format, or when the check fails.
orq auth login --server https://orq.acme.internalThe server selects the login session. There is one name for it, the global
--server (env: ORQ_SERVER), and you only pass it when you want to divert a
call. No per-command flag. Persist a host with orq server set when you do not
want to pass it on subsequent calls. The full order, highest first: --server,
the active profile's server, ORQ_SERVER, a host persisted globally with
orq server set, then https://my.orq.ai. orq doctor reports which of those
the current run used.
Switch back and forth between servers without logging out of either:
orq --server https://orq.acme.internal prompts list
orq --server https://my.orq.ai prompts listThat one host also drives everything orq setup writes and orq launch injects, so a coding agent on a self-hosted deployment never talks to the public gateway. On orq launch, global flags go before the agent name — orq launch --server <url> claude, or orq --server <url> launch claude — because everything after the agent name is handed to the agent verbatim, so its own flags (--resume, codex's -p) reach it untouched.
Derived from --server |
Used by |
|---|---|
<host>/v3/router |
model calls for codex, opencode, kilo, kimi, pi, copilot |
<host>/v3/anthropic |
model calls for claude (Anthropic-native API) |
<host>/v3/google |
model calls for gemini (Gemini-native API) |
<host>/v2/mcp |
the orq MCP server, wired per session by orq launch and persistently by orq connect mcp |
orq auth login --server https://orq.acme.internal
orq --server https://orq.acme.internal setup
orq launch --server https://orq.acme.internal kimiNothing is compiled in: the same released binary serves SaaS, staging and every self-hosted deployment. https://my.orq.ai — the API spec's own servers[0] — is only the fallback when there is no server override.
For an exported API key in CI, set ORQ_SERVER (or pass --server) to target a
different host; a saved API-key profile carries its own server. Either source
resolves the same three URLs.
If a deployment serves the AI gateway from a different hostname than the platform API, override just that one with ORQ_GATEWAY_URL (all agents) or --base-url (one command) — see per-agent environment overrides. Both take precedence over the derived value.
cmd/orq/main.go entrypoint
cli/generated/ bartolo-generated OpenAPI commands (DO NOT edit)
cli/custom/
├── register.go custom entrypoint: middleware + commands
├── auth/ OAuth device-login client, session store, URL resolution, projects/api-keys
└── commands/ cobra commands: auth, workspace, doctor, identity, setup, agents
npm/
├── cli/ @orq-ai/cli wrapper (JS shim + optionalDependencies)
└── cli-<os>-<arch>/ per-platform binary containers
scripts/
├── build.sh local dev build
├── install-local.sh install to ~/.local/bin
└── release-build.sh cross-compile all platforms + stamp version
install.sh curl | sh installer
.github/workflows/release.yml CI release workflow
make build # local dev binary at ./bin/orq
make install-local # install to ~/.local/bin/orq
make completions # generate shell completions into ./completions/
make tidy # go mod tidy
make doctor # run the doctor commandPR titles must be conventional commits (feat:, fix(auth):, chore!:) — CI
fails otherwise, and the type decides which release-notes section the PR lands
in. See AGENTS.md for the type → label table and the rest of the
repo conventions.
bartolo syncThis wipes cli/generated/ and rebuilds it from openapi.yaml. cli/custom/ is never touched — bartolo detects the existing directory and skips the stub.
You do not cut one by hand. .github/workflows/release.yml fires on every push
to main, releases when something that reaches a binary is unreleased —
cli/custom/, cmd/orq/ (or packages/orq-rc/cmd/ for the rc line), npm/,
scripts/, install.sh, VERSION, go.mod, go.sum, or either module's
openapi.yaml/.bartolo.json, changed since that line's last tag — and calls
release-pipeline.yml, which:
- Resolves the version, by the rules in Versioning, and takes the next free tag from it. Nobody tags by hand.
- Stamps
CHANGELOG.md: the hand-written## Unreleasedsection is renamed to the version being cut, a fresh empty one takes its place, and the section becomes the top of the release notes. An rc release becomes<next-minor>.0-rc.<n>and leaves the changelog alone. - Regenerates
cli/generated/from the module's schema. - Commits the regenerated tree, the stamped
CHANGELOG.mdand the resolvedVERSIONback tomain(signed, through the Git Data API —mainrequires verified signatures), then creates and pushes the release tag before building. This makes the version record and its tag one release identity; a tag may briefly have no assets. - Cross-compiles 5 platform binaries (
darwin-arm64,darwin-x64,linux-x64,linux-arm64,win32-x64), ad-hoc signs the macOS ones, and stamps version andorqApiVersioninto all 6package.jsonfiles. - Creates an idempotent draft GitHub release, uploads the raw binaries, their
.sha256files, the man pages and a stampedinstall.sh, then publishes it. - Calls
publish-npm.yml, which publishes the packages underlatest(stable) orrc(pre-release), skipping package versions already present so a retry can resume. It is called rather than triggered by the release event, because GitHub does not start a workflow run from an event raised withGITHUB_TOKEN; itsworkflow_dispatchis the manual retry. The npm dist-tags are whatinstall.sh --channel rcresolves a version from.
.github/workflows/** is deliberately not a release trigger: a change to the
pipeline itself ships with the next release that has something to ship.
npm publishing authenticates through OIDC (id-token: write), not a stored
token. workflow_dispatch runs a release on demand — stable, prerelease or
both — and no longer collides with an existing tag, because the patch is
resolved rather than read.
The orq API version comes from .bartolo.json's app_version, which
orquesta-web writes when it publishes a schema. It is recorded in the release
and in the binary; it is not the CLI's version.
To reproduce the release build locally (without publishing):
./scripts/release-build.sh 0.1.0
ls npm/cli-*/bin/MIT — see LICENSE.