# Configuration
Source: https://dorkos.ai/docs/getting-started/configuration

Environment variables and configuration options for DorkOS





# Configuration [#configuration]

DorkOS works out of the box. Most people never open this page again after their first session: no ports to pick, no files to edit, nothing to tune. This page exists for the day you need to change one specific thing, a port conflict, a tunnel so you can check on an agent from your phone, a different AI provider.

The one setting worth knowing on day one is `ANTHROPIC_API_KEY`, and the [Installation guide](/docs/getting-started/installation) already walks you through setting it. Everything below is reference: skip to the section you need and ignore the rest.

DorkOS reads settings from three places, in this order: CLI flags (what you type when you start DorkOS), environment variables (settings you export in your terminal, or put in a `.env` file next to where you run DorkOS), and the config file at `~/.dork/config.json` (DorkOS writes this itself; you rarely need to touch it by hand). If a setting appears in more than one place, the first one found wins. For example, to try a different port for one run without changing anything permanent:

```bash
DORKOS_PORT=5000 dorkos
```

<Callout type="info">
  Setting order: CLI flags win first, then environment variables, then `~/.dork/config.json`, then
  DorkOS's built-in defaults.
</Callout>

## Required [#required]

<TypeTable
  type="{
  ANTHROPIC_API_KEY: {
    description: 'Your Anthropic API key. Required to start any Claude Code session.',
    type: 'string',
  },
}"
/>

## Optional [#optional]

<TypeTable
  type="{
  DORKOS_PORT: {
    description: 'Port for the DorkOS server.',
    type: 'number',
    default: '4242',
  },
  DORKOS_DEFAULT_CWD: {
    description:
      'The folder DorkOS treats as its working directory for new sessions. Defaults to the folder you run `dorkos` from.',
    type: 'string',
    default: 'Current directory',
  },
  DORKOS_BOUNDARY: {
    description:
      'A directory boundary: DorkOS refuses to read or write anywhere outside this folder and its subfolders. Defaults to your home directory.',
    type: 'string',
    default: 'Home directory',
  },
  DORKOS_LOG_LEVEL: {
    description:
      'Log verbosity, as a number from 0 (quietest) to 5 (noisiest). Leave it unset unless you are debugging.',
    type: 'number (0-5)',
  },
}"
/>

## Reference [#reference]

Everything below is deep reference. Most people never touch it, it's here for the day you need it.

### Tunnel Configuration [#tunnel-configuration]

DorkOS supports ngrok tunnels (a service that gives your local machine a public URL) for remote access from any device. See the [Tunnel Setup](/docs/self-hosting/tunnel-setup) guide for full details.

<TypeTable
  type="{
  TUNNEL_ENABLED: {
    description: 'Set to `true` to enable the ngrok tunnel on startup.',
    type: 'boolean',
    default: 'false',
  },
  NGROK_AUTHTOKEN: {
    description: 'Your ngrok authentication token.',
    type: 'string',
  },
  TUNNEL_DOMAIN: {
    description: 'Custom tunnel domain (requires a paid ngrok plan).',
    type: 'string',
  },
  TUNNEL_AUTH: {
    description: 'Basic auth credentials for the tunnel in `user:pass` format.',
    type: 'string',
  },
}"
/>

<Callout type="warn">
  Always set `TUNNEL_AUTH` when exposing DorkOS publicly via a tunnel. Without it, anyone with the
  tunnel URL can access your sessions.
</Callout>

### Relay Configuration [#relay-configuration]

Relay is the messaging layer that lets agents reach you on Telegram, notify each other, and connect to external channels. See the [Relay Messaging guide](/docs/guides/relay-messaging) for setup details.

<TypeTable
  type="{
  DORKOS_RELAY_ENABLED: {
    description:
      'Enable the Relay messaging layer for inter-agent communication. Adapter configuration lives in `~/.dork/config.json` under the `relay` key.',
    type: 'boolean',
    default: 'true',
  },
}"
/>

