Skip to content

Environment Variables

NimbleBrain reads environment variables for model provider keys, server binding, public-origin resolution, rate limiting, MCP session limits, the Composio aggregator, and observability. This page lists every supported variable with its purpose, default, and precedence.

A provider’s API key can be supplied here or in nimblebrain.json under providers.<name>.apiKey. When the config field is omitted, the AI SDK falls back to the standard provider env var below.

VariableRequiredDefaultDescription
ANTHROPIC_API_KEYFor Anthropic modelsAnthropic API key. Also settable via providers.anthropic.apiKey.
OPENAI_API_KEYFor OpenAI modelsOpenAI API key. Also settable via providers.openai.apiKey.
GOOGLE_GENERATIVE_AI_API_KEYFor Google modelsGoogle Gemini API key (the AI SDK’s standard Google var). Also settable via providers.google.apiKey.
NEBIUS_API_KEYFor Nebius modelsNebius Token Factory API key. Also settable via providers.nebius.apiKey.
XAI_API_KEYFor xAI modelsxAI (Grok) API key. Also settable via providers.xai.apiKey.
VariableRequiredDefaultDescription
NB_WORK_DIRNo~/.nimblebrainWorking directory for runtime state (conversations, logs, workspaces, cache). Does not drive config-file discovery — see config resolution. Also passed to bundle subprocesses so they can locate workspace data.
PORTNo27247HTTP server port. Wins over the --port CLI flag when both are set.
ALLOWED_ORIGINSNoComma-separated additional CORS origins. The canonical origins (platform host, custom domain) are already trusted; this is for extra origins.
NB_CHAT_RATE_LIMITNo20Chat requests per minute per identity.
NB_TOOL_RATE_LIMITNo600Tool calls per minute per identity.
NB_MCP_RATE_LIMITNo300/mcp JSON-RPC requests per minute per identity.
NB_TIMEZONENoPacific/HonoluluDefault IANA timezone for time-aware features (e.g. automation schedules) when an identity has no timezone preference.
NB_MAX_PARALLEL_TOOL_CALLS_PER_SOURCENo6Most tool calls the agent dispatches to any one source at a time. A turn touching several connectors still fans out across them — only the depth against a single source is capped — so this bounds how loud the runtime can be toward one server, not overall throughput. Raise it for fast local servers; lower it for a fragile upstream. Zero, negative, fractional-below-1, and unparseable values fall back to the default: removing the bound is never the intended reading. Read once at startup. Scoped per source per agent run, which is a ceiling rather than a guarantee: concurrent conversations and delegated sub-agents each get their own budget, so the worst case against one server is roughly (concurrent runs + sub-agents) x this value, not this value. Size it with that multiple in mind.
NB_CONNECTION_REVALIDATE_INTERVAL_SECONDSNo300Sweep interval for the connection-revalidation monitor, which re-checks connectors whose upstream credential can lapse without a transport 401 (e.g. Composio). Provider-agnostic. Non-positive / unparseable values fall back to the default; a blank value falls through to the legacy COMPOSIO_MONITOR_INTERVAL_SECONDS (a set-but-empty var never masks it). Capped at 1789569 (~20.7 days), the largest interval the runtime can schedule; a higher value logs a warning and uses the cap. To stop the sweep entirely set connectors.providers.composio.monitorEnabled: false rather than a very large interval.

The platform builds every outward-facing URL (OAuth callbacks, post-login landing) from a single canonical public origin. Resolution order: NB_PUBLIC_ORIGIN → derived from NB_PLATFORM_HOST / NB_CUSTOM_DOMAIN → legacy NB_API_URLhttp://localhost:27247 (dev).

