# Configuration reference

> Config keys, environment variables, defaults, required values, and where each one is read.

- Repository: egoist/lorca
- GitHub: https://github.com/egoist/lorca
- Human docs: https://grok-wiki.com/public/docs/egoist-lorca-2cf67495e5e6
- Complete Markdown: https://grok-wiki.com/public/docs/egoist-lorca-2cf67495e5e6/llms-full.txt

## Source Files

- `crates/cli/src/config.rs`
- `.env.example`
- `web/content/docs/cli.mdx`

---

---
title: "Configuration reference"
description: "Config keys, environment variables, defaults, required values, and where each one is read."
---

Lorca configuration splits across four surfaces: Device CLI env + `~/.lorca/settings.json`, `lorca-relay` flags/env, install-script env, and macOS/mobile launch overrides. Set `LORCA_HOME` and `LORCA_RELAY_URL` first for a Runner; everything else is optional.

## Config surfaces

| Surface | Who reads it | Persist? |
| --- | --- | --- |
| CLI flags `--home`, `--port` | `lorca` | No (process) |
| `LORCA_*` env on the Device | `lorca`, bash tool, providers | No |
| `$LORCA_HOME/settings.json` | `Settings` in the CLI | Yes (mode `0600`) |
| Pairing / `machine.json` relay URL | `App::relay_url` | Yes |
| `lorca-relay` flags + `LORCA_RELAY_*` | Relay process | Deploy config |
| `.env` (repo root) | Bun `dev` / `relay` scripts; relay process when launched that way | Local only |
| macOS app launch env | `CLILauncher` → child `lorca` | App defaults + env |

```text
Device Runner                         Relay host
─────────────────                     ─────────────────
LORCA_HOME / --home                   LORCA_RELAY_BIND / --bind
LORCA_PORT / --port                   LORCA_RELAY_DB / --db
settings.json                         LORCA_RELAY_SECRET
  relay_url, marketplace_url          files dir or S3 + push keys
LORCA_RELAY_URL (wins)                .env.example documents push/secret
LORCA_DEFAULT_RELAY_URL (fallback)
credentials.json (provider keys)
```

## Device home layout

Default home: `~/.lorca` (`~/.lorca-dev` when the macOS Dev app launches the CLI). Override with `--home` or `LORCA_HOME`.

| Path under home | Role |
| --- | --- |
| `identity.json` | Identity keys |
| `machine.json` | This Device; may store relay URL from pairing |
| `credentials.json` | Provider API keys / OAuth tokens |
| `lorca.sqlite3` | Local DB |
| `settings.json` | Runtime settings (`relay_url`, `marketplace_url`) |
| `files/` | Attachment bytes |
| `plugins/` | Installed plugins + secrets |
| `workspaces/<bot-id>/` | Per-bot workspace / memory |

`ensure_home` creates the directory and sets Unix mode `0700` on the home dir; JSON writes use `0600`.

## `settings.json`

Loaded from `Config::settings_path()`. Missing file → empty defaults.

<ParamField body="relay_url" type="string | null">
Saved relay URL. Trimmed; trailing `/` stripped. Overridden by `LORCA_RELAY_URL` when that env is non-empty.
</ParamField>

<ParamField body="marketplace_url" type="string | null">
Extra marketplace index URL listed beside the bundled index. Wins over `LORCA_MARKETPLACE_URL`.
</ParamField>

Change relay at runtime via the app **Settings › Advanced › Relay URL**, or the local API that calls `App::set_relay_url` (writes `settings.json` and forgets the relay bearer token).

## Relay URL resolution

Effective URL for sync / pairing (highest wins):

1. `LORCA_RELAY_URL` (non-empty after trim)
2. `settings.json` → `relay_url`
3. `machine.json` relay URL stored at pairing
4. If `LORCA_DEV` is set and not `0`: `http://<LAN-IPv4>:8787` (`DEV_RELAY_PORT`)
5. `LORCA_DEFAULT_RELAY_URL` (macOS production app injects `https://relay.lorca.app` when unset)

No URL → single-Device mode. `lorca doctor` reports relay as not configured; `lorca identity restore` needs a relay.

## Device CLI environment

Global flags also bind these env vars (`lorca --help`).

### Core

