Every env var a scaffolded agent reads, grouped by feature. The full set surfaces in .env.example after scaffolding — this page is the one-stop reference.
Bearer token (or X-API-Key header) required on all endpoints except /health, /favicon.ico, and /gateways/*. If unset, the server warns and runs unauthenticated.
DOCS_ENABLED
no
If true, keeps /docs, /openapi.json, /redoc reachable when API_KEY is set. Default is to disable docs in production.
(Inherited from --with-composio, which --with-slack auto-enables.)
COMPOSIO_WEBHOOK_SECRET
yes
Long random string. Composio echoes it back as the ?secret= query parameter on every trigger delivery; the handler verifies via constant-time comparison.
SLACK_BOT_USER_ID
no
The bot's Slack user ID (e.g. U0BOT...). Required for @-mention detection in channels. Without it, channel-mode mention silently drops every channel message.
SLACK_CHANNEL_TRIGGER_MODE
no
mention (default) — only invoke on @-mention; or all — invoke on every channel message.
If all three are set → SDK mode (production, full JWT validation).
If any is missing → anonymous mode (Agents Playground / local dev only; not for public exposure).
Embedded scheduler ticks every minute and runs due jobs in fresh ADK sessions. Jobs and outputs persist on disk; on Railway, attach a Volume (see Deploy to Railway).
Var
Default
Description
NUVEL_CRON_ENABLED
0
1 = start the scheduler in the agent's FastAPI lifespan. Off → no scheduler, but /cron/* HTTP endpoints and the cronjob tool still work for storage.
NUVEL_CRON_TICK_SECONDS
60
Scheduler tick interval. Lower for tests; higher to reduce load.
NUVEL_CRON_DIR
~/.nuvel/cron
Where jobs.json, output/, and .tick.lock live. Override on Railway to point at a Volume mount.
NUVEL_CRON_RUNNING
(internal)
Set by the scheduler during a cron-spawned run. The cronjob tool checks this to refuse mutations from inside cron sessions (recursion guard). Don't set manually.
Opt-in audio transcription. When enabled, voice memos are converted to text before reaching the agent and the audio attachment is replaced with [Voice memo, M:SS]: <transcript>. Teams is not yet supported.
Var
Default
Description
GATEWAY_TRANSCRIBE_AUDIO
0
1 = enable transcription. Off → audio falls through unchanged.
GATEWAY_TRANSCRIBE_PROVIDER
openai
openai (Whisper) or groq (Whisper, faster/cheaper).
GATEWAY_TRANSCRIBE_MODEL
whisper-1 / whisper-large-v3
Override the model. Defaults depend on provider.
GATEWAY_TRANSCRIBE_TIMEOUT_SEC
60
HTTP timeout for the provider call.
OPENAI_API_KEY
—
Required when GATEWAY_TRANSCRIBE_PROVIDER=openai.
GROQ_API_KEY
—
Required when GATEWAY_TRANSCRIBE_PROVIDER=groq.
On provider error / missing key / oversized audio, the user message becomes [Voice memo received but transcription failed] so the turn isn't silently dropped.
The SkillCuratorPlugin is registered in the generated agent's plugin chain but stays inert until explicitly enabled. When active, it watches each run and — on complex turns — proposes new skills or patches to existing ones. Proposals are written to ~/.nuvel/skill-proposals/ for human review; nothing is auto-applied.
Var
Default
Description
NUVEL_SKILL_CURATOR
0
1 = enable the plugin. Off → no LLM calls, no proposals.
NUVEL_SKILL_CURATOR_MIN_TOOLS
5
Trigger threshold: minimum tool calls in a single run.
NUVEL_SKILL_CURATOR_MIN_EVENTS
12
Trigger threshold: minimum events in a single run.
NUVEL_SKILL_CURATOR_MIN_ERRORS
3
Trigger threshold: same tool failing this many times.
NUVEL_SKILLS_DIR
<pkg>/skills/
Directory enumerated to give the curator a view of existing skills.
NUVEL_SKILL_PROPOSALS_DIR
~/.nuvel/skill-proposals/
Where proposals are written. Always outside the repo by default.