### Tasks Configuration [#tasks-configuration]

Tasks runs agent jobs on a schedule (like "every night at 2am"), on their own, without you keeping a terminal open. See the [Task Scheduler guide](/docs/guides/task-scheduler) for setup details.

<TypeTable
  type="{
  DORKOS_TASKS_ENABLED: {
    description: 'Enable the Tasks scheduler for autonomous cron-based agent execution.',
    type: 'boolean',
    default: 'true',
  },
}"
/>

### A2A Gateway [#a2a-gateway]

The A2A gateway exposes your DorkOS agents to external A2A-compatible clients (other agent frameworks, orchestrators, or tools that speak Google's Agent-to-Agent protocol). Requires Relay to be enabled.

<TypeTable
  type="{
  DORKOS_A2A_ENABLED: {
    description:
      'Enable the A2A external gateway for cross-vendor agent communication. Requires `DORKOS_RELAY_ENABLED=true`. Auth reuses `MCP_API_KEY`.',
    type: 'boolean',
    default: 'false',
  },
}"
/>

### Mesh [#mesh]

Mesh is always on. It scans your projects for agent-capable directories and builds a discoverable registry without any additional configuration. See the [Agent Discovery guide](/docs/guides/agent-discovery) for details on registration and access control.

### Extensions [#extensions]

Extensions add UI, commands, and behavior to DorkOS. Core extensions ship with DorkOS and appear in Settings → Extensions under a "Core extensions" section, each with an enable or disable toggle. Extensions you install yourself appear under "Installed extensions". Toggling in the UI is all most people need. The underlying state lives in `~/.dork/config.json` under the `extensions` key.

DorkOS records only your **deviations** from each extension's default state, across two lists:

<TypeTable
  type="{
  'extensions.enabled': {
    description:
      'Extension IDs you turned on that ship off by default (the opt-in path). Covers installed extensions and any core extension that ships disabled.',
    type: 'string[]',
    default: '[]',
  },
  'extensions.disabled': {
    description:
      'Extension IDs you turned off that ship on by default (the opt-out path). Only core extensions that ship enabled land here.',
    type: 'string[]',
    default: '[]',
  },
}"
/>

An extension absent from both lists uses its default: ships-on extensions stay on, ships-off extensions stay off. To turn a ships-on extension off, add its id to `disabled`; to turn a ships-off extension on, add its id to `enabled`.

<Callout type="warn">
  Adding a ships-on extension's id to `enabled` does nothing, since it's already on. To disable it,
  add the id to `disabled` instead.
</Callout>

### Runtimes [#runtimes]

DorkOS runs three agent runtimes: Claude Code (the default), Codex, and OpenCode. The `runtimes` block in `~/.dork/config.json` controls which ones are available and how their binaries are found. Running multiple runtimes side by side is shipped, but still getting real-world mileage, so treat multi-runtime setups as an area to watch rather than a fully settled feature. See the [Runtimes guide](/docs/guides/runtimes) for connecting and choosing runtimes.

<TypeTable
  type="{
  'runtimes.default': {
    description:
      'Runtime for new sessions that don’t specify one (explicit session picks and per-agent runtimes take precedence).',
    type: 'string',
    default: '&#x22;claude-code&#x22;',
  },
  'runtimes.opencode.enabled': {
    description: 'Register the OpenCode runtime on server startup.',
    type: 'boolean',
    default: 'true',
  },
  'runtimes.opencode.binaryPath': {
    description:
      'Absolute path to the `opencode` binary. When `null`, DorkOS resolves it from PATH.',
    type: 'string | null',
    default: 'null',
  },
  'runtimes.opencode.port': {
    description: 'Port for the managed `opencode serve` sidecar. `0` picks an ephemeral port.',
    type: 'number',
    default: '0',
  },
  'runtimes.opencode.provider': {
    description:
      'Selected provider id keying into the `providers` registry (e.g. `openrouter`, `openai`). `null` uses OpenCode host auth.',
    type: 'string | null',
    default: 'null',
  },
  'runtimes.opencode.baseURL': {
    description:
      'Optional OpenAI-compatible base URL for a Direct provider, injected into the sidecar as `OPENAI_BASE_URL`.',
    type: 'string | null',
    default: 'null',
  },
  'runtimes.codex.enabled': {
    description: 'Register the Codex runtime on server startup.',
    type: 'boolean',
    default: 'true',
  },
  'runtimes.codex.binaryPath': {
    description:
      'Absolute path to the `codex` binary. When `null`, DorkOS resolves it from PATH.',
    type: 'string | null',
    default: 'null',
  },
  'runtimes.codex.credentialRef': {
    description:
      'Credential reference for Codex’s API key (never a raw secret). `null` delegates to `codex login`.',
    type: 'string | null',
    default: 'null',
  },
}"
/>

