Configuration#
The Lens Prism runtime is configured entirely through environment variables. For a native install they go in ~/.prism/.env (restart the service after editing); for Docker, pass them with -e. Only an LLM credential is required — everything else has a sensible default.
Provider selection#
The runtime talks to one LLM provider per container, chosen by LLM_PROVIDER.
| Variable | Description | Default |
|---|---|---|
LLM_PROVIDER |
LLM platform: bedrock (AWS) or azure (Claude via Microsoft Foundry). Any other value falls back to bedrock. |
bedrock |
Both platforms serve Claude through the Anthropic Messages API. azure mode runs the agent on Claude deployed in Microsoft Foundry (https://{resource}.services.ai.azure.com/anthropic/v1/messages). On Azure, memory embeddings come from an Azure OpenAI text-embedding-3 deployment (Anthropic has no embedding model), defaulting to text-embedding-3-small; if that deployment doesn't exist, memory embedding fails open (search degraded, no crash).
Each platform can run direct or through Nexus (the LLM gateway). Routing is automatic: set NEXUS_API_URL and the runtime routes through Nexus, otherwise it talks to the platform directly. Through Nexus the gateway holds the platform credentials, so no local LLM credential is needed.
Credentials#
| Variable | Description |
|---|---|
AWS_BEARER_TOKEN_BEDROCK |
Bedrock API key. The AI SDK auto-selects bearer auth when this is set. This is the one credential required for chat on Bedrock. |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY |
Bedrock AWS SigV4 credentials, as an alternative to the bearer token. |
AZURE_API_KEY |
Azure Foundry resource key, sent as the x-api-key header. Required for direct mode only — when routing through Nexus the gateway holds the key for both chat and embeddings. May be a __nexus_cred:<uuid>__ sentinel the proxy rewrites on the wire. |
AZURE_RESOURCE_NAME |
Azure (direct) Foundry resource name — derives the chat endpoint https://{resource}.services.ai.azure.com/anthropic/v1 and the embeddings endpoint https://{resource}.openai.azure.com. |
AZURE_FOUNDRY_BASE_URL |
Azure. Override the derived Foundry Anthropic chat endpoint (must end at /anthropic/v1). |
SLACK_BOT_TOKEN |
Slack bot token (xoxb-…). Enables the Slack adapter; validated via auth.test on boot. |
SLACK_APP_TOKEN |
Slack app-level token (xapp-…) for Socket Mode. |
SLACK_EXPECTED_APP_ID |
Optional safety check — the bot token's app ID must match this if set. |
See Slack for how the tokens are used. Bedrock is not mandatory — set the credentials for whichever provider LLM_PROVIDER selects.
Core#
| Variable | Description | Default |
|---|---|---|
PORT |
HTTP port the runtime listens on. | 3003 |
DATABASE_URL |
SQLite URL for the agent database. The Docker image's start.sh sets this to file:/data/agent.db; locally it resolves next to the Prisma schema. |
file:/data/agent.db (Docker) |
AGENT_ID |
Pin the agent's UUID. Unset generates a fresh UUID on first boot and reuses it thereafter. | generated |
AGENT_NAME |
Display name on first boot. | Prism |
TEAM_NAME |
Team name on first boot. | Local |
OWNER_USER_ID |
Owner user ID on first boot. | local sentinel UUID |
SHELL_WORKSPACE_ROOT |
Working directory for the agent's shell tools. | install workspace dir (Docker: /home/node) |
PRISM_DATA_DIR |
Persistent data dir for skills and the Claude Code config. The Docker image sets this to the /data volume. |
/data (Docker), else ~/.prism |
PRISM_SKILLS_DIR |
Override the skills directory specifically. | <data dir>/skills |
AGENT_NAME, TEAM_NAME, and OWNER_USER_ID only matter on the first boot with an empty database; later boots reuse the stored workspace.
Webhooks need no environment variables — the receiver toggle and subscriptions live in the database, managed from the web UI. The runtime doesn't authenticate inbound webhook calls itself (auth is the platform's job in front of the container), so don't expose the runtime port directly to the internet.
Chat verbosity#
The verbose setting controls how multi-step chat turns are delivered.
| Mode | Behavior |
|---|---|
Concise (default, verbose=false) |
Only the final text step of a turn is delivered to the channel. Intermediate steps are still saved but marked internal, so they stay hidden both live and when the thread is reloaded. The final message must be self-contained. |
Verbose (verbose=true) |
Every text step is delivered as it arrives — the streaming behavior. |
This is a per-agent database setting, not an environment variable. Set it via the Profile page toggle in the web UI, PATCH /agents/verbose with { "verbose": true | false }, or by asking the agent (the update_settings tool accepts verbose).
Persistence is unchanged — every step is always stored, and concise mode only flags the intermediate ones as internal — so the model's context window is correct regardless of mode.
Models#
Which set applies depends on LLM_PROVIDER. Bedrock model IDs are Bedrock model identifiers; Azure model IDs are Foundry deployment names (which default to Claude model IDs when you deploy without renaming).
| Variable | Description | Default |
|---|---|---|
BEDROCK_MODEL_ID |
Bedrock main model (the agent's reasoning loop). | us.anthropic.claude-opus-5 |
BEDROCK_CLASSIFICATION_MODEL_ID |
Bedrock fast model for the heartbeat DELIVER/SUPPRESS gate. | a Claude Haiku model |
BEDROCK_EMBEDDING_MODEL_ID |
Bedrock embedding model for searchable memory. | amazon.titan-embed-text-v2:0 |
AWS_REGION |
Bedrock AWS region. | us-east-1 |
AZURE_MODEL_ID |
Azure main model — a Claude chat deployment name. | claude-opus-5 |
AZURE_CLASSIFICATION_MODEL_ID |
Azure fast Claude deployment for the heartbeat gate. | claude-haiku-4-5 |
AZURE_EMBEDDING_MODEL_ID |
Azure OpenAI embedding deployment (a text-embedding-3 model; truncated to 1024 dims to match the memory index). The deployment must exist on the resource, else memory embedding fails open. Set to '' to skip embeddings entirely. |
text-embedding-3-small |
AZURE_API_VERSION |
Azure OpenAI API version (embeddings only). | SDK default (preview) |
CONTEXT_WINDOW_TOKENS |
Input-context window (tokens) to assume for the agent's model. Only needed when the catalog doesn't recognize it. Ignored unless a positive integer. | derived from the model ID |
MODELS_DEV_URL |
Refresh the model-window catalog from a registry once at startup. Unset means no outbound call, bundled catalog only. | disabled |
The main model can also be set per-agent at runtime (web UI Profile, the TUI /model command, or by asking the agent), which overrides the env default. On Azure, per-agent overrides are Foundry deployment names.
Heartbeat and scheduled (cron) runs can each use their own model, set the same ways — the web UI Profile page or the TUI /heartbeat-model and /cron-model commands. Both default to empty and fall back to the main model (which falls back to BEDROCK_MODEL_ID), so you can run routine heartbeats on a cheaper model while chat stays on a stronger one. The heartbeat gate always uses the active platform's classification model, independent of this.
Context-window size#
The web UI and terminal UI show how much of the model's context window a conversation has used. The runtime reads it from a bundled catalog of Claude window sizes sourced from models.dev. That bundled copy needs no network and is the only source by default.
Set MODELS_DEV_URL=https://models.dev/api.json to also refresh the catalog once at startup, so a model released after the build gets a window. Enable it deliberately — models.dev is community-maintained, so a wrong number upstream reaches your deployment without review.
Warning
In a sandboxed or egress-filtered deployment, enabling MODELS_DEV_URL means allow-listing models.dev — and an allow-list is not per-process. Once the domain is reachable, it's reachable by the agent's own tools too, not just the startup refresh. Treat it as adding a domain of untrusted, community-edited content to the web the agent can reach and act on.
When a model is in neither layer the indicator is hidden rather than guessed. That's most likely on Azure, where model IDs are deployment names you chose: AZURE_MODEL_ID=my-opus-deploy can't appear in any catalog. Set CONTEXT_WINDOW_TOKENS to that model's input-context size (for example 1000000) to bring it back. It applies to every model the agent uses, so the main and heartbeat models can't be given different windows.
Bootstrap model defaults#
When the runtime first creates an agent (empty database), it seeds the three model overrides from ~/.prism/settings.json if present — the same file the prism TUI reads.
| Key | Seeds |
|---|---|
modelId |
the main model |
heartbeatModelId |
the heartbeat model |
cronModelId |
the scheduled-task model |
Each is optional; an unset, blank, or malformed value leaves that override empty (and it falls back as above). These apply only at creation — editing them later doesn't touch an existing agent; use the Profile page or the TUI commands for that.
Observability#
All optional; each is off until its variable is set. Langfuse traces every LLM call (model, tokens, tool calls, latency); OpenTelemetry exports product telemetry to a collector. Structured logs (Pino) are always on.
| Variable | Description | Default |
|---|---|---|
LANGFUSE_SECRET_KEY |
Enables Langfuse LLM tracing when set. | — |
LANGFUSE_PUBLIC_KEY |
Langfuse public key. | — |
LANGFUSE_BASE_URL |
Langfuse server URL. | http://localhost:3100 |
OTEL_EXPORTER_OTLP_ENDPOINT |
Enables OpenTelemetry export when set. | — |
OTEL_EXPORTER_OTLP_API_KEY |
Collector auth, sent as x-api-key. |
— |
DEPLOYMENT_ENVIRONMENT |
Tags OTel records (production / staging / development). |
production (published images) |
With OpenTelemetry enabled, the runtime emits product telemetry events. They carry only identifiers, flags, and counts — never credentials, URLs, file paths, or message content.
Installer variables#
These affect the native installer, not the running agent.
| Variable | Description | Default |
|---|---|---|
PRISM_HOME |
Install directory. | ~/.prism (%USERPROFILE%\.prism) |
PRISM_HTTP_URL |
Runtime URL the prism TUI connects to. |
http://localhost:3003 |