Configuration
Every environment variable and flag the server reads.
Each option is a flag and an environment variable. Flags win. A BRAIN_MAX_* option is a limit
Brain enforces with a default it ships; the default is a starting point, not a fact about the
machine, and the deployment that knows its machine sets the value. Zero on a limit means no bound,
except the three queue capacities marked "at least 1". A limit the model provider enforces, such as
its output token ceiling, is not here: Brain neither sets nor overrides it.
For deployment, remote callbacks, backups and upgrades, start with Operate Brain.
| Variable | Flag | Default | What it does |
|---|---|---|---|
BRAIN_LISTEN | --listen | 127.0.0.1:8080 | Address to bind |
BRAIN_DATA_DIR | --data-dir | brain-data | Where journals, admitted Components, and local state live |
BRAIN_ENV_WORKER | --env-worker | brain-env-worker | Path to the loop worker executable |
BRAIN_ENV_WORKERS | --env-workers | 2 | OS worker processes in the built-in Environment pool |
BRAIN_ENV_PREPARATION | --env-preparation | none | JSON file of Components and program sources to prepare before serving execution |
BRAIN_ENV_NETWORK_ALLOW | --env-network-allow | none | Origins the brain env may grant through Environment configuration: exact, or https://*.example.com for a family of hosts |
BRAIN_ENV_SECRET_ALLOW | --env-secret-allow | none | Process environment variable names the brain env may mount under /secrets |
BRAIN_ENV_FILESYSTEM_ALLOW | --env-filesystem-allow | none | Filesystem roots the brain env may grant: scratch or workspace |
BRAIN_MODEL_BASE_URL | --model-base-url | https://ai-gateway.vercel.sh/v1 | Endpoint for the vercel-ai-gateway provider. Kept under its historic name because deploys and tests already set it |
BRAIN_OPENAI_BASE_URL | --openai-base-url | none | Endpoint override for the openai Responses provider |
BRAIN_ANTHROPIC_BASE_URL | --anthropic-base-url | none | Endpoint override for the anthropic provider |
BRAIN_PROVIDERS_FILE | --providers-file | none | A JSON file of custom provider definitions merged over the built-in catalog: {"providers": [{"name", "dialect", "base_url", ...}]}, each entry in the same shape as a registry ProviderDef. A definition here supersedes a catalog provider of the same name |
BRAIN_API_TOKEN | --api-token | none | Bearer token callers must present. Required when listening beyond loopback |
BRAIN_PUBLIC_URL | --public-url | none | Base URL reachable by HTTP Environments for invocation-service callbacks and Environment observations. Covers loops, Tools and controllers. Defaults to http://{listen}; set an externally reachable address when listening on 0.0.0.0 |
BRAIN_SESSION_IDLE_TTL_SECS | --session-idle-ttl-secs | none | Seconds an idle session keeps its task and memory before it is suspended to disk and rebuilt on its next request. A session may set its own at create; zero means never |
BRAIN_MAX_MODEL_INPUT_BYTES | --max-model-input-bytes | 16777216 | Maximum encoded model request bytes, including retained native state and media |
BRAIN_MAX_MODEL_CALLS | --max-model-calls | 128 | Model calls one turn may make before the next fails with model_call_limit |
BRAIN_MAX_TURN_SECS | --max-turn-secs | 1800 | Seconds one turn may run before it is cancelled |
BRAIN_MAX_TOOL_SECS | --max-tool-secs | 120 | Seconds one Tool call may run before the session records a timeout outcome |
BRAIN_MAX_EMITTED_BYTES | --max-emitted-bytes | 1048576 | Bytes of extension Events one turn may emit, kinds and payloads together |
BRAIN_MAX_MODEL_OUTPUT_BYTES | --max-model-output-bytes | 4194304 | Bytes of assistant content one model call may return |
BRAIN_MAX_MODEL_DELTA_BYTES | --max-model-delta-bytes | 65536 | Bytes one streamed model delta may carry |
BRAIN_MAX_MODEL_STREAM_BYTES | --max-model-stream-bytes | 33554432 | Bytes one model response stream may carry in total |
BRAIN_MAX_MODEL_FRAME_BYTES | --max-model-frame-bytes | 262144 | Bytes one server-sent event frame from a model provider may carry |
BRAIN_MAX_MODEL_ERROR_BYTES | --max-model-error-bytes | 16384 | Bytes of a provider error body kept for the failure record |
BRAIN_MAX_MODEL_SECS | --max-model-secs | 120 | Seconds one model call may take, connection to last byte |
BRAIN_MAX_MODEL_CONNECT_SECS | --max-model-connect-secs | 10 | Seconds connecting to a model provider may take |
BRAIN_MAX_JOURNAL_QUEUE_BYTES | --max-journal-queue-bytes | 67108864 | Bytes the journal writer may hold queued across every session before appends wait |
BRAIN_MAX_SESSION_QUEUE_BYTES | --max-session-queue-bytes | 8388608 | Bytes the journal writer may hold queued for one session before its appends wait |
BRAIN_MAX_JOURNAL_OPEN_FILES | --max-journal-open-files | 256 | Journal segment files the writer keeps open at once |
BRAIN_MAX_LIVE_BACKLOG | --max-live-backlog | 1024 | Records a live subscriber may fall behind before it loses them; at least 1 |
BRAIN_MAX_PACKAGE_BYTES | --max-package-bytes | 33554432 | Bytes an Agentloop or Tool Component package may hold |
BRAIN_MAX_EXECUTION_INPUT_BYTES | --max-execution-input-bytes | 33554432 | Bytes one execution input may hold, including an Agentloop's transcript and events |
BRAIN_MAX_EXECUTION_OUTPUT_BYTES | --max-execution-output-bytes | 33554432 | Bytes one execution output may hold |
BRAIN_MAX_LINEAR_MEMORY_BYTES | --max-linear-memory-bytes | 134217728 | Bytes of linear memory one Wasm instance may grow to |
BRAIN_MAX_FUEL | --max-fuel | 10000000000 | Wasmtime work units one invocation may consume; host and WASI waits consume none. A stable ceiling within one Wasmtime version, not a duration |
BRAIN_MAX_CONCURRENT_EXECUTIONS | --max-concurrent-executions | 8 | Executions per worker in each of two classes: those granted dispatch, and leaf calls. Each holds a fresh Store while it runs, so guest memory is bounded by twice this count times the linear memory ceiling |
BRAIN_MAX_CORE_INSTANCES | --max-core-instances | 8 | Core instances, memories, and tables one guest may hold: its own modules plus the shims Wasmtime builds for its imports |
BRAIN_MAX_NATIVE_HTTP_SECS | --max-native-http-secs | 120 | Seconds one outbound HTTP request from a native Component may take |
BRAIN_MAX_TELEMETRY_RECORDS | --max-telemetry-records | 4096 | Telemetry records the queue holds before it drops the newest; at least 1 |
BRAIN_MAX_TELEMETRY_BYTES | --max-telemetry-bytes | 8388608 | Bytes of telemetry the queue holds before it drops the newest; at least 1 |
BRAIN_TELEMETRY_RETRY_SECS | --telemetry-retry-secs | 30 | Seconds a telemetry batch is retried against a failing sink before it is dropped |
BRAIN_MAX_REQUEST_BYTES | --max-request-bytes | 33554432 | Bytes one HTTP request body may hold, including an admitted Component package |
BRAIN_MAX_ENVIRONMENT_RESPONSE_BYTES | --max-environment-response-bytes | 33554432 | Bytes one HTTP Environment response may hold |
BRAIN_MAX_ENVIRONMENT_SECS | --max-environment-secs | 120 | Seconds one HTTP Environment call other than a turn may take |
BRAIN_MAX_ENVIRONMENT_CONNECT_SECS | --max-environment-connect-secs | 5 | Seconds connecting to an HTTP Environment may take |
BRAIN_MAX_HOSTS | --max-hosts | 4096 | Registered hosts the server keeps before it refuses a registration |
BRAIN_MAX_HOST_COMMANDS | --max-host-commands | 128 | Commands queued for one connected host before the server waits; at least 1 |
BRAIN_HOST_UNCONNECTED_SECS | --host-unconnected-secs | 60 | Seconds a registered host with no sessions may stay disconnected before its registration is dropped |
BRAIN_REQUEST_RETENTION_SECS | --request-retention-secs | 86400 | Seconds a completed keyed request's answer is kept for replay |
An Environment reached over HTTP is addressed by the session that names it: the URL and credential travel in the create request and the credential is sealed beside the model key. The server has no Environment routes, endpoints, or credentials of its own.
The data directory
Brain owns everything under BRAIN_DATA_DIR. Use an empty directory for a new installation;
Brain writes the brain-data/1 layout marker on initialization. One server process may own it
at a time. A matching marker does not establish compatibility with every earlier contract:
pre-1.0 releases can change retained session and executable formats, and Brain does not
automatically migrate old data. Follow the upgrade and restore procedure
before changing the runtime on existing data.
brain-data/
.lock process-held single-writer lock
format layout marker (`brain-data/1`)
sessions/{session_id}/journal/ one canonical journal per session
sessions/{session_id}/checkpoint disposable current-state/index projection
agentloops/ admitted Agentloop and Tool Components
native-workspaces/{session_id}/{environment}/ retained native Environment workspace
hosts/hosts.log host registrations and token hashes
requests/requests.log durable HTTP request claims and answers
run/{worker_index}/ separate worker sockets
server-metadata/ sealed model and Environment credentialsSession configuration, status, public Events, transcript, and Agentloop kv are projections of the canonical journal. Brain does not keep a second event or state log.
Listening beyond loopback
Brain refuses to start on a non-loopback address without BRAIN_API_TOKEN. Binding 0.0.0.0 with
no token is a mistake worth failing on rather than serving.
The three BRAIN_ENV_* allow-lists are the ceiling on what the brain env may grant a Component
whose Environment configuration explicitly requests it. Keep them empty in a multi-tenant deployment unless its control plane
supplies the corresponding tenant custody, egress, and storage boundary. Never place Brain's own
API or cloud credentials in the secret allow-list. A session can make the server call any
Environment URL it names with the session's own credential; a hosted multi-tenant deployment may
want an egress ceiling on those URLs.
Docker
The image sets BRAIN_DATA_DIR=/var/lib/brain, BRAIN_ENV_WORKER=/usr/local/bin/brain-env-worker,
and BRAIN_LISTEN=0.0.0.0:8080, declares /var/lib/brain as a volume, and runs as uid 10001.
docker run --rm -p 127.0.0.1:8080:8080 \
-e BRAIN_API_TOKEN=local-development \
-v brain-data:/var/lib/brain ghcr.io/aexhq/brain:latestThis local example uses a development token. For deployment, set a private token and pin the
tested image digest or ghcr.io/aexhq/brain:sha-<commit> tag; latest moves between releases.
See release matching.
Health
Both health routes are public. GET /health/live returns 204 when the standalone server can
answer requests. GET /health/ready returns 204 when the built-in worker pool is ready, or 503
when it is unavailable. Readiness does not validate model keys, remote Environments or free
storage space. A successful check is not a guarantee that a particular turn will succeed.