VariableRequiredDefaultDescription
NB_PUBLIC_ORIGINRecommended (production)derived, else http://localhost:27247Canonical public origin (scheme + host, no path). The explicit operator override — trusted as given. Used to build the OAuth callback ${NB_PUBLIC_ORIGIN}/v1/mcp-auth/callback and the WorkOS / Composio callbacks. Must be a bare https origin (or http on a loopback host in dev); a value with a path/query throws at startup.
NB_PLATFORM_HOSTNoPlatform subdomain host (no scheme). Used to derive the canonical origin when NB_PUBLIC_ORIGIN is unset. Chart-forwarded in production.
NB_CUSTOM_DOMAINNoCustom domain host. When set and canonical, becomes the derived public origin (custom domain wins).
NB_CUSTOM_DOMAIN_CANONICALNotrue"true" / "false" only — anything else throws. When "false", the custom domain is served but the platform host stays canonical.
NB_WEB_URLNofalls back to the canonical originUser-facing SPA origin for post-OAuth browser returns. Only needed when the API and SPA are served from different origins (e.g. dev: API on :27247, SPA on :27246).
NB_API_URLNo (legacy)Legacy public-origin fallback for older deploys that set only this. Prefer NB_PUBLIC_ORIGIN. This is the only sanctioned reader; do not reintroduce it elsewhere.
VariableRequiredDefaultDescription
NB_CURATED_CATALOG_DIRNoin-image examplePath backing the locked bundled-static registry — a directory of ServerDetail YAML/JSON files (the intended use, hence the name) or a single such file — every *.yaml/*.yml/*.json in it, read in sorted filename order. Replaces src/connectors/curated/ wholesale, and wins over the persisted registries.json url for that registry. This is where auth: static and brokered (composio, smithery) entries belong; the in-image example is DCR-only. Read at registry-build time. See Connectors Catalog.
NB_REGISTRIESNoJSON array of registry configs that completely overrides the persisted registries.json for the lifetime of the process. Adds custom static / mpak / mcp registries without touching the pod filesystem. The locked bundled-static registry is re-pinned automatically. Read once at startup. See Connectors Catalog → Operator override.
VariableRequiredDefaultDescription
MCP_MAX_SESSIONSNo100Max concurrent live MCP sessions on /mcp per process. A well-formed initialize at capacity evicts the least-recently-used session and is admitted — it is never a 4xx. Non-positive / non-integer values are rejected with a warning and the default is used.
MCP_SESSION_TTL_SECONDSNo28800 (8 h)MCP session inactivity TTL in seconds. Each request resets the clock — actively-used sessions never expire. Highest priority, overriding sessionStore.ttlSeconds in nimblebrain.json. Non-positive / non-integer values fall back to the default.
VariableRequiredDefaultDescription
WORKOS_API_KEYWhen auth.adapter: "workos" and no apiKey in instance.jsonWorkOS API key. Also settable via instance.json → auth.apiKey.
NB_INTERNAL_TOKENNoShared secret for service-to-service calls. Hard-denied to bundle subprocesses.

Required only when the connectors catalog contains any auth: composio entries (Gmail, Outlook, …). See the Composio operator guide for end-to-end setup.

The provider’s settings live in nimblebrain.json under connectors.providers.composio.

COMPOSIO_API_KEY is the one value with two sources — it is also declarable as connectors.providers.composio.apiKey, though the environment remains the better posture for a secret (why). NB_TENANT_ID is env-only.

VariableRequiredDefaultDescription
COMPOSIO_API_KEYWhen the catalog has auth: composio entries(fallback for …composio.apiKey) Platform-wide Composio API key — the broker credential, and the gate on registering the provider at all. Read once at startup. Without it, the Composio integration reports “not configured” and installs of auth: composio entries fail.
NB_TENANT_IDWhen multi-tenant pods share a Composio accountPer-pod tenant identifier prepended to the wsId so two tenants never collide in Composio’s namespace. Required in bouncer (multi-tenant) mode — startup fails without it. Single-tenant deployments can omit it.
COMPOSIO_MONITOR_INTERVAL_SECONDSNo300Deprecated alias for NB_CONNECTION_REVALIDATE_INTERVAL_SECONDS (the sweep cadence is provider-agnostic). Still honored; slated for removal (#727).

Required only when the connectors catalog contains any auth: smithery entries. Smithery brokers the connection and hosts the MCP session; the platform stores no upstream credential.

A credential and a namespace must both resolve — a Smithery namespace is globally unique and account-owned, so there is no safe default. Setting only the key logs a warning and leaves the integration disabled.

SMITHERY_API_KEY is a fallback for connectors.providers.smithery.apiKey, because an installed connector’s transport names the smithery credential provider rather than an env var. Every other Smithery setting lives in that block only.

VariableRequiredDefaultDescription
SMITHERY_API_KEYWhen the catalog has auth: smithery entriesPlatform-wide Smithery API key, from smithery.ai/account/api-keys. Read once at startup. Fallback for connectors.providers.smithery.apiKey.
NB_TENANT_IDWhen multi-tenant pods share a Smithery accountPrepended to the workspace id so two tenants never collide in the namespace. Same variable as the Composio prefix above.

Vendor-neutral. Trace ids always exist for log correlation; export only happens when an OTLP endpoint is configured, so local dev and OSS checkouts need no infrastructure.

VariableRequiredDefaultDescription
OTEL_EXPORTER_OTLP_ENDPOINTNo— (no export)OTLP collector base URL. Unset means spans are still created (for log correlation) but nothing is exported.
NB_SERVICE_NAMENoOverrides the service name stamped on spans and structured logs.
NB_TENANT_IDNoBoot-time resource attribute stamped on spans/logs as tenant_id. (Same var as the Composio multi-tenant prefix above.)
NB_LOG_FORMATNoprettySet to json for structured JSON logs auto-enriched with service, tenant_id, correlation_id (the active trace id), and identity. Set by the chart in production.
NB_DEBUGNoNamespace-scoped hot-path debug logging (e.g. NB_DEBUG=mcp,sse). Read once at process start.

Optional, additive error capture on top of OpenTelemetry. Off unless NB_SENTRY_ENABLED=true (the SDK is loaded only then — never inferred from DSN presence), initialized as an out-of-kernel preload that does not take over OTel tracing. NB_SENTRY_* are our own knobs (mirroring the web client), not Sentry’s auto-read SENTRY_*. Per-tenant via the chart (runtime.config.sentry.enabled). See Observability → Error reporting.

VariableRequiredDefaultDescription
NB_SENTRY_ENABLEDNofalseExplicit on/off switch. Must be true to enable; never inferred from the DSN.
NB_SENTRY_DSNNoProject DSN (required when enabled).
NB_SENTRY_ENVNoEnvironment tag (e.g. staging, production); one project discriminated by this tag.
NB_SENTRY_TRACES_SAMPLE_RATENo0Sentry performance tracing. 0 = errors only (recommended; leaves tracing to OTel).

Release is taken from the runtime’s existing NB_VERSIONNB_BUILD_SHA (no separate Sentry release var).

VariableRequiredDefaultDescription
NB_TELEMETRY_DISABLEDNoSet to 1 to disable anonymous usage telemetry.
DO_NOT_TRACKNoStandard opt-out signal. Set to 1 to disable telemetry. Equivalent to NB_TELEMETRY_DISABLED=1.
POSTHOG_API_KEYNoOverride the built-in PostHog key. Rarely needed.

The web UI is a static bundle, so it cannot read pod env from JS. Instead Caddy serves /config.js dynamically from these NB_* values (set window.__NB_CONFIG__), which the client reads on boot. This lets one image be configured per tenant via Helm with no rebuild and no writable filesystem. All values are public client keys — never secrets. Unset ⇒ the corresponding feature is disabled (the OSS/self-host default).

VariableRequiredDefaultDescription
NB_SENTRY_DSNNoSentry DSN (public). Unset ⇒ client crash tracking off.
NB_SENTRY_ENABLEDNofalseSet true to enable Sentry for this deployment (also requires a DSN).
NB_SENTRY_ENVNoSentry environment label (e.g. staging, production).
NB_SENTRY_TRACES_SAMPLE_RATENo0Performance-trace sample rate, 01.
NB_POSTHOG_KEYNoPostHog write-only key for web analytics.
NB_POSTHOG_ENABLEDNofalseSet true to enable web analytics (also requires a key).

Sentry tags every event with tenant_id (from NB_TENANT_ID), workspace_id, and an opaque user.id — never email, display name, prompts, or tool content. For local development, the same values can be supplied to bun run dev as VITE_* fallbacks (see .env.example).

The canonical public origin of the deployment. Every OAuth callback URL the platform hands to a vendor is built from it:

${NB_PUBLIC_ORIGIN}/v1/mcp-auth/callback

Each OAuth app registered with a vendor (Asana, HubSpot, Gmail, …) must list this exact URL in its redirect_uri allow-list. A mismatch surfaces as a vendor-side redirect_uri does not match error at the moment a user clicks Connect.

Terminal window
export NB_PUBLIC_ORIGIN=https://nimblebrain.acme.com

The value must be a bare origin — scheme + host with no path, query, or fragment. A malformed value (a pasted full callback URL, an http origin on a non-loopback host) throws at startup rather than minting broken callbacks at first click.

In dev (bun run dev) the default http://localhost:27247 is correct without setting the variable. In production, set this explicitly (or supply NB_PLATFORM_HOST / NB_CUSTOM_DOMAIN for the chart to derive it). Pointing it at localhost, an internal cluster service name, or a stale staging URL produces confusing OAuth failures that look like vendor outages.

Sets the working directory where NimbleBrain stores runtime state.

Terminal window
export NB_WORK_DIR=/data/nimblebrain

The working directory contains workspaces/<wsId>/ (which holds each workspace’s conversations, files, and automations), users/<userId>/, logs/, registries.json, and cache/.

NB_WORK_DIR sets the workDir runtime value (where state lives) and is forwarded to bundle subprocesses. It does not select which nimblebrain.json is loaded — config-file discovery is driven by --config, a project-local .nimblebrain/, and the command’s default workdir. See config resolution.

Adds origins to the CORS allowlist beyond the canonical ones (platform host and custom domain, which are trusted automatically).

Terminal window
export ALLOWED_ORIGINS=https://app.example.com,https://admin.example.com

Separate multiple origins with commas. Whitespace around each origin is trimmed.

Either variable disables anonymous telemetry:

Terminal window
export NB_TELEMETRY_DISABLED=1
export DO_NOT_TRACK=1

DO_NOT_TRACK follows the Console Do Not Track standard. You can also disable telemetry via telemetry.enabled: false in nimblebrain.json.

When the same setting can be configured in multiple places, this is the resolution order (highest priority first):

SettingEnv varCLI flagConfig fileDefault
Working directoryNB_WORK_DIR (beats all)--workdirworkDir~/.nimblebrain
PortPORT (beats --port)--porthttp.port27247
MCP session TTLMCP_SESSION_TTL_SECONDS (beats all)sessionStore.ttlSeconds28800
Public originNB_PUBLIC_ORIGINderived from host facts, else legacy NB_API_URLhttp://localhost:27247
Anthropic keyANTHROPIC_API_KEYproviders.anthropic.apiKey
TelemetryNB_TELEMETRY_DISABLED / DO_NOT_TRACKtelemetry.enabledEnabled

A typical production setup:

Terminal window
export ANTHROPIC_API_KEY=sk-ant-api03-...
export NB_PUBLIC_ORIGIN=https://app.example.com
export NB_WORK_DIR=/data/nimblebrain
export NB_TELEMETRY_DISABLED=1
# Composio connectors (only if the catalog uses auth: composio).
# Per-toolkit ac_… ids are not env vars — declare them in nimblebrain.json
# under connectors.providers.composio.authConfigs.
export COMPOSIO_API_KEY=...
# Observability
export NB_LOG_FORMAT=json
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318

Authentication is configured separately in instance.json, not via environment variables.