All pages
On this page

Environment variables

Most of OAR is set up in the web UI or in config.json. 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 start without a service: the relay is started in the background with the environment of the shell you ran oar start in. 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 sets COPILOT_WEB_RELAY_CONFIG, COPILOT_WEB_RELAY_DATA_DIR (always the install's own data/, even when your shell sets another), COPILOT_WEB_RELAY_LOG_DIR, and the PATH of the shell that ran the command with ~/.local/bin and Node.js's folder added, and nothing else. oar start uses 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, and oar service install and oar setup --start write 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_WEB_RELAY_DATA_DIR and COPILOT_WEB_RELAY_LOG_DIR (the system-startup one also adds Node.js's folder to 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 restart of 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, run oar stop, then oar start from 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 tmux is 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 tmux installed), 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_WEB_RELAY_CONFIG, COPILOT_WEB_RELAY_LOG_DIR, COPILOT_WEB_RELAY_DATA_DIR, COPILOT_SDK_PATH, COPILOT_PROVIDER_MAX_PROMPT_TOKENS, COPILOT_PROVIDER_MAX_OUTPUT_TOKENS, CLAUDE_CONFIG_DIR, CLAUDE_CODE_EXECUTABLE, CURSOR_AGENT_STORE_DIR, GROK_CLI_COMMAND, GROK_ALWAYS_APPROVE and OAR_MCP_SERVER. 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_CODE_OAUTH_TOKEN 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_API_KEY and ANTHROPIC_AUTH_TOKEN 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_TURN_STALL_IDLE_MS, OAR_TURN_STALL_MODEL_MS, OAR_TURN_STALL_TOOL_MS Not passed. They have no effect on a worker that runs under tmux.
CLAUDE_CODE_AUTO_COMPACT_WINDOW (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_MCP_SERVER, CLAUDE_CONFIG_DIR, CLAUDE_CODE_EXECUTABLE, CURSOR_AGENT_STORE_DIR, GROK_CLI_COMMAND, COPILOT_PROVIDER_MAX_* Passed. The relay hands GROK_CLI_COMMAND, or GROK_COMMAND when that is not set, to every Grok worker as GROK_CLI_COMMAND.
XAI_API_KEY (read by the Grok CLI) Not passed.
COPILOT_SDK_PATH Passed: your value, or the folder the relay resolved. COPILOT_PKG_DIR 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_PROJECT_DIR and CLAUDE_ENV_FILE;
  • by family: every CLAUDE_CODE_SESSION_* (the session id among them), every CLAUDE_CODE_*_SESSION_ID and every CLAUDE_CODE_MESSAGING_*.

Your own settings stay: every other CLAUDE_CODE_* variable (such as CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_GIT_BASH_PATH), every other CLAUDE_AGENT_SDK_* variable, CLAUDE_CONFIG_DIR, and the two settings inside a family, CLAUDE_CODE_SESSION_START_ANNOUNCEMENTS_BEFORE_PROMPT and CLAUDE_CODE_SESSION_LOG. 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.json for the data folder (dataDir), 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 in config.json.
  • A program installed from the panel beats the variable for CLAUDE_CODE_EXECUTABLE and GROK_CLI_COMMAND: the panel saves it in config.json and sets it again at every relay start.
  • 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.json (see config.json); oar setup --port changes the port.

The installer #

Read by oar.sh/install (macOS and Linux) and oar.sh/install.ps1 (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_VERSION x.y.z; unset installs the latest Installs that version. Wins over OAR_CHANNEL. macOS, Linux and Windows.
OAR_CHANNEL 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_PORT 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_NODE private Uses OAR's own Node.js in ~/.oar/runtime/node even when yours would do. macOS and Linux only.
OAR_DRY_RUN any non-empty value, for example 1 Prints the plan and installs nothing. Even 0 counts as set. macOS, Linux and Windows.
OAR_YES any non-empty value The same as --yes: no question before installing. macOS and Linux only.
OAR_STATE_ROOT a folder; default ~/.oar 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_STATE_ROOT a folder; default ~/.oar, %APPDATA%\oar on Windows Moves the state of a global install: config.json, 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_WEB_RELAY_CONFIG a file path; default server/config.json in the package The config file the relay reads, when you start it yourself (node server/server.js). oar copilot uses it when the file exists. oar start and the service use the install's own config.json. See oar command.
COPILOT_WEB_RELAY_DATA_DIR a folder; default dataDir from config.json, else server/data The data folder (database, uploads, Cursor agent stores and, Added in 0.9.17 in deepseek-claude, the Claude Code state of DeepSeek chats). Beats dataDir. oar start and oar copilot pass it on to the relay; the systemd service and oar status use the install's own data/.
COPILOT_WEB_RELAY_LOG_DIR a folder The log folder; default logs in the state folder of a global install. A relay you start yourself keeps relay-console.log in logs of COPILOT_WEB_RELAY_DATA_DIR when that is set, else in server/logs, and its worker logs in server/logs.
COPILOT_WEB_RELAY_NODE 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_NO_CONSOLE_LOG 1 switches it off; other values do nothing Stops the relay keeping a copy of its console in relay-console.log in the log folder.
OAR_NO_UPDATE_CHECK 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.Y.Z still works. Other values do nothing.
OAR_UPDATE_MANIFEST_URL a URL; default https://oar.sh/latest.json The update manifest that the relay and oar update read.
OAR_MCP_SERVER 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 tool. The other providers carry their tools in-process and are not affected. See Agent tools.
OAR_TURN_STALL_IDLE_MS, OAR_TURN_STALL_MODEL_MS, OAR_TURN_STALL_TOOL_MS 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_WORKSPACE_ROOT_ALLOW_LIST folders separated by : (; on Windows); unset allows any The folders a conversation may start in, and their subfolders. Beats workspaceRootAllowList. 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_REMOTE_<FLAG> 1, true, yes, on or 0, false, no, off Pins a feature flag. See below.
OAR_HOST_SUSPEND_DRY_RUN 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_TURN_STALL_* 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_TURN_STALL_IDLE_MS, the model and tool windows keep their proportion to it: setting it to 240000 doubles both defaults. Set them as well to pin them. An idle window of 0 takes both to 0 unless 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_TURN_STALL_MODEL_MS has a default of 600000, and its tool window scales with OAR_TURN_STALL_IDLE_MS 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.
  • The extension engine and Claude Cloud do not read these variables.
  • On Grok an idle window of 0 does not turn the watch off: all three windows return to their defaults, and OAR_TURN_STALL_MODEL_MS and OAR_TURN_STALL_TOOL_MS are ignored.
  • 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_REMOTE_. 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_REMOTE_SESSION_WORKER_ROUTING_ENABLED Session worker routing on
COPILOT_REMOTE_SESSION_WORKER_CONTINUATION_ROUTING_ENABLED Continuation answer routing on
COPILOT_REMOTE_SESSION_WORKER_FALLBACK_RESTART_ENABLED Worker fallback restart (reserved) off, and changes nothing
COPILOT_REMOTE_IMAGE_CONVERSATION_CONTINUITY_ENABLED 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_PREVIEWS_ENABLED 1/true or 0/false Switches previews on or off. Any other value leaves previews.enabled in charge.
COPILOT_PREVIEWS_PORT 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_PREVIEWS_BIND_HOST an address; default 127.0.0.1 The address the preview listener binds to. An address other than loopback also needs previews.allowPublicBind: true in config.json, or previews stay off.
COPILOT_PREVIEWS_PUBLIC_BASE_URL 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_PREVIEWS_ALLOWED_TARGET_HOSTS 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 allowedTargetHosts.

The Cloudflare tunnel #

For the cloudflaredTunnel block of config.json, and the marker headers of any tunnel. Each COPILOT_CLOUDFLARED_* variable beats its key; the marker headers are merged.

Variable Value / default What it does
COPILOT_CLOUDFLARED_MODE managed or disabled Overrides cloudflaredTunnel.mode (Cloudflare Tunnel). Any other value is ignored. managed needs a token.
COPILOT_CLOUDFLARED_TOKEN a tunnel token Overrides cloudflaredTunnel.token.
COPILOT_CLOUDFLARED_BINARY a name or path; default cloudflared from the PATH Overrides cloudflaredTunnel.binary.
COPILOT_TUNNEL_MARKER_HEADERS header names separated by commas More marker headers, besides cf-ray, 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 tunnelMarkerHeaders in config.json, not replaced by it: tunnelMarkerHeaders: [] 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_SDK_PATH a folder The copilot-sdk 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_WEB_RELAY_CLI_EXECUTABLE, then COPILOT_CLI_EXECUTABLE, then COPILOT_CLI_PATH a program; default copilot The Copilot CLI the extension engine runs on Linux and macOS (Windows always runs gh copilot). The first beats cliPath in config.json.
COPILOT_CONFIG_HOME a folder; default ~/.copilot Where oar copilot writes its extension wrapper.
COPILOT_PKG_DIR a folder An extra package cache to search.
XDG_CACHE_HOME, XDG_DATA_HOME folders On Linux, where the two default package caches are (copilot/pkg inside each).
GH_TOKEN, GITHUB_TOKEN a GitHub token Used for the Copilot card in Check Usage, instead of the result of gh auth token. GH_TOKEN is read first.
COPILOT_SESSION_STATE_DIR a folder; default ~/.copilot/session-state The Copilot CLI's session-state folder, if it is elsewhere. Used only if that folder exists.

OAR_MCP_SERVER and COPILOT_REMOTE_SESSION_WORKER_ROUTING_ENABLED 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_PROVIDER_MAX_PROMPT_TOKENS a positive whole number The prompt ceiling for the model, instead of OAR's table. An unusable value is logged and ignored.
COPILOT_PROVIDER_MAX_OUTPUT_TOKENS a positive whole number The same for the output.

The folder for generated pictures follows COPILOT_SESSION_STATE_DIR.

Claude #

See Claude.

Variable Value / default What it does
CLAUDE_CONFIG_DIR a folder; default ~/.claude 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-claude in the data folder (DeepSeek). Added in 0.9.18 Claude API chats use it as Claude chats do.
CLAUDE_CODE_EXECUTABLE 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.json, and from then on that program wins over your variable at every start. Sign-in runs claude from the PATH.
CLAUDE_CODE_OAUTH_TOKEN a Claude login token Read by Claude Code in place of the login in CLAUDE_CONFIG_DIR. Added in 0.9.17 Claude workers get it under tmux too. Which workers get it: see Claude Cloud.
ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN 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_CODE_OAUTH_TOKEN), 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_DEFAULT_TIMEOUT_MS, BASH_MAX_TIMEOUT_MS, CLAUDE_CODE_AUTO_BACKGROUND_TIMEOUT_MS 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_CODE_AUTO_COMPACT_WINDOW 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_API_KEY 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_API_KEY, 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_CONFIG_DIR Used, as for Claude: the chats share the Claude configuration folder.
CLAUDE_CODE_EXECUTABLE Used, as for Claude.
BASH_DEFAULT_TIMEOUT_MS, BASH_MAX_TIMEOUT_MS, CLAUDE_CODE_AUTO_BACKGROUND_TIMEOUT_MS Set by OAR from Claude background command limit, as for Claude.
CLAUDE_CODE_AUTO_COMPACT_WINDOW Ignored.
CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, CLAUDE_CODE_USE_FOUNDRY, every ANTHROPIC_* Ignored: OAR points Claude Code at https://api.anthropic.com with the saved key.
CLAUDE_CODE_EFFORT_LEVEL, CLAUDE_CODE_SUBAGENT_MODEL, CLAUDE_CODE_SUBAGENT_MODEL_FORCE, CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL Ignored: OAR sets the effort and the models from the chat.
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB 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_CODE_OAUTH_TOKEN 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_CONFIG_DIR a folder; default ~/.claude Where the CLI's login (.credentials.json) is read from.
OAR_CLAUDE_CLOUD_BRANCH_LOOKUP 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_API_KEY or DEEPSEEK_BASE_URL 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_CODE_EXECUTABLE Used, as for Claude.
BASH_DEFAULT_TIMEOUT_MS, BASH_MAX_TIMEOUT_MS, CLAUDE_CODE_AUTO_BACKGROUND_TIMEOUT_MS Set by OAR from Claude background command limit, as for Claude.
CLAUDE_CONFIG_DIR Ignored. Claude Code keeps its state in deepseek-claude in the data folder (Folder and session).
CLAUDE_CODE_AUTO_COMPACT_WINDOW Ignored.
CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, CLAUDE_CODE_USE_FOUNDRY, every ANTHROPIC_* Ignored: OAR points Claude Code at DeepSeek's endpoint with the saved key.
CLAUDE_CODE_EFFORT_LEVEL, CLAUDE_CODE_SUBAGENT_MODEL, CLAUDE_CODE_SUBAGENT_MODEL_FORCE, CLAUDE_CODE_WORKFLOW_SUBAGENT_MODEL Ignored: OAR sets the effort and the models from the chat (Reasoning effort, Models).
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB 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_CODE_DISABLE_NONESSENTIAL_TRAFFIC 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_ID, and every COPILOT_WEB_RELAY_*, COPILOT_PROVIDER_*, 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_API_KEY 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_SESSION_TOKEN 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_AGENT_STORE_DIR a folder; default cursor-agents in the relay's data folder (Added in 0.9.14; before, data/cursor-agents in the relay's server folder) Where the per-conversation agent state is kept.

Grok #

See Grok.

Variable Value / default What it does
GROK_CLI_COMMAND a program name or path; default grok The Grok program for sign-in, model discovery and the workers. GROK_COMMAND is read when it is not set; the relay hands either one to the workers as GROK_CLI_COMMAND, under tmux too. An install or update from the panel saves the program in config.json, and from then on it wins over the variable at every start.
GROK_ALWAYS_APPROVE 0; default 1 0 starts Grok without --always-approve; OAR then answers each permission request with allow-once. Passed to workers under tmux.
XAI_API_KEY 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 (*_STUB_*, *_ALLOW_STUB_SPAWN, COPILOT_WEB_RELAY_DISABLE_CLI_SPAWN, OAR_PACKAGE_SPEC, OAR_CLAUDE_CLOUD_API_BASE_URL, Added in 0.9.18 OAR_ANTHROPIC_API_BASE_URL, OAR_HYGIENE_DENYLIST); the variables the relay sets for its own worker processes (COPILOT_WEB_RELAY_WORKER_KIND, *_RELAY_MODEL, SESSION_ID, COPILOT_WEB_RELAY_ROOT, COPILOT_WEB_RELAY_SERVER_DIR, OAR_MCP_SERVER_ATTACHED and the other COPILOT_PROVIDER_*, which the relay fills from the OpenAI settings, and Added in 0.9.17 DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL and DEEPSEEK_CLAUDE_CONFIG_DIR, which it fills from the DeepSeek settings, and Added in 0.9.18 OAR_CLAUDE_API_KEY and CLAUDE_API_RELAY_MODEL, 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_SDK_RELAY_*, CLAUDE_RELAY_*, OAR_BOOT_REPORTING_WINDOW_MS, OAR_RELAY_RESTART_MAX_WAIT_MS, COPILOT_WEB_RELAY_CLAUDE_AUTH_BIN, COPILOT_WEB_RELAY_CLI_BIN_DIR, COPILOT_WEB_RELAY_*_WORKER_PATH); GROK_DISABLE_AUTOUPDATER, which OAR sets to 1 for Grok; and COPILOT_WORKSPACE_ROOT, which the launchers set. The oar menu honours NO_COLOR. Leave the rest alone.