Skip to content

Environment variables·

Generated at every docs build by scripts/envdoc.py, which walks every os.getenv / os.environ in the repo. Purposes come from scripts/envdoc_notes.py; a variable without a note still gets a row (purpose ) so nothing can go undocumented silently — tests/test_docs.py asserts that.

Where they are set: your .env (see the walkthrough), the compose files (service-specific overrides), .tiny-mcp.env for the fleet token, and the cockpit's ⚙️ drawer for live edits of masked keys.

Rover·

variable default read by purpose
ROVER_CONTROLLER_ANGULAR_MAX 0.9 tools/_controller_engine.py PS4 teleop: cap on
ROVER_CONTROLLER_DEADZONE 0.08 tools/_controller_engine.py PS4 teleop: stick dead-zone (0.08).
ROVER_CONTROLLER_DEBUG 0 tools/_controller_engine.py 1 surfaces pygame/SDL warnings on stderr.
ROVER_CONTROLLER_HZ 10 tools/_controller_engine.py PS4 teleop: /control frames per second while sticks are held.
ROVER_CONTROLLER_LINEAR_MAX 0.7 tools/_controller_engine.py PS4 teleop: cap on
ROVER_CONTROLLER_LOG /tmp/rover_controller_sdl.log tools/_controller_engine.py Spool file for those warnings.
ROVER_HTTP_TIMEOUT 60 tools/_rover_common.py Seconds before an SDK HTTP call in _rover_common gives up.
ROVER_SDK_URL http://localhost:8002 dashboard_server.py, listener_loop.py, media_client.py, media_hub.py, tools/_rover_common.py, voice_agent.py Where every tool and the cockpit find the Earth Rovers SDK (http://localhost:8002 locally, http://sdk:8002 in compose).
ROVER_TURN_SIGN 1 tools/_rover_common.py Flip (-1) the agent tools' angular sign if the rover turns the wrong way; independent from the cockpit's DASH_TURN_SIGN.
SCOUT_ASYNC_FRAME_INTERVAL 0.35 tools/rover_async.py rover_async: seconds between /control frames streamed by the background worker (0.35).

Models·

variable default read by purpose
AWS_REGION us-east-1 voice_agent.py Bedrock region for the text model and Nova Sonic voice.
C3_GEN_MODEL nvidia/Cosmos3-Nano docker/warmup.py GPU stack: Cosmos 3 generator HF id to pre-download.
C3_MODEL nvidia/Cosmos3-Nano docker/warmup.py GPU stack: Cosmos 3 reasoner HF id to pre-download (default nvidia/Cosmos3-Nano).
GEMINI_API_KEY (unset) voice_agent.py Alternative to GOOGLE_API_KEY for Gemini Live.
GOOGLE_API_KEY (unset) voice_agent.py Gemini Live key (VOICE_PROVIDER=gemini); GEMINI_API_KEY is the alternative name.
HF_TOKEN (unset) docker/warmup.py Hugging Face token for model downloads during the GPU image warm-up.
OPENAI_API_KEY (unset) voice_agent.py OpenAI Realtime key for VOICE_PROVIDER=openai.

Voice·