| Variable | Default | Read in |
| --- | --- | --- |
| `LORCA_HOME` | `~/.lorca` | `Config::load`, CLI `--home` |
| `LORCA_PORT` | `4862` | `Config::load`, CLI `--port`; macOS Dev default port is `4863` via app prefs |
| `LORCA_RELAY_URL` | unset | `Settings::effective_relay_url` / `App::relay_url` |
| `LORCA_DEFAULT_RELAY_URL` | unset (prod app sets production relay) | `default_relay_url()` |
| `LORCA_DEV` | unset | `dev_relay_url()`; `scripts/dev.ts` sets `1` on the app |
| `LORCA_SHELL` | `/bin/bash` if present else `/bin/sh`; Windows: Git for Windows `bash.exe` or `bash` | `BashTool::new` |
| `LORCA_MARKETPLACE_URL` | unset | Marketplace index fetch (after settings) |
| `LORCA_COMPACTION` | on (any value except `0`) | `turns.rs`; `0` disables compaction |
| `LORCA_MEMORY_FLUSH` | on | `0` disables pre-compaction memory flush |
| `LORCA_OAUTH_NO_BROWSER` | unset | `1` skips opening a browser for MCP OAuth |

### Provider model defaults

Used when a bot does not pick a model. Built-in fallbacks if env is also unset:

| Variable | Built-in default |
| --- | --- |
| `LORCA_DEEPSEEK_MODEL` | `deepseek-flash` |
| `LORCA_ANTHROPIC_MODEL` | `claude-opus-5` |
| `LORCA_CHATGPT_MODEL` | `gpt-6-sol` |
| `LORCA_GROK_MODEL` | `grok-4.7` |
| `LORCA_OPENCODE_MODEL` | `deepseek-v4.1-flash` |
| `LORCA_OPENCODE_GO_MODEL` | `glm-5.3-flash` |

### Provider base URLs / issuers

Credential `base_url` wins when set. Else env, else built-in root:

| Variable | Default root |
| --- | --- |
| `LORCA_DEEPSEEK_BASE_URL` | `https://api.deepseek.com` (Anthropic-compatible path `/anthropic` appended when missing) |
| `LORCA_ANTHROPIC_BASE_URL` | `https://api.anthropic.com` |
| `LORCA_OPENCODE_BASE_URL` | `https://opencode.ai/zen` |
| `LORCA_OPENCODE_GO_BASE_URL` | `https://opencode.ai/zen/go` |
| `LORCA_GROK_BASE_URL` | provider default unless set |
| `LORCA_GROK_ISSUER` | xAI OAuth endpoints unless set |

Provider **secrets** live in `credentials.json` via `lorca provider set` / app Settings — not in these env vars on the Device CLI path.

<Note>
The `lorca_agent` library’s `EnvProviderFactory` is a separate BYOK surface for embedding the agent crate: `DEEPSEEK_API_KEY`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, plus `DEEPSEEK_BASE_URL` / `ANTHROPIC_BASE_URL` / `OPENAI_BASE_URL` / `GROK_BASE_URL`. The shipping CLI does not use those names for account credentials.
</Note>

## `lorca-relay` configuration

Every flag has a matching env var (`lorca-relay --help`). CLI flag wins over env when both are passed through the usage parser.

### Required for durable multi-Device deploys

| Variable / flag | Default | Notes |
| --- | --- | --- |
| `LORCA_RELAY_SECRET` / `--secret` | random per boot | **Set in production.** Unset → every restart logs Devices out |
| `LORCA_RELAY_BIND` / `--bind` | `127.0.0.1:8787` | Docker/Railway: image uses `[::]:$PORT` when bind unset |
| `LORCA_RELAY_DB` / `--db` | `lorca-relay.db` | SQLite path or `postgres://…` URL |

### Limits and housekeeping

| Variable | Default | Meaning |
| --- | --- | --- |
| `LORCA_RELAY_QUOTA_BYTES` | `5368709120` (5 GiB) | Per-identity ciphertext cap; `0` = none |
| `LORCA_RELAY_IP_PER_MINUTE` | `60` | Unauthed routes; burst = same; `0` = off |
| `LORCA_RELAY_IDENTITY_PER_SECOND` | `50` | Authed; burst 10×; `0` = off |
| `LORCA_RELAY_MIN_PROTOCOL` | `0` | Older clients get `426` |
| `LORCA_RELAY_INACTIVE_DAYS` | `365` | Delete idle identities; `0` = keep |
| `LORCA_RELAY_CONCURRENT_UPLOADS` | `3` | Large uploads at once; `0` = off |
| `LORCA_RELAY_TRUST_PROXY` | `false` | Use last `X-Forwarded-For` hop; set only behind a rewriting proxy |
| `LORCA_RELAY_METRICS_TOKEN` | unset | Enables `GET /metrics` with that bearer; unset → no route |

### File storage

