Reference
Configuration
38 environment variables, found by sweeping every read in the Rust workspace rather than by transcribing a list. A variable that stopped being read would leave this page; one added upstream arrives without an annotation instead of going unmentioned.
Every teal entry on this page is generated from every env read under rust/**/src at 158c9b4c, not from prose about it. Regenerate with pnpm --filter @smooai/web gen:operator-reference.
The shape of it
Nothing is required. An unconfigured server boots on loopback, keeps everything in memory, serves /ws, disables /admin, and answers with a clean error instead of an LLM. Every variable below moves it away from that.
# Everything below is optional except the key: unset, the server binds
# 127.0.0.1:8787 on in-memory storage with the admin API disabled.
export SMOOAI_GATEWAY_KEY=sk-...
cargo run -p smooai-smooth-operator-server
# ws://127.0.0.1:8787/wsDefaults on this page are the server’s, read from Rust source. The Helm chart and the SST deploy set their own values on top, and the chart’s differ — that is the subject of the last section.
Server and model
What the process binds to and which model a turn runs on.
SMOOTH_AGENT_BINDdefault 127.0.0.1Bind address. Containers need 0.0.0.0 or nothing outside the pod can reach it.
SMOOTH_AGENT_PORTdefault 8787TCP port. The WebSocket endpoint is /ws on it.
SMOOTH_AGENT_MODELdefault claude-haiku-4-5Deployment-wide default model. A per-agent value overrides it, and a per-turn send_message.model overrides that.
SMOOTH_AGENT_MAX_ITERATIONSdefault 20Agent-loop cap per turn. The shipped Helm chart sets 6 in its default values, so a chart deploy does not get this number — see below.
SMOOTH_AGENT_MAX_TOKENSdefault 8192max_tokens sent to the gateway. The Helm chart sets 512, which will truncate most real answers — see below.
SMOOTH_AGENT_JUDGE_MODELdefault same as SMOOTH_AGENT_MODELModel for the cheap post-turn judge, separate so a big turn model does not make every turn expensive.
SMOOTH_AGENT_PREAMBLE_MODELdefault unset ⇒ offNames a fast model that runs in parallel with the turn and streams one ephemeral stream_preamble sentence to cover time-to-first-token.
SMOOTH_AGENT_SEED_KBdefault offExactly 1 seeds a couple of demo documents at startup. Any other value is off.
Gateway and retrieval
One key drives chat, embeddings, and rerank. Everything degrades rather than failing when it is absent.
SMOOAI_GATEWAY_URLdefault https://llm.smoo.ai/v1OpenAI-compatible gateway base. Serves chat, /v1/embeddings, and /v1/rerank.
adapters/postgres/src/embedder.rsadapters/postgres/src/reranker.rsexamples/dev-support/src/ingest.rsexamples/dev-support/src/main.rssmooth-operator-server/src/config.rs
SMOOAI_GATEWAY_KEYdefault unsetGateway key. Unset is a working server with no LLM: turns fail cleanly, and embeddings fall back to the network-free deterministic embedder. Setting it is what makes the semantic embedder eligible.
adapters/postgres/src/embedder.rsadapters/postgres/src/reranker.rsevals/src/lib.rsexamples/dev-support/src/ingest.rsexamples/dev-support/src/main.rssmooth-operator-server/src/config.rs
SMOOTH_AGENT_RERANKdefault unset ⇒ offgateway (or on/1/true) · lexical · anything else is off.
Storage and fan-out
The two variables that decide whether a restart loses your data and whether a second replica can answer.
SMOOTH_AGENT_STORAGEdefault memorymemory · postgres · dynamodb. Also selects the matching settings, connector-config, and indexing stores.
SMOOTH_AGENT_DATABASE_URLdefault unsetPostgres connection string. Preferred name.
adapters/postgres/src/lib.rsexamples/dev-support/src/serve.rssmooth-operator-server/src/server.rs
DATABASE_URLdefault unsetFallback for the above, honored only once SMOOTH_AGENT_STORAGE=postgres has explicitly chosen the backend — so an ambient DATABASE_URL alone can never redirect where data goes.
adapters/postgres/src/lib.rsexamples/dev-support/src/serve.rssmooth-operator-server/src/server.rs
SMOOTH_AGENT_DDB_TABLEdefault smooth-operatorDynamoDB single-table name. Credentials and region come from the standard AWS chain.
SMOOTH_AGENT_BACKPLANEdefault memorymemory · redis / valkey · nats. An unknown value fails the boot, and so does naming a backend the binary was not built with.
SMOOTH_AGENT_BACKPLANE_URLdefault unsetConnection URL for the selected backplane. Falls back to SMOOTH_AGENT_REDIS_URL or SMOOTH_AGENT_NATS_URL.
Identity
Unset behaves as jwt with no key, which boots the server with the admin API disabled rather than failing. Choosing jwt explicitly with no key is a startup error.
SMOOTH_AGENT_AUTH_MODEdefault jwtCanonical name. jwt · smoo · trusted · none.
AUTH_MODEdefault —Older alias for the above. The canonical name wins when both are set.
examples/dev-support/src/serve.rssmooth-operator/src/auth.rs
AUTH_JWT_RS256_PUBLIC_KEYdefault unsetRS256 PEM. First in key precedence.
AUTH_JWT_JWKS_URLdefault unsetExplicit JWKS endpoint. Third, and the keyless path — any OIDC issuer works.
AUTH_JWT_ISSUERdefault unsetRequired iss. Also derives the JWKS URL as {issuer}/.well-known/jwks.json when none is set, and is mandatory in smoo mode.
AUTH_DEV_ORG_IDdefault dev-orgOrg the none-mode admin principal belongs to.
WIDGET_AUTH_URLdefault unsetEndpoint asked whether an origin may embed the widget. Unset leaves the permissive provider in place.
WIDGET_AUTH_TTL_SECSdefault provider defaultHow long an origin decision is cached.
WIDGET_AUTH_STRICTdefault falseAccepts 1, true, or yes. Tightens widget origin enforcement.
Capabilities
Every one of these is off when unset, and each says so in a different vocabulary — an empty list, an unset path, an unparsed flag.
SMOOTH_AGENT_CONFIRM_TOOLSdefault empty ⇒ HITL offComma-separated tool-name patterns that must be confirmed by a human before they run. Empty or whitespace-only means no confirmation hook is installed at all.
SMOOTH_AGENT_AUTH_TOOLSdefault empty ⇒ gate inertComma-separated names of tools that honor auth levels. With none listed, the per-agent auth gate is not built.
SMOOTH_SKILLS_DIRdefault unset ⇒ offColon-separated skill roots, searched in order. Unset installs no resolver, so every send_message.skill is unknown.
SMOOTH_EXTENSIONS_ALLOWdefault unset ⇒ deny allNames the out-of-process extensions allowed to contribute tools. Empty means the extension host is never built and nothing is spawned.
SMOOTH_EXTENSIONS_DIRdefault engine defaultOverrides where extensions are discovered.
SMOOTH_AGENT_DURABLE_EXECUTORdefault unset ⇒ in-processAccepts 1/true/on/yes. Asking for durable execution without also supplying an executor logs a warning and runs the turn in-process — the flag alone does not make a turn survive a disconnect.
Operations
Tracing, connector credentials, and the gate on tests that cost money.
OTEL_EXPORTER_OTLP_ENDPOINTdefault unsetSet to ship gen_ai.* spans over OTLP gRPC. Unset means local logging only, no collector needed.
GITHUB_TOKENdefault unsetRead-scope PAT for the GitHub connector and the github_search tool.
SMOOTH_AGENT_E2Edefault unsetOpts into the gated live-gateway tests. Without it they skip cleanly.
What the sweep cannot see
Included deliberately as the exception that shows what the sweep does and does not cover.
RUST_LOGdefault info,smooth_operator=infoTracing filter. Independent of OTLP export. Read indirectly by the tracing subscriber rather than by a direct environment read, which is why it is not in the swept list above it.
The sweep matches direct environment reads and reads through a named constant. Two backplane fallbacks — SMOOTH_AGENT_REDIS_URL and SMOOTH_AGENT_NATS_URL — are read through a helper that takes the name as an argument, so they are also absent from the generated list above and are described by hand under SMOOTH_AGENT_BACKPLANE_URL.
Where the chart disagrees with the server
Three things in deploy/k8s worth knowing before a first production install, all of them checkable in values.yaml and templates/deployment.yaml.
The chart caps turns much lower. Its defaults are maxIterations: 6 and maxTokens: 512 against the server’s own 20 and 8192. Both are real values; they just are not the same value, and the chart is what a Helm install actually applies.
The chart templates no storage or backplane variable. There is no SMOOTH_AGENT_STORAGE or SMOOTH_AGENT_BACKPLANE key in values.yaml and nothing renders them in deployment.yaml — they reach the container only via server.extraEnv. A default install therefore runs on in-memory storage with an in-memory backplane, even with a database secret configured.
And it runs two replicas by default. replicaCount: 2plus the point above is two pods that cannot see each other’s sockets or share a conversation. Set storage and backplane in extraEnv, or set replicaCount: 1, before this matters to a user.
Verified against deploy/k8s/values.yaml and deploy/k8s/templates/deployment.yaml at the pinned commit. These are chart facts, not code facts, so they are not part of the generated sweep.