variable default read by purpose
LISTENER_COOLDOWN_SEC 2 listener_loop.py Minimum gap between two agent triggers.
LISTENER_CUDA auto listener_loop.py cpu forces CPU inference; anything else tries CUDA.
LISTENER_DISABLED 0 listener_loop.py 1 = the listener loop exits immediately.
LISTENER_ENERGY_THRESHOLD 0.012 listener_loop.py RMS (0..1) above which a frame counts as speech.
LISTENER_MAX_SEG_SEC 12 listener_loop.py Hard cap on a single utterance.
LISTENER_MIC_RATE 16000 listener_loop.py Mic sample rate the listener drains at (16 kHz).
LISTENER_MIN_CHARS 4 listener_loop.py Ignore transcripts shorter than this.
LISTENER_MIN_SEG_SEC 0.6 listener_loop.py Drop segments shorter than this.
LISTENER_SILENCE_SEC 0.8 listener_loop.py Trailing silence that ends an utterance.
LISTENER_USE_HUB 1 listener_loop.py 1 (default) reads the mic through the MediaHub instead of draining /rover-mic directly.
LISTENER_VAD_AGGRESSIVENESS 2 listener_loop.py webrtcvad aggressiveness 0–3.
LISTENER_WAKE_WORD (unset) listener_loop.py Only trigger when the transcript contains this phrase (e.g. hey scout).
LISTENER_WHISPER_MODEL base.en listener_loop.py faster-whisper model id (base.en).
ROVER_AEC_DELAY_MS 150 voice_agent.py Voice: far-end delay hint for AEC — the rover's speaker→mic round trip (150 ms).
ROVER_AEC_RATE 48000 voice_agent.py Voice (rover audio): pywebrtc echo-canceller sample rate (48 kHz; the model runs at 24 kHz).
ROVER_GATE_TAIL_S 0.6 voice_agent.py Voice: how long the mic stays muted after the model stops speaking (half-duplex gate tail, 0.6 s).
SCOUT_BRIEFING_DEBOUNCE_S 4.0 voice_agent.py Voice bridge: coalesce briefings that arrive within this window into one text turn (4 s).
SCOUT_BRIEFING_GATE_TIMEOUT_S 15.0 voice_agent.py Voice bridge: give up waiting for the in-flight response to end after this many seconds (15 s).
SCOUT_BRIEFING_MAX_HOLD_S 20.0 voice_agent.py Voice bridge: never hold a briefing longer than this while waiting for a quiet moment (20 s).
SCOUT_BRIEFING_MUTE_SOURCES (unset) voice_agent.py Comma list of personas whose briefings are dropped unless URGENT (compose default thinker).
VOICE_AUDIO laptop voice_agent.py laptop (local mic/speakers) or rover (the rover's mic + speaker over the SDK) — default for --audio.
VOICE_MODEL (unset) voice_agent.py Realtime model id override (e.g. gpt-realtime-2).
VOICE_NAME (unset) dashboard_server.py, voice_agent.py Voice inside the provider (marin, shimmer, matthew, Kore…).
VOICE_PROVIDER openai dashboard_server.py, personas.py, voice_agent.py openai · nova_sonic · gemini — which bidi speech model the voice persona builds.

Telegram·

variable default read by purpose
SCOUT_TELEGRAM_ALLOWED_USERS (unset) telegram_listener.py, tools/telegram.py Comma list of Telegram user ids allowed to command the rover (empty = anyone — don't).
SCOUT_TELEGRAM_BOT_TOKEN (unset) telegram_listener.py, tools/telegram.py Bot token from @BotFather (preferred name).
SCOUT_TELEGRAM_DEFAULT_CHAT_ID (unset) tools/telegram.py Chat the telegram tool and the thinker post to when none is given.
SCOUT_TELEGRAM_HISTORY_LIMIT (unset) telegram_listener.py How many past messages the Telegram persona keeps in context.
TELEGRAM_ALLOWED_USERS (any) telegram_listener.py, tools/telegram.py Legacy name for SCOUT_TELEGRAM_ALLOWED_USERS.
TELEGRAM_BOT_TOKEN (unset) telegram_listener.py, tools/telegram.py Legacy name for SCOUT_TELEGRAM_BOT_TOKEN.
TELEGRAM_DEFAULT_CHAT_ID (unset) thinker_loop.py, tools/telegram.py Legacy name for SCOUT_TELEGRAM_DEFAULT_CHAT_ID.
TELEGRAM_HISTORY_LIMIT 20 telegram_listener.py Legacy name for SCOUT_TELEGRAM_HISTORY_LIMIT.

Thinker·

variable default read by purpose
THINKER_DISABLED (unset) thinker_loop.py 1 makes the loop a no-op (debugging).
THINKER_INTERVAL 60 thinker_loop.py Seconds between thinker cycles (60).
THINKER_TELEGRAM_CHAT_ID (unset) thinker_loop.py Chat the thinker may post photos/updates to (falls back to the default chat id).

Personas·

variable default read by purpose
SCOUT_PERSONA (unset) tools/_rover_common.py Which persona this process is (thinker, voice, telegram, dashboard…) — the thinker drive gate keys on it.
SCOUT_PERSONA_FLAGS .memory/personas.json tools/persona_flags.py Path of the shared flags file (.memory/personas.json: thinker_drive, recording).
SCOUT_REPO Path(__file__).resolve().parent.parent deploy/scout_supervisor.py Supervisor: the compose project directory it runs docker compose in.
SCOUT_SUPERVISOR_DIR REPO / '.supervisor' deploy/scout_supervisor.py Supervisor: where the socket and audit.log live (default <repo>/.supervisor).
SCOUT_SUPERVISOR_SOCK /run/scout-supervisor/scout-supervisor.sock personas.py Unix socket where the dashboard reaches the host-side supervisor.
SCOUT_SUPERVISOR_TOKEN (unset) deploy/scout_supervisor.py, personas.py Shared secret both the dashboard and the supervisor read; sent as X-Scout-Supervisor-Token.

Perception·

variable default read by purpose
COSMOS_BUFFER_CAMERA front cosmos_buffer.py Cosmos ring buffer: front or rear.
COSMOS_BUFFER_DIR cosmos_clips cosmos_buffer.py Cosmos ring buffer: where finished clips are written.
COSMOS_CLIP_FPS 10 cosmos_buffer.py Cosmos ring buffer: encode fps.
COSMOS_CLIP_SECONDS 4 cosmos_buffer.py Cosmos ring buffer: clip length.
COSMOS_KEEP_CLIPS 10 cosmos_buffer.py Cosmos ring buffer: how many clips to retain.
DET_BACKEND yolo yolo_detector.py yolo (default) or locate (NVIDIA LocateAnything-3B open-vocabulary grounding).
LOCATE_ATTN sdpa yolo_detector.py Attention implementation for LocateAnything (sdpa).
LOCATE_MODEL nvidia/LocateAnything-3B yolo_detector.py HF id for the locate backend.
LOCATE_QUERY person. chair. sofa. table. door. plant. tv. cup. bottle. yolo_detector.py Natural-language grounding query for the locate backend (person. chair. sofa. …).
MEDIA_HUB_DATA_INTERVAL 0.1 media_hub.py Seconds between /data telemetry pulls.
MEDIA_HUB_DEFAULT_URL http://media:8090 media_client.py Fallback hub URL when MEDIA_HUB_URL is unset.
MEDIA_HUB_ENABLED auto media_client.py auto · on · off — whether clients try the hub before polling the SDK directly.
MEDIA_HUB_MIC_INTERVAL 0.1 media_hub.py Seconds between mic buffer drains.
MEDIA_HUB_MIC_RATE 16000 media_hub.py Mic sample rate the hub republishes (16 kHz).
MEDIA_HUB_PORT 8090 media_hub.py MediaHub listen port (8090).
MEDIA_HUB_REAR 1 media_hub.py 1 also drains the rear camera stream.
MEDIA_HUB_URL (unset) media_client.py Where clients find the hub (compose: http://media:8090).
MEDIA_HUB_VIDEO_INTERVAL 0.1 media_hub.py Seconds between camera pulls from the SDK (0.1 → ~10 fps).
SCOUT_ANG_SPEED_MAX 1.20 tools/rover_pose.py Dead reckoning: rad/s at angular=1.0 (1.20).
SCOUT_CAL_FILE str(Path(__file__).resolve().parent.parent / '.scout_calibration.json') tools/rover_pose.py Where speed calibration is persisted.
SCOUT_ENABLE_COSMOS auto tools/rover_cosmos.py 1/0 force the Cosmos tools on/off; auto = present when the package imports (GPU stack). Slim pins 0.
SCOUT_IMU_YAW_TRUST 0.15 tools/rover_pose.py Dead reckoning: complementary-filter weight of IMU yaw (0 = ignore, 1 = trust fully).
SCOUT_LIN_SPEED_MAX 0.35 tools/rover_pose.py Dead reckoning: m/s at linear=1.0 (0.35).
SCOUT_POSE_DRIFT_BUDGET_M 8 tools/rover_pose.py Dead reckoning: pose flagged STALE after this much travel (8 m).
SCOUT_POSE_FILE str(Path(__file__).resolve().parent.parent / '.scout_pose.json') tools/rover_pose.py Where the estimated pose is persisted between processes.
SCOUT_POSE_STALE_SECONDS 1800 tools/rover_pose.py Dead reckoning: pose flagged STALE after this long (30 min).
SCOUT_ROOM_SCAN str(Path(__file__).resolve().parent.parent / 'cagatay_lab.usdz') tools/room_map.py Path of the Apple RoomPlan .usdz the room-map tool parses (default cagatay_lab.usdz).
YOLO_CAMERA front yolo_detector.py front · rear · both.
YOLO_CONF 0.35 yolo_detector.py Detection confidence threshold (0.35).
YOLO_DEVICE auto yolo_detector.py cuda · cpu · auto.
YOLO_EVERY_N 1 yolo_detector.py Run inference on every Nth hub frame (compose sets 2).
YOLO_IMGSZ 640 yolo_detector.py Inference image size (640).
YOLO_MODEL yolov8n.pt yolo_detector.py Ultralytics weights (yolov8n.pt, auto-downloaded).

Datasets·

variable default read by purpose
ECOT_EVENTS_DB (unset) tools/ecot_export.py, tools/reasoning_log.py ECoT export: override path of the reasoning events SQLite.
ROVER_AGENT_ID (unset) tools/_recorder_engine.py Persona/agent id folded into the per-day dataset path so several processes append to their own sub-dataset.
ROVER_AUDIO_RATE 16000 tools/_recorder_engine.py Sample rate of the recorded mic track (16 kHz).
ROVER_BLACK_FRAME_STD 1.0 tools/_recorder_engine.py Std-dev threshold under which a frame counts as black.
ROVER_DATASET_ROOT str(ROOT / 'datasets') dashboard_replay.py, tools/_recorder_engine.py, tools/ecot_export.py, tools/reasoning_log.py Root directory for LeRobot datasets (default datasets/) — recorder and replay API.
ROVER_MIN_FRAME_DIM 64 tools/_recorder_engine.py Reject frames smaller than this many pixels on a side (placeholder images).
ROVER_RECORDER_DEBUG 0 tools/_recorder_engine.py 1 prints the macOS SDL2/objc duplicate-dylib warnings instead of spooling them to a file.
ROVER_RECORDER_LOG /tmp/rover_recorder_sdl.log tools/_recorder_engine.py Where those swallowed SDL warnings go (default /tmp/rover_recorder_sdl.log).
ROVER_RECORD_ERROR_LOG_PERIOD 5 tools/_recorder_engine.py Seconds between repeated 'capture frame error' log lines (anti-spam).
ROVER_RECORD_FPS 10 tools/_recorder_engine.py, tools/reasoning_log.py Dataset frame rate (10 — the earthrover_mini_plus convention).
ROVER_RECORD_HEIGHT 480 tools/_recorder_engine.py Recorded frame height (480).
ROVER_RECORD_REAR 1 tools/_recorder_engine.py 1 (default) also records the rear camera as observation.images.rear; 0 = front-only datasets.
ROVER_RECORD_WIDTH 640 tools/_recorder_engine.py Recorded frame width (640).
ROVER_REJECT_BLACK_FRAMES 1 tools/_recorder_engine.py Drop frames whose pixel std-dev is below ROVER_BLACK_FRAME_STD (camera not yet streaming).
ROVER_REPO_ID (unset) tools/_recorder_engine.py Pin one growing LeRobot dataset id; unset = a new scout__earth-rover-mini-YYYYMMDD per day.
SCOUT_AUTO_RECORD 1 agent.py 0 disables auto-recording of agent turns.
SCOUT_AUTO_RECORD_MAX_TASK_LEN 256 agent.py Truncate the prompt stored as the episode task to this many chars (256).
SCOUT_AUTO_RECORD_MIN_ACTIONS 1 agent.py Drop auto-recorded episodes with fewer than N motion actions (1).
SCOUT_CLIP_MODEL openai/clip-vit-base-patch32 tools/memory_index.py Memory index: CLIP model for image embeddings (openai/clip-vit-base-patch32).
SCOUT_DATASETS_DIR datasets tools/dataset_index.py Dataset index: root to scan for the cockpit/agent list.
SCOUT_DATASET_MAX_TRACES 12 tools/dataset_index.py Dataset index: cap on reasoning-trace paths surfaced.
SCOUT_DATASET_MAX_VIDEOS 12 tools/dataset_index.py Dataset index: cap on video paths surfaced to the agent prompt.
SCOUT_INJECT_DATASETS 1 tools/dataset_index.py 1 injects the dataset index into the agent prompt (Cosmos tools need real paths).
SCOUT_KEYFRAME_MOTION 1 tools/enrich_episode.py Episode enrichment: also keyframe when the action changes.
SCOUT_KEYFRAME_STRIDE 4 tools/enrich_episode.py Episode enrichment: keyframe every N frames.
SCOUT_SEAL_EPISODES 1 tools/_recorder_engine.py 1 (default) finalizes the dataset after every episode so it is readable mid-session; 0 = packed files, footer only at exit.
SCOUT_WHISPER_MODEL base tools/enrich_episode.py Episode enrichment: faster-whisper size for transcribing the mic track.
SCOUT_YOLO_MODEL yolov8n.pt tools/enrich_episode.py Episode enrichment: YOLO weights for offline detection.

Dashboard·

variable default read by purpose
CAROOT (unset) tls.py mkcert CA root directory (mkcert's own variable), honoured when exporting /ca.
DASH_HOST 0.0.0.0 dashboard_server.py Bind address of the cockpit server.
DASH_PORT 8080 dashboard_server.py, field_setup.py, scout_mdns.py, tls.py Cockpit port (8080).
DASH_TLS true dashboard_server.py, field_setup.py, tls.py true serves HTTPS with a generated self-signed cert (WebAuthn needs it).
DASH_TLS_CERT (unset) tls.py Use this real certificate instead of generating one.
DASH_TLS_DIR ./.scout_tls dashboard_server.py, field_setup.py, tls.py Where the generated cert/key are kept (compose: the auth volume).
DASH_TLS_HOSTS (unset) tls.py Extra SANs to put in the generated cert (a private domain, scout.local).
DASH_TLS_KEY (unset) tls.py Private key matching DASH_TLS_CERT.
DASH_TLS_MKCERT auto dashboard_server.py, tls.py auto uses mkcert when installed for a locally-trusted cert.
DASH_TURN_SIGN -1 dashboard_server.py Flip the joystick/WASD angular sign (default -1), independent from ROVER_TURN_SIGN.
SCOUT_MDNS_NAME scout field_setup.py, scout_mdns.py, tls.py mDNS name announced on the LAN (scoutscout.local).
SCOUT_PUBLIC_URL (unset) dashboard_server.py Public URL printed on the field card / QR and used for links (else the request Host).

Auth·

variable default read by purpose
SCOUT_AUTH_BOOTSTRAP_TOKEN (unset) auth.py, dashboard_server.py, field_setup.py One-time secret required to enrol the FIRST passkey — set it before exposing a fresh rover to the internet.
SCOUT_AUTH_ORIGIN (unset) auth.py Expected WebAuthn origin (derived from the request when unset).
SCOUT_AUTH_RP_ID (unset) auth.py WebAuthn relying-party id — the public hostname when behind a tunnel.
SCOUT_AUTH_RP_NAME scout rover auth.py Display name shown in the passkey prompt.
SCOUT_AUTH_STORE ./.scout_auth.json auth.py Path of the passkey + JWT-secret store (auth.json, chmod 600).
SCOUT_AUTH_TOKEN_TTL 86400 auth.py Session JWT lifetime in seconds (24 h).

Fleet·

variable default read by purpose
TINY_MCP 0 tools/tiny_mcp.py 1 mounts the tiny.technology fleet tools into the agents (off by default).
TINY_MCP_COMMAND (unset) tools/tiny_mcp.py Full command to start the MCP server (overrides node/tiny-tech autodetection).
TINY_MCP_HOME ~/.tiny-mcp tools/tiny_mcp.py Isolated TINY_HOME for the server (default ~/.tiny-mcp).
TINY_MCP_MESH 0 tools/tiny_mcp.py 1 lets the server join the zenoh mesh (off: CPU).
TINY_MCP_NODE (unset) tools/tiny_mcp.py Path to the node binary.
TINY_MCP_PERSONAS (unset) tools/tiny_mcp.py Comma list of personas that get fleet tools (default dashboard, telegram, shell).
TINY_MCP_STARTUP_TIMEOUT 45 tools/tiny_mcp.py Seconds to wait for the MCP server to come up (45).
TINY_MCP_TIMEOUT 90 tools/tiny_mcp.py Per-tool-call read timeout in seconds (90).
TINY_MCP_TINY_TECH (unset) tools/tiny_mcp.py Path to the tiny-tech package dir (image: /opt/tiny-mcp/node_modules/tiny-tech).
TINY_SELF_DEVICE_IDS (unset) tools/tiny_mcp.py This robot's own device ids/names — use_device refuses to invoke them.
TINY_SELF_NAME (unset) tools/tiny_mcp.py Name stamped into the [fleet depth=1 from <name>] marker on outgoing fleet turns.
TINY_TOKEN (unset) tools/tiny_mcp.py tiny.technology user CLI JWT the MCP server authenticates with (lives in .tiny-mcp.env).
TINY_TOKEN_FILE (unset) tools/tiny_mcp.py Read the token from a file instead (wins over TINY_TOKEN).

Scout·

variable default read by purpose
SCOUT_MEMORY_DIR .scout_memory memory.py, tools/rover_memory.py Directory of the shared SQLite brain (.scout_memory locally, .memory in compose).
SCOUT_MEMORY_PROMPT_MAX 1000 memory.py Max chars of recalled memory injected into the system prompt.
SCOUT_MEMORY_RECALL_TURNS 8 memory.py How many recent turns to recall.
SCOUT_MEMORY_REPLY_MAX 1500 memory.py Max chars of a reply stored per turn.

Other·

variable default read by purpose
STRANDS_MODEL_ID (unset) dashboard_server.py Bedrock model id for every text persona; editable live from the cockpit ⚙️ drawer.

155 variables, scanned from every os.getenv / os.environ in the repo.