| Variable | Default / constraint |
| --- | --- |
| `LORCA_RELAY_FILES_DIR` | DB path with `.files` extension; conflicts with S3 |
| `LORCA_RELAY_S3_BUCKET` | Requires `--s3-endpoint` / `LORCA_RELAY_S3_ENDPOINT` |
| `LORCA_RELAY_S3_ENDPOINT` | Required with bucket |
| `LORCA_RELAY_S3_REGION` | `auto` |
| `LORCA_RELAY_S3_PREFIX` | `""` |
| `LORCA_RELAY_S3_ACCESS_KEY` | Falls back to `AWS_ACCESS_KEY_ID` |
| `LORCA_RELAY_S3_SECRET_KEY` | Falls back to `AWS_SECRET_ACCESS_KEY` |

Postgres multi-replica deploys need shared `LORCA_RELAY_SECRET` and S3-compatible attachment storage.

### Push notifications

Documented in `.env.example`. Keys may be file paths or inline text (`-----BEGIN…` or `{…}` JSON).

| Variable | Required with | Default |
| --- | --- | --- |
| `LORCA_RELAY_APNS_KEY` | key id + team id | — |
| `LORCA_RELAY_APNS_KEY_ID` | with key | — |
| `LORCA_RELAY_APNS_TEAM_ID` | with key | — |
| `LORCA_RELAY_APNS_TOPIC` | — | `app.lorca` (dev scripts use `app.lorca.dev`) |
| `LORCA_RELAY_FCM_SERVICE_ACCOUNT` | — | — |
| `LORCA_RELAY_APNS_URL` | tests only | production APNs |
| `LORCA_RELAY_FCM_URL` | tests only | production FCM |

Without push keys, sync still works; phones get no push.

### Test-only relay env

| Variable | Use |
| --- | --- |
| `LORCA_RELAY_TEST_POSTGRES` | Integration tests against Postgres |
| `LORCA_RELAY_TEST_S3` | MinIO/S3 test endpoint |
| `LORCA_RELAY_TEST_S3_KEYS` | `access:secret` for that endpoint |

## Install script environment

`web/public/install-cli.sh` and `install-cli.ps1`:

| Variable | Default | Effect |
| --- | --- | --- |
| `LORCA_VERSION` | latest release | Pin version (`1.0.0`) |
| `LORCA_INSTALL_DIR` | `~/.local/bin` | Binary destination |
| `LORCA_NO_MODIFY_PATH` | unset | `1` = do not edit shell PATH |
| `LORCA_DOWNLOAD_URL` | GitHub releases base | Mirror / alternate releases root |
| `LORCA_HOME` | `~/.lorca` | Installer checks for existing `machine.json` |

## macOS app and mobile build

| Variable | Reader | Effect |
| --- | --- | --- |
| `LORCA_HOME` | `CLILauncher` | Defaults to `~/.lorca` or `~/.lorca-dev` for Dev bundle |
| `LORCA_DEFAULT_RELAY_URL` | `CLILauncher` | Prod app sets `https://relay.lorca.app` if unset |
| `LORCA_PORT` | `Preferences.cliPort` | Overrides stored CLI port |
| `LORCA_CLI` | `CLILaunchWorker` | Path to `lorca` binary override |
| `LORCA_MOCK` | `AppStore` | `1` = mock mode |
| `LORCA_TRACE_STARTUP` | `StartupTrace` | `1` = launch timings |
| `RUST_LOG` | `CLILauncher` | Defaults to `lorca=info` for the child |
| `LORCA_MOBILE_VARIANT` | `mobile/app.config.ts` | `development` → dev client |
| `LORCA_IOS_BUILD_NUMBER` | `app.config.ts` / release script | iOS build number (default `"1"`) |

## Quick verification

<Steps>
<Step title="Check Device config">
Run `lorca doctor`. Expect home, identity, port, and relay checks; missing relay is OK for single-Device use.
</Step>
<Step title="Confirm effective relay">
Run `lorca status` and inspect the JSON for relay / device state after setting `LORCA_RELAY_URL` or `settings.json`.
</Step>
<Step title="Confirm relay process">
`curl http://127.0.0.1:8787/v1/health` → `{"ok":true,"service":"lorca-relay"}` (adjust host/port to your bind).
</Step>
</Steps>

<Warning>
Unset `LORCA_RELAY_SECRET` on a public relay invalidates every Device token on each restart. Set a stable secret before pairing phones or extra Runners.
</Warning>

## Related pages

<CardGroup>
<Card title="CLI reference" href="/cli-reference">
Commands, flags, and doctor/status behavior for `lorca`.
</Card>
<Card title="crates/relay reference" href="/ref-crates-relay">
Relay binary exports, storage modes, and error cases.
</Card>
<Card title="Deployment and operations" href="/deployment">
Build, containerize, and run relay environments.
</Card>
<Card title="Installation" href="/installation">
Install CLI / app and first-run success signals.
</Card>
</CardGroup>

Next: open `~/.lorca/settings.json` (or set `LORCA_RELAY_URL`) and run `lorca doctor` to confirm the Device sees the intended home and relay.