<Callout type="info">
  DorkOS stores credentials **by reference**, never as plaintext in `config.json`. The top-level
  `providers` block maps a provider id to a reference: `keychain:<id>` (your operating system's
  built-in password manager), `env:<VAR>` (a process environment variable), or `file:<name>` (a
  DorkOS-owned encrypted secret store). The reference resolves to a real key at each runtime's
  startup, and a broken reference fails loudly instead of quietly sending an empty key. Claude
  reads `providers.anthropic`; OpenCode reads the provider selected by
  `runtimes.opencode.provider`. Codex never receives its key via a subprocess environment
  variable, so `runtimes.codex.credentialRef` feeds the delegated `codex login` path instead. Net
  effect: your API key never sits in a plain text file waiting to be read.
</Callout>

### Harness Sync [#harness-sync]

Harness Sync projects your `.agents/` definitions and installed marketplace plugins out to every agent harness. By default, installing or uninstalling a marketplace plugin re-runs this projection automatically.

<TypeTable
  type="{
  'harness.autoSync': {
    description:
      'Automatically run Harness Sync projection when a marketplace plugin is installed or uninstalled. Set to false to manage projection manually via `dorkos harness sync`.',
    type: 'boolean',
    default: 'true',
  },
}"
/>

### Local login [#local-login]

DorkOS runs with no login by default: no login screen, no user concept, instant start. Turning on local login creates an owner account (email + password) that is required to use the instance. The first registered user becomes the owner; further sign-ups are rejected until a future invites release reopens registration.

<TypeTable
  type="{
  'auth.enabled': {
    description:
      'Whether local login is required to use this instance. When false (the default), no login gate runs. The enable-login flow creates the owner account before flipping this to true.',
    type: 'boolean',
    default: 'false',
  },
}"
/>

Session cookies are signed by Better Auth. Production deployments should set the `BETTER_AUTH_SECRET` environment variable so sessions survive server restarts.

### Cloud link [#cloud-link]

Linking this instance to a DorkOS account lets the account see and manage it. Run `dorkos cloud login` to link (it prints a code to approve in your browser, and works even with no browser on the same machine), `dorkos cloud status` to check the link, and `dorkos cloud logout` to unlink. Local login and the cloud link are independent: either can exist without the other.

<TypeTable
  type="{
  'cloud.instanceToken': {
    description:
      'The scoped instance API key issued by the cloud when this instance is linked. Sensitive: the CLI and API warn when it is set by hand. null when not linked.',
    type: 'string | null',
    default: 'null',
  },
  'cloud.instanceName': {
    description:
      &#x22;This instance's display name registered with the cloud (typically the hostname).&#x22;,
    type: 'string | null',
    default: 'null',
  },
  'cloud.linkedAccountLabel': {
    description: 'Human-readable label of the linked DorkOS account, when the cloud reports one.',
    type: 'string | null',
    default: 'null',
  },
}"
/>

Set `DORKOS_CLOUD_URL` to point at a non-production cloud (defaults to `https://dorkos.ai`). While linked, the instance checks in with the cloud on startup and every 15 minutes. If the account revokes the instance, the next check-in clears the local token and the instance is unlinked.

