Environment variables
Jarvis Code CLI uses environment variables to control a small number of runtime behaviors — relocating the data directory, turning off telemetry, and temporarily switching models without touching the config file.
Important: API keys are not configured here
Credential variables such as JARVIS_API_KEY, ANTHROPIC_API_KEY, and OPENAI_API_KEY are not read automatically from shell environment variables. Running export JARVIS_API_KEY=xxx in the terminal does not give any provider its key — they must be written in config.toml under [providers.<name>] or the [providers.<name>.env] sub-table.
The only exception is the JARVIS_MODEL_* family, which is an explicit channel that does read credentials from the shell — see Define a model from environment variables.
For background, see Config overrides: provider credentials.
Core paths
JARVIS_CODE_HOME
Overrides the data root directory; the default is ~/.jarvis-code. Once set, the config file, sessions, logs, OAuth credentials, and all other data land under the new path:
export JARVIS_CODE_HOME="/path/to/custom/jarvis-code"Make sure the directory is writable. Multiple Jarvis Code instances sharing the same
JARVIS_CODE_HOMEwill share config and credential files.
For the complete data directory structure, see Data locations.
JARVIS_DISABLE_TELEMETRY
Set to 1 to turn off anonymous telemetry reporting (also accepts true, yes, y, case-insensitive):
export JARVIS_DISABLE_TELEMETRY=1JARVIS_MODEL_* family
Switch models temporarily without modifying config.toml — when JARVIS_MODEL_NAME is set, the CLI synthesizes a temporary provider in memory; the change does not persist after restart. See Define a model from environment variables.
JARVIS_CODE_CUSTOM_HEADERS
Attaches custom HTTP headers to every outbound model request — both LLM chat requests (across all provider protocols) and /models listing requests. Useful when a gateway routes by header, for example to pin a specific cluster:
export JARVIS_CODE_CUSTOM_HEADERS=$'X-Gateway-Cluster: my-cluster\nX-Custom-Tag: debug'The format mirrors ANTHROPIC_CUSTOM_HEADERS: newline-separated Name: Value lines. Names and values are trimmed, and lines without a colon are ignored.
Added
Added in 0.20.2.
Precedence: the Kimi identity headers (
User-Agent,X-Msh-*) and a provider'scustom_headersinconfig.toml(see Config files) override same-named entries here. Authentication is protocol-dependent: on thekimi,openai, andopenai_responsesprotocols an exactAuthorizationentry replaces the generated bearer token, while/modelslisting requests keep their own authentication. A case variant such asauthorizationis never treated as the same name — it is combined with the real header, which can break requests. Do not use this variable for authentication or other reserved headers. Usecustom_headerswhen headers need to differ per provider.
Provider credential key names (written in config.toml)
The key names below are not read directly from the shell — they are key names written inside the [providers.<name>.env] sub-table of config.toml, serving as fallback values for api_key / base_url. The CLI reads only from the config file, not from process.env.
This design lets you keep familiar key name conventions while centralizing secret management in the config file:
[providers.kimi.env]
JARVIS_API_KEY = "sk-xxx"
JARVIS_BASE_URL = "https://api.moonshot.ai/v1"Key names per provider:
| Key | Applicable provider | Default |
|---|---|---|
JARVIS_API_KEY | Kimi / Moonshot | None |
JARVIS_BASE_URL | Kimi / Moonshot | https://api.moonshot.ai/v1 |
ANTHROPIC_API_KEY | Anthropic | None |
ANTHROPIC_BASE_URL | Anthropic | Follows Anthropic SDK default |
OPENAI_API_KEY | OpenAI (openai and openai_responses) | None |
OPENAI_BASE_URL | OpenAI (openai and openai_responses) | https://api.openai.com/v1 |
GOOGLE_API_KEY | Google GenAI, Vertex AI | None |
VERTEXAI_API_KEY | Vertex AI | None |
GOOGLE_CLOUD_PROJECT | Vertex AI | None |
GOOGLE_CLOUD_LOCATION | Vertex AI | None |
WARNING
GOOGLE_APPLICATION_CREDENTIALS (path to a service account JSON file) is the only exception that goes through the system environment variable mechanism — it is read by the Google SDK directly via the standard ADC flow, and the CLI does not participate. All other key names must be placed in the [providers.<name>.env] sub-table to take effect.
For the full provider type and field reference, see Providers and models.
OAuth and managed services
This group of variables redirects OAuth authentication and managed service endpoints to a self-hosted or test environment. They are not needed for everyday use.
| Variable | Purpose | Default |
|---|---|---|
JARVIS_CODE_OAUTH_HOST | OAuth auth host; highest priority | Falls back to JARVIS_OAUTH_HOST when unset |
JARVIS_OAUTH_HOST | OAuth auth host; fallback for JARVIS_CODE_OAUTH_HOST | Falls back to https://auth.kimi.com when unset |
JARVIS_CODE_BASE_URL | Managed API base URL used after OAuth login | https://api.kimi.com/coding/v1 |
WARNING
JARVIS_CODE_BASE_URL (OAuth-managed service, targeting kimi.com) and JARVIS_BASE_URL (direct API key connection, targeting moonshot.ai) are two distinct variables. Use each one in its appropriate context.
Define a model from environment variables (JARVIS_MODEL_*)
Want to switch models for testing without touching config.toml? When JARVIS_MODEL_NAME is set, the CLI synthesizes a temporary provider and model alias from the JARVIS_MODEL_* variables in memory — nothing is written back to the config file. These variables take priority over default_model in config.toml, but the -m <alias> option at startup still has the highest priority.
export JARVIS_MODEL_NAME="kimi-for-coding"
export JARVIS_MODEL_API_KEY="YOUR_API_KEY"
export JARVIS_MODEL_BASE_URL="https://api.example.com/v1"
export JARVIS_MODEL_MAX_CONTEXT_SIZE="262144"
export JARVIS_MODEL_CAPABILITIES="image_in,thinking"
jarvisComplete variable list:
| Variable | Required | Purpose | Default |
|---|---|---|---|
JARVIS_MODEL_NAME | Yes (also the enable switch) | Model id sent to the API | — |
JARVIS_MODEL_API_KEY | Yes | API key | — |
JARVIS_MODEL_PROVIDER_TYPE | No | Provider type: kimi, anthropic, openai | kimi |
JARVIS_MODEL_BASE_URL | No | API base URL | Each type has its own default |
JARVIS_MODEL_MAX_CONTEXT_SIZE | No | Maximum context length (tokens) | 262144 (256 K) |
JARVIS_MODEL_CAPABILITIES | No | Comma-separated capability tags, unioned with auto-detected capabilities | image_in,thinking |
JARVIS_MODEL_DISPLAY_NAME | No | Name shown in /model | Falls back to JARVIS_MODEL_NAME |
JARVIS_MODEL_MAX_OUTPUT_SIZE | No | Per-request output cap (anthropic only); when set, overrides the built-in Claude ceiling | Model default |
JARVIS_MODEL_REASONING_KEY | No | Reasoning field name override (openai only) | Auto-detected |
JARVIS_MODEL_THINKING_EFFORT | No | Thinking effort level: low/medium/high/xhigh/max | — |
JARVIS_MODEL_ADAPTIVE_THINKING | No | Force adaptive thinking on or off (anthropic only) | Inferred from model name |
If JARVIS_MODEL_NAME is set but a required variable is missing, startup fails immediately with a clear error message.
Runtime switches
Switches that control the behavior of subsystems such as telemetry, background tasks, and the plugin marketplace:
| Variable | Purpose | Valid values |
|---|---|---|
JARVIS_DISABLE_TELEMETRY | Disable anonymous telemetry reporting | 1, true, yes, y (case-insensitive) |
JARVIS_CODE_PASSWORD | Set a parallel auth credential for the jarvis server API, valid alongside the bearer token; recommended when binding the server beyond loopback — see Local server and API | Any non-empty string; when unset, only the token is valid |
JARVIS_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT | Whether to keep background tasks when the session closes; takes higher priority than config.toml. The default is to stop them on exit | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_BACKGROUND_MAX_RUNNING_TASKS | Cap on concurrently running background tasks; takes higher priority than [background] max_running_tasks in config.toml (unset means no cap) | Positive integer; invalid values are ignored |
JARVIS_IMAGE_MAX_EDGE_PX | Longest-edge ceiling (px) for image compression; takes higher priority than [image] max_edge_px in config.toml (default 2000) | Positive integer; invalid values are ignored |
JARVIS_IMAGE_READ_BYTE_BUDGET | Per-image byte budget for model-initiated image reads (ReadMediaFile default reads); takes higher priority than [image] read_byte_budget in config.toml (default 262144, i.e. 256 KB) | Positive integer; invalid values are ignored |
JARVIS_CODE_PLUGIN_MARKETPLACE_URL | Override the plugin marketplace JSON loaded by /plugins; useful for dev loopback servers, staging CDN files, or alternate marketplace directories | https://code.kimi.com/kimi-code/plugins/marketplace.json; also accepts http://, file:// URLs, and local paths |
JARVIS_CODE_AGENT_SWARM_MAX_CONCURRENCY | Cap how many AgentSwarm subagents run concurrently during the initial ramp; leave unset for no cap | Positive integer; invalid values fail fast |
JARVIS_SUBAGENT_TIMEOUT_MS | Maximum wall-clock time (ms) a single Agent subagent may run; takes higher priority than [subagent] timeout_ms in config.toml (default 7200000, i.e. 2 hours) | Positive integer; invalid values fall back to the config or default |
JARVIS_CODE_SWARM_TIMEOUT_MS | Maximum wall-clock time (ms) a single AgentSwarm subagent may run; takes higher priority than [swarm] timeout_ms in config.toml (default 7200000, i.e. 2 hours) | Positive integer; invalid values fall back to the config or default |
JARVIS_CODE_IDENTITY_NAME | Display name the agent calls itself in the system prompt; takes higher priority than [identity] name in config.toml and is never written back to it | Any non-empty string; blank values read as unset |
JARVIS_CODE_IDENTITY_SLUG | Protocol identifier for the User-Agent product token sent to third-party providers and the MCP client name; takes higher priority than [identity] slug. Derived from the name when unset | Any non-empty string; normalized to lowercase with non-alphanumeric runs folded to - |
JARVIS_CODE_BUILTIN_PRODUCT_SKILLS | Whether the built-in skills documenting Jarvis Code itself are offered to the model; takes higher priority than builtin_product_skills in config.toml (default enabled) | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_TUI_FULL_SCREEN | Enable the experimental fullscreen alternate-screen UI: scrollable transcript viewport, mouse text selection, clickable links, and Ctrl-Shift-F transcript search | 1 enables it; anything else keeps the regular inline UI |
JARVIS_CODE_EXPERIMENTAL_SECONDARY_MODEL | Enable the experimental subagent model pool in every launch mode, including the interactive TUI; the master JARVIS_CODE_EXPERIMENTAL_FLAG=1 also enables it | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_SECONDARY_MODEL | Secondary model; takes higher priority than [secondary_model] model in config.toml. When the secondary-model experiment is enabled, newly spawned subagents (Agent / AgentSwarm) bind to it by default instead of inheriting the main agent's model | The alias of a configured [models] entry, e.g. jarvis-code/kimi-for-coding; blank values are ignored |
JARVIS_SECONDARY_EFFORT | Thinking effort for the secondary model; takes higher priority than [secondary_model] default_effort in config.toml and applies only when both the model and its experiment are enabled | An effort value, e.g. low; blank values are ignored |
JARVIS_CODE_EXPERIMENTAL_SUBAGENT_FORK | Enable the experimental fork parameter on the Agent and AgentSwarm tools, letting the model start a subagent with a snapshot of the calling agent's conversation history instead of an empty context; the master JARVIS_CODE_EXPERIMENTAL_FLAG=1 also enables it | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_MCP_STARTUP_TIMEOUT_MS | Global default connection timeout (ms) for all MCP servers; takes higher priority than [mcp] startup_timeout_ms in config.toml, but a per-server startupTimeoutMs in mcp.json still wins (default 30000) | Integer from 1 to 2147483647; invalid values are ignored |
JARVIS_MCP_TOOL_TIMEOUT_MS | Global default single tool-call timeout (ms) for all MCP servers; takes higher priority than [mcp] tool_timeout_ms in config.toml, but a per-server toolTimeoutMs in mcp.json still wins (default 60000) | Integer from 1 to 2147483647; invalid values are ignored |
JARVIS_LOOP_MAX_STEPS_PER_TURN | Maximum Agent steps per turn; takes higher priority than [loop_control] max_steps_per_turn in config.toml (unset or 0 means unlimited) | Non-negative integer; invalid values are ignored |
JARVIS_LOOP_MAX_ATTEMPTS_PER_STEP | Maximum total attempts for a failing step (including the initial attempt); takes higher priority than [loop_control] max_attempts_per_step in config.toml (default 10). The deprecated JARVIS_LOOP_MAX_RETRIES_PER_STEP is still honored with a warning when this variable is unset | Non-negative integer; invalid values are ignored |
JARVIS_CODE_INFINITE_RETRY | Retry every failed LLM request indefinitely — turn steps and background operations such as compaction alike — instead of failing the task; waits use exponential backoff (capped at 32 s) and honor the server's Retry-After header, and aborting still cancels immediately. Intended for long-running unattended evaluations against endpoints that may fail temporarily | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_TOKEN_COUNTING_STRATEGY | Which context token count is reported externally (the context-size display); takes higher priority than [token_counting] strategy in config.toml (default measured+estimated) | measured+estimated, measured, estimated (case-insensitive); invalid values are ignored |
JARVIS_WEB_SEARCH_BASE_URL | API URL of the web search (WebSearch) service; takes higher priority than [services.moonshot_search] base_url in config.toml, and enables the service without that config section. Persisted credentials and custom headers are not forwarded to an env-selected endpoint | Non-blank string; blank values are ignored |
JARVIS_WEB_SEARCH_API_KEY | API key of the web search (WebSearch) service; replaces both the configured API key and OAuth credential when set | Non-blank string; blank values are ignored |
JARVIS_WEB_FETCH_BASE_URL | API URL of the web fetch (FetchURL) service; takes higher priority than [services.moonshot_fetch] base_url. Persisted credentials and custom headers are not forwarded to an env-selected endpoint. Without an env or config endpoint, signed-in users try the managed Kimi OAuth fetch service before direct local requests | Non-blank string; blank values are ignored |
JARVIS_WEB_FETCH_API_KEY | API key of the web fetch (FetchURL) service; replaces both the configured API key and OAuth credential when set | Non-blank string; blank values are ignored |
JARVIS_BRAVE_BASE_URL | API URL of the Brave Search backend; takes higher priority than [services.brave] base_url in config.toml. Persisted credentials and custom headers are not forwarded to an env-selected endpoint. Read by the default agent-core-v2 engine only | Non-blank string; blank values are ignored |
JARVIS_BRAVE_API_KEY | API key of the Brave Search backend; takes higher priority than [services.brave] api_key. Requires active_search_provider = "brave" to serve WebSearch. Read by the default agent-core-v2 engine only | Non-blank string; blank values are ignored |
JARVIS_CODE_EXPERIMENTAL_FLAG | Master switch: enable every registered experimental feature for this process; it does not select the agent engine. See Experimental flags | 1, true, yes, on |
JARVIS_CODE_EXPERIMENTAL_TOWER | Enable Tower mode; engine v2 only, and a restart is required after enabling | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE | Enable AI-generated session titles; requires a managed OAuth login | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_EXPERIMENTAL_TOOL_SELECT | Enable progressive tool disclosure so MCP tool schemas load on demand; legacy engine only | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL | Use the minidb-backed read model for session indexing and wire replay; on by default | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_EXPERIMENTAL_SEARCH_WORKER | Run the global search index in a dedicated worker thread; on by default | Truthy: 1/true/yes/on; falsy: 0/false/no/off |
JARVIS_CODE_LEGACY_FLAG | Use the legacy agent-core engine for jarvis, jarvis -p, jarvis doctor, jarvis acp, jarvis export, and jarvis provider; these commands use agent-core-v2 by default | 1, true, yes, on |
JARVIS_SHELL_PATH | Override the Git Bash path on Windows (used when auto-detection fails) | Absolute path |
JARVIS_MODEL_MAX_COMPLETION_TOKENS | Hard cap on max_completion_tokens per LLM step; applies to the kimi provider only | Positive integer; 0 or negative disables clamping |
JARVIS_MODEL_TEMPERATURE | Sampling temperature for every request; applies to the kimi provider only (global — independent of JARVIS_MODEL_NAME) | Number, e.g. 0.3 |
JARVIS_MODEL_TOP_P | Nucleus-sampling top_p for every request; applies to the kimi provider only (global) | Number, e.g. 0.95 |
JARVIS_MODEL_THINKING_EFFORT | Force a specific thinking effort on the wire (thinking.effort), bypassing the model's declared support_efforts; applies to the kimi provider only, and only while Thinking is on | An effort value, e.g. max |
JARVIS_MODEL_THINKING_KEEP | Preserved-thinking passthrough; on kimi sent as thinking.keep, on anthropic (Claude and Kimi's Anthropic-compatible mode) sent as a context_management clear_thinking_20251015 edit (enabling keep routes Anthropic requests to the beta Messages API); overrides [thinking] keep (which defaults to "all"); only injected while Thinking is on | A value the API accepts, e.g. all; an off-value (false/0/no/off/none/null) disables it |
JARVIS_VISUAL_MODEL | Alias of the visual model used for image / screenshot / video inspection tasks; takes higher priority than [visual_model] model in config.toml. While set, it never leaks into config.toml. Read by the default agent-core-v2 engine only | Alias of a configured [models] entry |
JARVIS_VISUAL_EFFORT | Thinking effort applied when visual tasks bind the visual model; takes higher priority than [visual_model] default_effort | An effort value, e.g. low |
JARVIS_CODE_NO_AUTO_UPDATE | Fully disable the update preflight — no check, background install, or prompt. Legacy alias JARVIS_CLI_NO_AUTO_UPDATE is also honored | Truthy: 1/true/yes/on |
JARVIS_DISABLE_CRON | Disable the scheduled-task tool (CronCreate rejects new schedules; existing tasks do not fire) | 1 to disable |
The JARVIS_CODE_INFINITE_RETRY, JARVIS_CODE_IDENTITY_*, and JARVIS_CODE_BUILTIN_PRODUCT_SKILLS variables are read by the default agent-core-v2 engine. The legacy jarvis / jarvis -p path selected with JARVIS_CODE_LEGACY_FLAG=1 ignores them. Conversely, JARVIS_SECONDARY_MODEL and JARVIS_SECONDARY_EFFORT are read by the legacy engine only, and the default engine ignores them. JARVIS_CODE_EXPERIMENTAL_SECONDARY_MODEL is read by both engines: it gates the v2 subagent model pool and the legacy secondary-model recipe.
Experimental flags
Experimental features are registered per engine domain and each one declares its own environment variable. JARVIS_CODE_EXPERIMENTAL_FLAG=1 is the master switch that enables every registered flag for the process; it does not select the agent engine. A flag that defaults to on is turned off by setting its variable to a falsy value.
| Flag id | Environment variable | Default | What it does |
|---|---|---|---|
tower | JARVIS_CODE_EXPERIMENTAL_TOWER | off | Tower mode: coordinate several agents on one objective, toggled with /tower. Engine v2 only, and a restart is required after enabling |
secondary-model | JARVIS_CODE_EXPERIMENTAL_SECONDARY_MODEL | off | The subagent model pool. Read by both engines |
subagent-fork | JARVIS_CODE_EXPERIMENTAL_SUBAGENT_FORK | off | The fork parameter on the Agent and AgentSwarm tools, starting a subagent from a snapshot of the caller's history |
auto_session_title | JARVIS_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE | off | AI-generated session titles through the managed chat_title tool. Requires a managed OAuth login |
tool-select | JARVIS_CODE_EXPERIMENTAL_TOOL_SELECT | off | Progressive tool disclosure: keep MCP tool schemas out of the top-level tool list and let the model load them on demand. Legacy engine only |
persistence_minidb_readmodel | JARVIS_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL | on | Use the minidb-backed read model for session indexing and wire replay |
search_worker | JARVIS_CODE_EXPERIMENTAL_SEARCH_WORKER | on | Run the global search index in a dedicated worker thread instead of the server main thread |
Flags can also be set in the [experimental] section of config.toml, or toggled from the /experiments panel in the TUI. The environment variable takes priority over the config file.
Diagnostic logs
These variables control log level and file rotation, read once at process startup:
| Variable | Purpose | Default |
|---|---|---|
JARVIS_LOG_LEVEL | Log level: off, error, warn, info, debug | info |
JARVIS_LOG_GLOBAL_MAX_BYTES | Maximum bytes per global log file | 6291456 (6 MB) |
JARVIS_LOG_GLOBAL_FILES | Number of global log files to retain | 5 |
JARVIS_LOG_SESSION_MAX_BYTES | Maximum bytes per session log file | 5242880 (5 MB) |
JARVIS_LOG_SESSION_FILES | Number of session log files to retain | 3 |
System environment variables
The CLI also reads several standard system variables to detect the runtime environment; it does not modify them:
HOME: used to resolve the default data pathVISUAL,EDITOR: external editor command (VISUALtakes precedence)PATH: used to locate dependencies such asrg,fd,fdfind, andgit; on Windows, Git Bash detection checks eachgit.exefound onPATH, including package-manager shims such as ScoopNO_COLOR,FORCE_COLOR: control color output (following the no-color.org convention)CI: when non-empty and not"0", disables theme detection and falls back to the dark themeTERM_PROGRAM,TERM,TMUX: detect terminal features and notification supportDISPLAY,WAYLAND_DISPLAY,XDG_SESSION_TYPE: detect Linux graphical sessions (for clipboard and image features)WSL_DISTRO_NAME,WSLENV: detect WSL for the clipboard PowerShell bridgeLOCALAPPDATA: used on Windows as a fallback when probing for the Git Bash installation path
HTTP proxy
Jarvis Code honors the standard proxy environment variables for all outbound traffic — model API calls, MCP servers, web tools, telemetry, sign-in, and update checks:
HTTP_PROXY/http_proxy: proxy forhttp://requestsHTTPS_PROXY/https_proxy: proxy forhttps://requestsALL_PROXY/all_proxy: fallback proxy used when the scheme-specific variable is unset; this is where a SOCKS proxy is usually setNO_PROXY/no_proxy: comma-separated hosts that bypass the proxy
Both HTTP(S) and SOCKS proxies are supported. A SOCKS proxy is recognized by its scheme — socks5://, socks5h://, socks4://, or socks:// (an alias for socks5://) — and is typically set via ALL_PROXY (the form used by tools like Clash and V2RayN). An HTTP(S) proxy takes precedence over ALL_PROXY for HTTP/HTTPS traffic.
The proxy is applied only when one of these variables is set; otherwise connections are made directly. Loopback hosts (localhost, 127.0.0.1, ::1) always bypass the proxy, so a local server such as a localhost MCP server keeps working when a proxy is configured — add your own internal hosts to NO_PROXY to exempt them too.
Stdio MCP servers that run as Node child processes honor HTTP_PROXY / HTTPS_PROXY / NO_PROXY automatically when the child's Node version supports NODE_USE_ENV_PROXY (Node ≥ 22.21 or ≥ 24.5); SOCKS proxying applies to Jarvis Code's own traffic only.
Next steps
- Config overrides — how environment variables, CLI options, and the config file interact by priority
- Data locations — directory structure affected by
JARVIS_CODE_HOME - Providers and models — full connection examples per provider type