Environment variables
Most of OAR is set up in the web UI or in config.. Environment variables
are for what has to be known before the relay is up, or what you want to pin
from the outside: where the relay keeps its files, whether it may contact
oar.sh, where a provider's program lives. This page lists the variables a
user may set, grouped by area.
Where to set them #
The relay reads its variables once, when it starts. Set them in the environment of the process that starts the relay, and start the relay again after a change.
oar startwithout a service: the relay is started in the background with the environment of the shell you ranoar startin. Set the variable in that shell, or in the profile that shell reads.- The systemd user service (
oar service install, and the installer on Linux where a user session exists) does not read your shell. The unit file it writes setsCOPILOT_,WEB_ RELAY_ CONFIG COPILOT_(always the install's ownWEB_ RELAY_ DATA_ DIR data/, even when your shell sets another),COPILOT_, and theWEB_ RELAY_ LOG_ DIR PATHof the shell that ran the command with~/.and Node.js's folder added, and nothing else.local/ bin oar startuses this service whenever the unit exists and a systemd user session answers, so a variable exported in your shell does not reach the relay. OAR has no setting for more variables in the unit, andoar service installandoar setup --startwrite the unit file again, so a line you add to it does not last. See Autostart and the service. - The Windows autostart is set in Settings → General → Autostart
(Windows), at sign-in or at system startup. It runs a small script that
sets
COPILOT_,WEB_ RELAY_ CONFIG COPILOT_andWEB_ RELAY_ DATA_ DIR COPILOT_(the system-startup one also adds Node.js's folder toWEB_ RELAY_ LOG_ DIR PATH) and starts the relay. It does not copy variables from a shell either, and OAR has no setting for more. - A restart with
oar restartof a relay that does not run as a service starts the new process with the same environment as the old one. To change a variable there, runoar stop, thenoar startfrom a shell that has it.
The installer variables are read by the install script, on the command line that runs it, and not by the relay. See Install OAR.
Which variables reach the agents' workers #
Every conversation runs in a worker process that the relay starts. Most of the variables on this page are read by the relay itself. A few are read by the worker, and whether the relay's value reaches it depends on how the worker is started:
- Without tmux (Windows, and Linux or macOS where
tmuxis not installed), the worker is started with the relay's environment, less what the relay takes out for every worker (below). Setting a variable for the relay is enough. - Under tmux (Linux and macOS with
tmuxinstalled), the relay passes a fixed list of variables to the worker and nothing else. Any other variable does not reach it. If no tmux server is running yet, the one that a launch starts may keep the rest of the relay's environment, but do not rely on that.
The fixed list, as far as this page covers it: COPILOT_,
COPILOT_, COPILOT_, COPILOT_, COPILOT_,
COPILOT_, CLAUDE_,
CLAUDE_, CURSOR_, GROK_,
GROK_ and OAR_. Added in 0.9.17 These, and the
values of one launch (the kind of worker, its model, its folder), go into
that worker's own command only, no longer into the environment a tmux server
keeps for every later session. Every worker's command begins by unsetting
the host Claude Code session's variables (below) and each variable of the
list, and each provider key, that this launch has no value for. A value that an earlier launch, an
older relay or the shell that started the tmux server left there does not
reach the worker.
Added in 0.9.17 CLAUDE_ goes to Claude and Claude Cloud
workers only, on every platform, under tmux through a file that only the
relay's user can read. See Claude Cloud.
Added in 0.9.18 The key saved for Claude API goes to Claude API workers alone,
the same way. See Claude API.
ANTHROPIC_ and ANTHROPIC_ go to no worker at all, on
every platform; under tmux the worker's command also unsets them, whatever
the tmux server or your login profile holds. See Claude.
| Read by the worker | Under tmux |
|---|---|
OAR_, OAR_, OAR_ |
Not passed. They have no effect on a worker that runs under tmux. |
CLAUDE_ (read by Claude Code, which the Claude worker runs; a DeepSeek or Added in 0.9.18 Claude API chat's Claude Code never gets it) |
Not passed. |
OAR_, CLAUDE_, CLAUDE_, CURSOR_, GROK_, COPILOT_ |
Passed. The relay hands GROK_, or GROK_ when that is not set, to every Grok worker as GROK_. |
XAI_ (read by the Grok CLI) |
Not passed. |
COPILOT_ |
Passed: your value, or the folder the relay resolved. COPILOT_ is read by the relay only. |
A relay started from inside Claude Code #
Added in 0.9.17 A relay you start from a shell of a Claude Code session (an agent's shell, for example) has that session's variables in its environment. The relay drops them for every worker, with and without tmux, so no worker's Claude Code takes itself for part of that session:
- by name:
CLAUDECODE,CLAUDE_,CODE_ ENTRYPOINT CLAUDE_,CODE_ EXECPATH CLAUDE_,CODE_ CHILD_ SESSION CLAUDE_,CODE_ AUTO_ BACKGROUND_ TIMEOUT_ MS CLAUDE_,AGENT_ SDK_ VERSION CLAUDE_,AGENT_ SDK_ CLIENT_ APP CLAUDE_,PID CLAUDE_,EFFORT CLAUDE_andPROJECT_ DIR CLAUDE_;ENV_ FILE - by family: every
CLAUDE_(the session id among them), everyCODE_ SESSION_ * CLAUDE_and everyCODE_ *_ SESSION_ ID CLAUDE_.CODE_ MESSAGING_ *
Your own settings stay: every other CLAUDE_ variable (such as
CLAUDE_ or CLAUDE_), every other
CLAUDE_ variable, CLAUDE_, and the two settings
inside a family, CLAUDE_ and
CLAUDE_. A DeepSeek chat's Claude Code gets fewer still:
see DeepSeek.
What wins #
It differs by variable, and the tables say which. In short:
- A variable beats
config.for the data folder (json data), the workspace allow list, the preview settings and the tunnel token, binary and mode. The tunnel marker headers of both are merged. There is no log folder key inDir config..json - A program installed from the panel beats the variable for
CLAUDE_andCODE_ EXECUTABLE GROK_: the panel saves it inCLI_ COMMAND config.and sets it again at every relay start.json - A value saved in the web UI beats the variable for the Cursor session token. Feature flags are the other way round: a variable beats what the Features tab saved.
- There is no variable for the relay's port or token. They live in
config.(see config.json);json oar setup --portchanges the port.
The installer #
Read by oar. (macOS and Linux) and oar.
(Windows). Put them in front of the shell that runs the script:
curl -fsSL oar.sh/install | OAR_VERSION=0.9.19 OAR_PORT=3400 sh
$env:OAR_VERSION = '0.9.19'; irm oar.sh/install.ps1 | iex
| Variable | Value / default | What it does |
|---|---|---|
OAR_ |
x.; unset installs the latest |
Installs that version. Wins over OAR_. macOS, Linux and Windows. |
OAR_ |
beta (on Windows also BETA; the letter case does not matter there); any other value or unset is the stable channel |
Follows the beta channel. macOS, Linux and Windows. |
OAR_ |
a port number; unset keeps the config's port, or 3333 (the next free one if that is taken) | Writes this port into the config, also over the port of an existing one. A port in use stops the install. macOS and Linux only: the Windows installer has none, and oar setup asks. |
OAR_ |
private |
Uses OAR's own Node.js in ~/. even when yours would do. macOS and Linux only. |
OAR_ |
any non-empty value, for example 1 |
Prints the plan and installs nothing. Even 0 counts as set. macOS, Linux and Windows. |
OAR_ |
any non-empty value | The same as --yes: no question before installing. macOS and Linux only. |
OAR_ |
a folder; default ~/. |
Where the installer puts the config, the data and its own folders (Where OAR keeps its files). The relay and the oar command read it too: see below. The macOS and Linux installer reads it; on Windows the script itself ignores it, but the oar setup it runs at the end reads it. |
The relay #
| Variable | Value / default | What it does |
|---|---|---|
OAR_ |
a folder; default ~/., %APPDATA%\ on Windows |
Moves the state of a global install: config., data/ and logs/. Set it in every shell where you run oar, or the command looks in the default place. A git checkout keeps its own layout and ignores it. |
COPILOT_ |
a file path; default server/ in the package |
The config file the relay reads, when you start it yourself (node server/). oar copilot uses it when the file exists. oar start and the service use the install's own config.. See oar command. |
COPILOT_ |
a folder; default data from config., else server/ |
The data folder (database, uploads, Cursor agent stores and, Added in 0.9.17 in deepseek-, the Claude Code state of DeepSeek chats). Beats data. oar start and oar copilot pass it on to the relay; the systemd service and oar status use the install's own data/. |
COPILOT_ |
a folder | The log folder; default logs in the state folder of a global install. A relay you start yourself keeps relay- in logs of COPILOT_ when that is set, else in server/, and its worker logs in server/. |
COPILOT_ |
a path to a node program; default the Node.js that runs the relay |
The Node.js the relay starts its workers with. Added in 0.9.11 Without it, workers run on the relay's own Node.js by its full path on every platform, so they start even when no node is on the relay's PATH. It also runs OAR's MCP server for the Copilot extension engine. |
OAR_ |
1 switches it off; other values do nothing |
Stops the relay keeping a copy of its console in relay- in the log folder. |
OAR_ |
1 |
Never contacts oar.sh, not even for a manual check (Updating OAR): the update checks in Settings → General answer that checks are disabled, and oar update without --to refuses. oar update --to X. still works. Other values do nothing. |
OAR_ |
a URL; default https:// |
The update manifest that the relay and oar update read. |
OAR_ |
0, false, off or no switches it off |
Keeps OAR's MCP server out of Grok sessions and the Copilot extension engine. They then get the preview instructions as text and have no relay_ tool. The other providers carry their tools in-process and are not affected. See Agent tools. |
OAR_, OAR_, OAR_ |
milliseconds; defaults 120000, 300000 and 1800000 | How long a turn may stay silent before it fails, with nothing in flight, during a model request, and during a tool call. 0 means no limit for that phase. Read by the workers, and not passed to a worker under tmux: see Which variables reach the agents' workers and below. |
COPILOT_ |
folders separated by : (; on Windows); unset allows any |
The folders a conversation may start in, and their subfolders. Beats workspace. Folders that do not exist are dropped with a warning; if none is left, any folder is allowed. An empty variable leaves the config key in charge. See Starting a conversation. |
COPILOT_ |
1, true, yes, on or 0, false, no, off |
Pins a feature flag. See below. |
OAR_ |
1, true, yes or on |
Suspend host (Windows) writes the suspend to the log and does not put the machine to sleep. For trying the flow out. |
Turn stall timers #
The three OAR_ variables are read by the workers of GitHub
Copilot and OpenAI on the SDK engine, of Cursor and of Grok. A turn that is
quiet for longer than the window of its current phase fails with a system
note; the table in Turns and the queue
shows what you see.
- A value must be a number of 0 or more. Anything else is ignored and the default applies.
- If you set only
OAR_, the model and tool windows keep their proportion to it: setting it toTURN_ STALL_ IDLE_ MS 240000doubles both defaults. Set them as well to pin them. An idle window of0takes both to0unless you set them, which is no limit in all three phases. - Claude, and Added in 0.9.17 DeepSeek, which runs on the Claude worker, only
log a quiet turn and never end it. For them,
OAR_has a default of 600000, and its tool window scales withTURN_ STALL_ MODEL_ MS OAR_in the same way. A value there that is set but empty or not a number gives 300000 (scaled by the idle window), not 600000.TURN_ STALL_ IDLE_ MS - The extension engine and Claude Cloud do not read these variables.
- On Grok an idle window of
0does not turn the watch off: all three windows return to their defaults, andOAR_andTURN_ STALL_ MODEL_ MS OAR_are ignored.TURN_ STALL_ TOOL_ MS - The workers read the variables, so under tmux they have no effect (see above).
Feature flags #
The Features tab in the settings shows the flags. A variable pins a flag
to a value regardless of what the tab saved; the relay reads it at start. Write
the flag's name in capitals after COPILOT_. The value is 1, true,
yes or on for on, and 0, false, no or off for off, in any case;
anything else is ignored and the saved value stands. These four flags exist:
| Variable | Tab label | Default |
|---|---|---|
COPILOT_ |
Session worker routing | on |
COPILOT_ |
Continuation answer routing | on |
COPILOT_ |
Worker fallback restart (reserved) | off, and changes nothing |
COPILOT_ |
Generated-image continuity | on |
Switching session worker routing off makes the SDK engine unavailable.
Previews #
Previews also need a previews block and a hostname of their own: see
preview. Each variable beats the
same key in that block.
| Variable | Value / default | What it does |
|---|---|---|
COPILOT_ |
1/true or 0/false |
Switches previews on or off. Any other value leaves previews. in charge. |
COPILOT_ |
a port number | The port of the preview listener. 0 takes a free port; otherwise 1024 or higher, and not a relay port. An unusable value leaves the port key in charge. Without a variable and a port key it is the relay's port plus one. |
COPILOT_ |
an address; default 127. |
The address the preview listener binds to. An address other than loopback also needs previews. in config., or previews stay off. |
COPILOT_ |
an http(s) URL |
The public address of previews. Required when previews are on, and its hostname must differ from the relay's. A value that is not an http(s) URL counts as missing; the key is not used instead. |
COPILOT_ |
host names separated by commas | The hosts besides the relay's own machine that a port preview may point at. A variable that is set but empty means an empty list and ignores allowed. |
The Cloudflare tunnel #
For the cloudflared block of config., and the marker headers of
any tunnel. Each COPILOT_ variable beats its key; the marker
headers are merged.
| Variable | Value / default | What it does |
|---|---|---|
COPILOT_ |
managed or disabled |
Overrides cloudflared (Cloudflare Tunnel). Any other value is ignored. managed needs a token. |
COPILOT_ |
a tunnel token | Overrides cloudflared. |
COPILOT_ |
a name or path; default cloudflared from the PATH |
Overrides cloudflared. |
COPILOT_ |
header names separated by commas | More marker headers, besides cf-, that make a request count as coming through a tunnel: the session-worker path guard refuses it, and its wrong tokens count toward the sign-in lockout. Added in 0.9.11 Added to tunnel in config., not replaced by it: tunnel no longer switches this variable off. |
Providers #
GitHub Copilot #
See GitHub Copilot for how the CLI is found.
| Variable | Value / default | What it does |
|---|---|---|
COPILOT_ |
a folder | The copilot- folder the SDK engine's workers load, instead of the one next to the newest CLI in the package cache. The relay's own model list and session import do not read it. |
COPILOT_, then COPILOT_, then COPILOT_ |
a program; default copilot |
The Copilot CLI the extension engine runs on Linux and macOS (Windows always runs gh copilot). The first beats cli in config.. |
COPILOT_ |
a folder; default ~/. |
Where oar copilot writes its extension wrapper. |
COPILOT_ |
a folder | An extra package cache to search. |
XDG_, XDG_ |
folders | On Linux, where the two default package caches are (copilot/ inside each). |
GH_, GITHUB_ |
a GitHub token | Used for the Copilot card in Check Usage, instead of the result of gh auth token. GH_ is read first. |
COPILOT_ |
a folder; default ~/. |
The Copilot CLI's session-state folder, if it is elsewhere. Used only if that folder exists. |
OAR_ and COPILOT_ apply to
Copilot too (see above).
OpenAI #
The API key and base URL are set in Settings → Providers → OpenAI and have no variable. Two variables adjust the token ceilings of OpenAI on the SDK engine; see OpenAI.
| Variable | Value / default | What it does |
|---|---|---|
COPILOT_ |
a positive whole number | The prompt ceiling for the model, instead of OAR's table. An unusable value is logged and ignored. |
COPILOT_ |
a positive whole number | The same for the output. |
The folder for generated pictures follows COPILOT_.
Claude #
See Claude.
| Variable | Value / default | What it does |
|---|---|---|
CLAUDE_ |
a folder; default ~/. |
The Claude configuration folder: the login, and where session folders are looked up. Added in 0.9.17 Not for DeepSeek chats: their Claude Code keeps its state in deepseek- in the data folder (DeepSeek). Added in 0.9.18 Claude API chats use it as Claude chats do. |
CLAUDE_ |
a file path | The Claude Code program the workers use, instead of the build bundled with the Agent SDK. An install or update from the panel sets it, saves the program in config., and from then on that program wins over your variable at every start. Sign-in runs claude from the PATH. |
CLAUDE_ |
a Claude login token | Read by Claude Code in place of the login in CLAUDE_. Added in 0.9.17 Claude workers get it under tmux too. Which workers get it: see Claude Cloud. |
ANTHROPIC_, ANTHROPIC_ |
an Anthropic key or token | Added in 0.9.17 Not passed to any worker. A Claude chat runs on the host's Claude login (the CLI's login file, or CLAUDE_), never on a key in the relay's environment. Before 0.9.17 every worker got them, and Claude Code preferred either to the Claude login. Added in 0.9.18 A Claude API chat runs on the key saved in Settings → Providers → Claude API, not on these. |
BASH_, BASH_, CLAUDE_ |
set by OAR | Added in 0.9.12 Not read from the relay's environment: OAR sets them for every Claude session it starts, and Added in 0.9.17 every DeepSeek one, from Claude background command limit (the limit, 8 h, and 2 min). See Background command limit. |
CLAUDE_ |
a token count | Read by Claude Code, not by OAR: it sets the auto-compact window. When Claude Code reports that it took the window from there, the line under the slider reads from CLAUDE_CODE_AUTO_COMPACT_WINDOW. Not passed to a worker under tmux. Added in 0.9.17 A DeepSeek chat ignores it (DeepSeek). See Compacting. |
Claude API Added in 0.9.18 #
Claude API has no variable of its own. The key is set in Settings →
Providers → Claude API; an ANTHROPIC_ in the relay's environment is
not used. The relay gives the saved key to Claude API workers only, and their
Claude Code gets it as its ANTHROPIC_, in its own environment. See
Claude API.
A Claude API chat runs Claude Code on the relay host, so the Claude variables apply to it, with these differences:
| Variable | In a Claude API chat |
|---|---|
CLAUDE_ |
Used, as for Claude: the chats share the Claude configuration folder. |
CLAUDE_ |
Used, as for Claude. |
BASH_, BASH_, CLAUDE_ |
Set by OAR from Claude background command limit, as for Claude. |
CLAUDE_ |
Ignored. |
CLAUDE_, CLAUDE_, CLAUDE_, CLAUDE_, every ANTHROPIC_ |
Ignored: OAR points Claude Code at https:// with the saved key. |
CLAUDE_, CLAUDE_, CLAUDE_, CLAUDE_ |
Ignored: OAR sets the effort and the models from the chat. |
CLAUDE_ |
Ignored: it would make Claude Code leave plan mode and run every shell command in a sandbox. |
Claude Cloud #
See Claude Cloud.
| Variable | Value / default | What it does |
|---|---|---|
CLAUDE_ |
a Claude login token | Used for Claude Cloud instead of the CLI's credentials file, by the relay and its cloud workers. Added in 0.9.17 It reaches Claude Cloud and Claude workers only, on every platform: under tmux through a file that only the relay's user can read, without tmux in the environment they inherit. The GitHub Copilot, OpenAI, Cursor, Grok and DeepSeek workers, and Added in 0.9.18 the Claude API workers, are started without it. Before 0.9.17 every worker started without tmux got it, and under tmux a tmux server that a launch started kept it for every later session. A Claude chat on a host that signs in with the token alone now gets it under tmux as well. |
CLAUDE_ |
a folder; default ~/. |
Where the CLI's login (.) is read from. |
OAR_ |
off, 0, false or no (any case) |
Stops the branch list in New Chat from asking git. Any other value leaves it on. |
DeepSeek #
Added in 0.9.17 DeepSeek has no variable of its own. The API key and the base
URL are set in Settings → Providers → DeepSeek (the base URL under
Advanced). A DEEPSEEK_ or DEEPSEEK_ in the relay's
environment is not used: the relay gives DeepSeek workers the saved values,
and no other worker gets either. See DeepSeek.
A DeepSeek chat runs Claude Code on the relay host, so the Claude variables above matter, but not all of them:
| Variable | In a DeepSeek chat |
|---|---|
CLAUDE_ |
Used, as for Claude. |
BASH_, BASH_, CLAUDE_ |
Set by OAR from Claude background command limit, as for Claude. |
CLAUDE_ |
Ignored. Claude Code keeps its state in deepseek- in the data folder (Folder and session). |
CLAUDE_ |
Ignored. |
CLAUDE_, CLAUDE_, CLAUDE_, CLAUDE_, every ANTHROPIC_ |
Ignored: OAR points Claude Code at DeepSeek's endpoint with the saved key. |
CLAUDE_, CLAUDE_, CLAUDE_, CLAUDE_ |
Ignored: OAR sets the effort and the models from the chat (Reasoning effort, Models). |
CLAUDE_ |
Ignored: it would make Claude Code leave plan mode for its default mode, so the agent could edit files, and run every shell command in a sandbox. |
CLAUDE_ |
Set to 1 by OAR, whatever yours says: Claude Code's own traffic to Anthropic (updates, telemetry) is off. |
The relay's settings for its worker (the worker kind, the relay's folders
and tools file, SESSION_, and every COPILOT_,
COPILOT_, DEEPSEEK_ and OAR_ variable) stay with the
worker: neither Claude Code nor the commands its agent runs see them. The
key itself reaches Claude Code as its token for DeepSeek's endpoint, so the
agent's commands can read it; see Where the key is
kept. Your other variables reach it as
they reach a Claude chat.
Cursor #
The Cursor API key is saved in Settings → Providers → Cursor. A
CURSOR_ in the relay's environment is not used: the relay gives its
workers the saved key. See Cursor.
| Variable | Value / default | What it does |
|---|---|---|
CURSOR_ |
a dashboard session token | For the live plan bars (Check Usage). A token saved in the panel wins over it, and it wins over the Cursor app's login. |
CURSOR_ |
a folder; default cursor- in the relay's data folder (Added in 0.9.14; before, data/ in the relay's server folder) |
Where the per-conversation agent state is kept. |
Grok #
See Grok.
| Variable | Value / default | What it does |
|---|---|---|
GROK_ |
a program name or path; default grok |
The Grok program for sign-in, model discovery and the workers. GROK_ is read when it is not set; the relay hands either one to the workers as GROK_, under tmux too. An install or update from the panel saves the program in config., and from then on it wins over the variable at every start. |
GROK_ |
0; default 1 |
0 starts Grok without --always-; OAR then answers each permission request with allow-once. Passed to workers under tmux. |
XAI_ |
an xAI key | Read by the Grok CLI, not by OAR, as an alternative to its login. The account row only knows a login made through the CLI. Not passed to a worker under tmux. |
Not for you #
Other names turn up in the source and in logs. They are not settings: the
stub and test hooks (*_, *_,
COPILOT_, OAR_,
OAR_, Added in 0.9.18 OAR_, OAR_); the variables the
relay sets for its own worker processes (COPILOT_,
*_, SESSION_, COPILOT_,
COPILOT_, OAR_ and the other
COPILOT_, which the relay fills from the OpenAI settings, and
Added in 0.9.17 DEEPSEEK_, DEEPSEEK_ and
DEEPSEEK_, which it fills from the DeepSeek settings, and
Added in 0.9.18 OAR_ and CLAUDE_, which it
fills from the Claude API settings; the keys go to a worker under tmux through
the owner-only file); and the
tuning knobs for developers (COPILOT_, CLAUDE_,
OAR_, OAR_,
COPILOT_, COPILOT_,
COPILOT_); GROK_, which OAR sets
to 1 for Grok; and COPILOT_, which the launchers set. The
oar menu honours NO_. Leave the rest alone.