Skip to content

Configuration

Since 0.9, configuration is split between two homes:

  • ~/.jarvis/config.yaml: system configuration only. The daemon treats it as read-only: daemon, auth, google, browser, timezone, cron.
  • The dashboard settings (stored in the database): everything user-facing. LLM providers and API keys (keys go to an encrypted keychain), voice/TTS/STT, channels, authority, heartbeat, awareness, personality, goals, workflows, sites.

If you add a user-owned section (like llm: or channels:) to config.yaml, it is not honored live: LLM blocks are ignored outright, and other user sections are imported into the settings database once at the next daemon restart, after which the database is the source of truth. Dashboard saves apply immediately with no restart (hot reload).

Usejarvis runs on built-in defaults if the file is absent. Create it by hand (start from config.example.yaml in the repo) when you need to change system settings. A file that exists but fails to parse is a fatal error, the daemon does not fall back to defaults.

daemon:
port: 3142
data_dir: "~/.jarvis"
db_path: "~/.jarvis/jarvis.db"
brain_domain: "https://jarvis.example.com" # external origin, explicit scheme
drain_deadline_ms: 75000 # graceful shutdown budget
auth:
insecure_open_access: false # setup-only escape hatch, see below
google:
client_id: "..." # OAuth client for Gmail/Calendar
client_secret: "..."
browser:
local: true # false on headless servers: browser actions route to sidecars
timezone: "Europe/Rome" # IANA zone for cron and goal windows

Where the daemon listens and stores data. brain_domain matters as soon as anything connects from another machine: enrollment tokens embed it, and a bare host:port without a scheme is treated as HTTPS, so set it explicitly. listen: "unix:/abs/path.sock" switches to a unix socket instead of TCP.

There is exactly one key: insecure_open_access. Access is JWT-only by default: enroll devices with jarvis enroll and connect through the sidecar. Setting insecure_open_access: true disables auth entirely for first-time setup; the daemon logs a loud warning the whole time it is on. Turn it back off after enrolling.

The old auth.token shared secret no longer exists and is ignored if present.

OAuth client credentials for Gmail and Calendar. The actual account authorization happens through the dashboard flow; only the client credentials live in the file.

local: false stops the daemon from ever launching a local Chromium; browser actions route to a connected sidecar’s browser. Recommended for headless servers and implied in Docker.

IANA timezone string so scheduled workflows and goal windows fire in your local time when the daemon runs on a UTC VPS.

JARVIS_PORT, JARVIS_HOME, JARVIS_BRAIN_DOMAIN, JARVIS_WAKE_ENGINE, JARVIS_REALTIME_VOICE, JARVIS_TELEMETRY. LLM provider configuration is intentionally not read from env vars.

Everything else lives in Settings in the dashboard and applies without a restart:

  • LLM: providers, API keys, single-model or multi-tier routing. See LLM Providers.
  • Voice: TTS, STT, wake engine, realtime voice. See Voice.
  • Channels: Telegram, Discord. See their pages.
  • Authority: autonomy level, governed categories, overrides. See Authority & Safety.
  • Awareness, heartbeat, personality, goals, workflows, sites: their respective rooms and settings tabs.

Telemetry is also user-owned: it defaults to on and can be disabled with telemetry.enabled: false, JARVIS_TELEMETRY=0, or DO_NOT_TRACK=1.

After the first successful start:

  1. Add your LLM provider and key in Settings → LLM
  2. Enroll your devices and turn insecure_open_access back off if you used it
  3. Review the authority level in Settings → Authority (default level 3)
  4. Enable TTS in Settings if you want voice output
  5. Set daemon.brain_domain before any remote sidecar joins

The daemon’s config is evaluated from the daemon’s network point of view, not your browser’s.

This matters especially for addresses like an Ollama base URL (Settings → LLM) or a local STT endpoint (Settings → Voice). If those point at http://localhost:..., that means localhost inside the container or on the VPS, not your laptop. See Troubleshooting for the common remote-host networking failure mode.