### Uploads [#uploads]

Uploaded files (from chat, workbench, or anywhere else you attach a file) are stored under `.dork/.temp/uploads/` in your working directory, with limits you can adjust:

<TypeTable
  type="{
  'uploads.maxFileSize': {
    description: 'Maximum size for a single uploaded file, in bytes.',
    type: 'number',
    default: '10485760 (10 MB)',
  },
  'uploads.maxFiles': {
    description: 'Maximum number of files in a single upload.',
    type: 'number',
    default: '10',
  },
  'uploads.allowedTypes': {
    description:
      'File types allowed for upload, as MIME type patterns. `[&#x22;*/*&#x22;]` allows everything.',
    type: 'string[]',
    default: '[&#x22;*/*&#x22;]',
  },
}"
/>

### Telemetry [#telemetry]

DorkOS shares a little anonymous data by default. Two channels are on: a daily heartbeat and marketplace install counts, both genuinely anonymous (no prompts, code, paths, or session content). DorkOS shows a first-run notice and sends nothing on that first run, and you can turn it off any time with `dorkos telemetry disable`, `DO_NOT_TRACK=1`, or the Privacy & Data settings tab. Crash reporting is separate and stays off until you turn it on. See the full [telemetry contract](/docs/self-hosting/telemetry) for the exact payload.

<TypeTable
  type="{
  'telemetry.userHasDecided': {
    description:
      'True once you have answered a telemetry consent prompt either way. Stops the first-run banner from reappearing.',
    type: 'boolean',
    default: 'false',
  },
  'telemetry.heartbeat': {
    description:
      'Send an anonymous daily heartbeat to dorkos.ai (version, OS, configured runtimes, and rough counts). Never prompts, code, paths, or session content. Anonymous and opt-out; a first-run notice is shown before anything sends.',
    type: 'boolean',
    default: 'true',
  },
  'telemetry.install': {
    description:
      'Send anonymous marketplace install counts to dorkos.ai. Anonymous and opt-out; a first-run notice is shown before anything sends.',
    type: 'boolean',
    default: 'true',
  },
  'telemetry.errorReporting': {
    description:
      'Send scrubbed crash reports to dorkos.ai when something breaks, never a third party. A separate opt-in from the anonymous channels. Sends the error type and a cleaned stack trace, never the message, paths, or session data. See the telemetry page.',
    type: 'boolean',
    default: 'false',
  },
  'telemetry.lastPromptedVersion': {
    description:
      'The DorkOS version whose consent notice this install last saw, or null if never prompted. Used internally to decide when to ask again after a data-policy change. Set by the consent surfaces.',
    type: 'string | null',
    default: 'null',
  },
}"
/>

<Callout type="info">
  Two environment variables turn everything off no matter what these settings say: `DO_NOT_TRACK`
  and `DORKOS_TELEMETRY_DISABLED`. Set either to `1` and DorkOS sends nothing. `dorkos telemetry
    status` shows each channel and any override; `DORKOS_TELEMETRY_DEBUG=1` prints the exact payload
  to your terminal instead of sending it. See the [telemetry page](/docs/self-hosting/telemetry).
</Callout>

### Config Directory [#config-directory]

DorkOS creates `~/.dork/` on startup for configuration and state storage. Structured logs are written to `~/.dork/logs/dorkos.log`, one JSON entry per line.

Use `dorkos config path` to print the path to your config file, and `dorkos config list` to view all active settings.

## Next Steps [#next-steps]

<Cards>
  <Card title="CLI Usage" href="/docs/guides/cli-usage">
    Manage config via CLI subcommands: get, set, list, reset, edit.
  </Card>

  <Card title="Tunnel Setup" href="/docs/self-hosting/tunnel-setup">
    Access DorkOS remotely via ngrok tunnel.
  </Card>

  <Card title="Quickstart" href="/docs/getting-started/quickstart">
    Get up and running with your first session.
  </Card>
</Cards>
