Configuration
The complete environment-variable reference for IntelliApps — core server, secrets and signed tokens, the three data planes, S3 assets, remote-image fetch, upload/version limits, theming, deployment branding, the ask-the-data LLM, and the Identity Bridge — plus how the service connects to the IntelliAsk stack.
IntelliApps is configured entirely through environment variables (optionally loaded
from a local .env file). Every value is validated at startup; in non-development
environments the service refuses to boot with placeholder secrets so an insecure
deployment can't be created by accident.
Names below are the exact environment-variable names the container reads (case-insensitive). This page covers the core service; the per-feature tuning knobs for published pages live on Published-page features.
Production refuses placeholder secrets
When APP_ENV is not development, the service will not start if
HTML_APP_MCP_API_KEY, PREVIEW_SIGNING_SECRET, or DOWNLOAD_SIGNING_SECRET are
left at their change-me defaults. Set strong, unique values before deploying.
Core server
| Name | Purpose | Default | Required |
|---|---|---|---|
APP_ENV | Environment: development, staging, or production. Non-dev enables secret validation | development | No |
SERVICE_HOST | Bind address for the server | 0.0.0.0 | No |
SERVICE_PORT | Port the server listens on | 8000 | No |
MCP_STATELESS_HTTP | Serve the MCP endpoint in stateless Streamable HTTP mode | true | No |
MCP_REQUEST_STATE_SECRET | Optional secret for MCP request-state signing | (empty) | No |
HTML_APP_MCP_API_KEY | Shared service key the IntelliAsk container presents as X-App-Service-Key | change-me | Yes (prod) |
PUBLIC_BASE_URL | Public origin of this service, used to build absolute preview/publish/download URLs | http://localhost:8000 | Yes (prod) |
INTELLIASK_ORIGIN | The IntelliAsk app origin — used for the page CSP frame-ancestors, the landing link, and the default sign-in handoff URL | http://localhost:3080 | Yes (prod) |
PUBLISH_MODE | unlisted (shareable-link only) or authenticated (requires an upstream auth proxy) | unlisted | No |
authenticated publish needs a proxy
PUBLISH_MODE=authenticated requires INTELLIASK_ORIGIN to be set, because the
service cannot verify identity itself — it relies on an upstream authenticating
proxy. In a non-dev environment it refuses to start otherwise.
Secrets & signed tokens
Previews and downloads are authorised by HMAC-signed, time-limited tokens rather than sessions, so the service stays stateless.
| Name | Purpose | Default | Required |
|---|---|---|---|
PREVIEW_SIGNING_SECRET | Secret signing preview tokens | change-me-too | Yes (prod) |
DOWNLOAD_SIGNING_SECRET | Secret signing self-contained-export download tokens | change-me-too | Yes (prod) |
PREVIEW_TOKEN_TTL_SECONDS | Lifetime of a preview token | 3600 (1 h) | No |
DOWNLOAD_TOKEN_TTL_SECONDS | Lifetime of a download token | 900 (15 m) | No |
PUBLISH_UNLOCK_TTL_SECONDS | Lifetime of a password-unlock cookie for a protected page | 28800 (8 h) | No |
Data planes
Persistence is split into three planes (see
Architecture → data planes).
Each backend is pluggable; the memory options exist for tests/local runs.
Control plane (MongoDB)
| Name | Purpose | Default | Required |
|---|---|---|---|
PLATFORM_BACKEND | mongo (pymongo) or memory (mongomock) | mongo | No |
MONGO_URL | MongoDB connection string | mongodb://localhost:27017 | Yes (prod) |
MONGO_DB_NAME | Database name for control-plane collections | intelliapps | No |
App-data plane (PostgreSQL)
| Name | Purpose | Default | Required |
|---|---|---|---|
APPDATA_BACKEND | postgres (psycopg) or memory (in-process) | postgres | No |
APPDATA_URL | PostgreSQL DSN for per-app datasets and live collections | postgresql://intelliapps:intelliapps@localhost:5432/intelliapps_data | Yes (prod) |
The app-data plane owns both the generated datasets and each app's live
read/write collections (one schema per app, app_<app_id>). The definition and
ownership metadata for those collections still lives in the control plane (MongoDB).
Asset plane (S3)
Binary assets an app references (uploaded images, fonts) are stored content-addressed by SHA-256 in S3-compatible object storage, so the service stays stateless and identical bytes are never duplicated across versions.
| Name | Purpose | Default | Required |
|---|---|---|---|
ASSET_BACKEND | s3 (boto3 / AWS S3 / MinIO) or memory (in-process) | s3 | No |
ASSET_S3_BUCKET | Bucket for assets | intelliapps-assets | No |
ASSET_S3_ENDPOINT_URL | S3 endpoint — empty for AWS, set for MinIO/self-hosted | (empty) | No |
ASSET_S3_REGION | S3 region | (empty) | No |
ASSET_S3_ACCESS_KEY_ID | Access key | (empty) | Yes (with s3) |
ASSET_S3_SECRET_ACCESS_KEY | Secret key | (empty) | Yes (with s3) |
ASSET_S3_USE_PATH_STYLE | Use path-style addressing (required by MinIO and most self-hosted gateways) | true | No |
MAX_ASSET_BYTES | Per-file upload cap | 5000000 (5 MB) | No |
ALLOWED_ASSET_CONTENT_TYPES | Comma list of accepted asset content types | image/png,image/jpeg,image/gif,image/webp,image/svg+xml,font/woff,font/woff2 | No |
Remote image fetch (web-search → asset)
The builder agent can pull an image it found on the web straight into the app's asset plane (the build sandbox has no network of its own, so the service performs the fetch — guarded against SSRF).
| Name | Purpose | Default | Required |
|---|---|---|---|
ASSET_FETCH_ENABLED | Allow the service to fetch remote images into the asset plane | true | No |
ASSET_FETCH_TIMEOUT_SECONDS | Per-fetch timeout | 10.0 | No |
ASSET_FETCH_MAX_REDIRECTS | Max redirects followed | 3 | No |
FETCHABLE_IMAGE_CONTENT_TYPES | Content types accepted from a remote fetch (images only — never fonts or SVG) | image/png,image/jpeg,image/gif,image/webp | No |
SSRF guardrails
Remote fetches allow only public http/https hosts (no private/loopback
ranges), cap size (MAX_ASSET_BYTES) and time, and reject SVG and internal hosts.
Set ASSET_FETCH_ENABLED=false to disable the capability entirely.
Upload & version limits
| Name | Purpose | Default | Required |
|---|---|---|---|
MAX_HTML_BYTES | Max size of a saved app's HTML | 2000000 (2 MB) | No |
MAX_DATASET_IMPORT_ROWS_PER_CALL | Hard cap on rows accepted in one import call | 1000 | No |
MAX_DATASET_IMPORT_PAYLOAD_BYTES | Hard cap on one import call's payload size | 5000000 (5 MB) | No |
MAX_SNAPSHOT_DATA_BYTES | Max dataset bytes snapshotted into a version | 25000000 (25 MB) | No |
DATASET_IMPORT_RECOMMENDED_ROWS_PER_CHUNK | Rows the builder is advised to send per append_dataset_rows call | 500 | No |
STALE_IMPORT_TTL_SECONDS | Abandoned, never-finished imports older than this are swept (0 disables) | 86400 (24 h) | No |
MAX_VERSIONS_RETAINED | Immutable versions kept per app; the current and published versions are always retained (0 = unlimited) | 0 | No |
Theming
A served page's visual theme comes from /runtime/app-base.css. The choices are
go-light, go-dark, light, dark, plus the none sentinel (platform theming
off — the app's own CSS fully owns the page).
| Name | Purpose | Default | Required |
|---|---|---|---|
DEFAULT_THEME | Theme applied to apps that haven't pinned their own | go-light | No |
DEFAULT_THEME_ROTATION | Comma/space list seeded onto new apps as their theme-switcher rotation (e.g. go-light,go-dark); empty = new apps ship no switcher | (empty) | No |
Deployment branding (company logo)
When configured, a logo is base64-inlined into every app's data bootstrap and auto-rendered in a page corner, surviving preview, publish, and the offline export (which has no server). Priority when several are set: data URI → URL → path.
| Name | Purpose | Default | Required |
|---|---|---|---|
BRAND_LOGO_PATH | Filesystem path to the logo image (svg/png/jpg/webp/gif). Empty disables the whole feature | (empty) | No |
BRAND_LOGO_DATA_URI | The logo supplied inline as a data:image/...;base64,... string (no file mount needed). Wins over the others | (empty) | No |
BRAND_LOGO_URL | Public http(s) URL the server fetches once (SSRF-guarded) and inlines. PNG/JPEG/GIF/WebP only | (empty) | No |
BRAND_LOGO_ALT | Alt text; empty means the logo is treated as decorative (aria-hidden) | (empty) | No |
BRAND_LOGO_PLACEMENT | Default corner: top-left, top-right, bottom-left, bottom-right | top-right | No |
BRAND_LOGO_DEFAULT_ON | Whether apps show the logo by default (true) or only on explicit opt-in (false) | true | No |
Ask-the-data LLM
The published-page ask-the-data chat routes viewer questions back through
IntelliAsk's model gateway using a service key. The cleanest setup is to leave the
overrides blank and let it reuse the same chat credentials the IntelliAsk container
already has (the ANTHROPIC_* values) — deploying in the same stack then needs no
new LLM secrets.
| Name | Purpose | Default | Required |
|---|---|---|---|
ASK_LLM_PROVIDER | Wire format: openai, anthropic, or empty to infer | (empty) | No |
ASK_LLM_BASE_URL | OpenAI-compatible gateway base (e.g. https://gateway/v1) | (empty) | No |
ASK_LLM_API_KEY | Gateway API key | (empty) | No |
ASK_LLM_MODEL | Model id; blank inherits the stack's default chat model | (empty) | No |
ASK_LLM_MODELS | JSON array of selectable model profiles (see below) | (empty) | No |
Multiple selectable models
ASK_LLM_MODELS is a JSON array of profiles so each app can pick its own model. Any
omitted provider/base_url/api_key inherits the effective defaults, so a
single shared gateway sets its secret once and each extra model is just
{"name","model"}:
The first entry is the default when an app doesn't choose. When empty, a single implicit profile is synthesized from the effective defaults.
Shared IntelliAsk chat provider (fallback)
Used whenever the ASK_LLM_* overrides are blank — mirror the env the IntelliAsk
(LibreChat) container already sets:
| Name | Purpose | Default | Required |
|---|---|---|---|
ANTHROPIC_API_KEY | Chat provider key reused by ask-the-data | (empty) | No |
ANTHROPIC_REVERSE_PROXY | Reverse-proxy base (e.g. https://<host>/anthropic/) | (empty) | No |
ANTHROPIC_MODELS | Comma list; the first entry is the default model | (empty) | No |
Ask-the-data limits
| Name | Purpose | Default | Required |
|---|---|---|---|
ASK_DATA_MAX_QUESTION_CHARS | Max characters per viewer question | 1000 | No |
ASK_DATA_MAX_CONTEXT_BYTES | Max dataset JSON bytes sent as context (larger is truncated) | 200000 | No |
ASK_DATA_MAX_PAGE_CHARS | Max page text used as grounding when the app has no dataset | 24000 | No |
ASK_DATA_RATE_PER_MIN | Questions per client fingerprint per 60 s (0 disables) | 15 | No |
ASK_DATA_MAX_ANSWER_TOKENS | Upper bound on answer length | 800 | No |
ASK_DATA_TIMEOUT_SECONDS | HTTP timeout for the model call | 45.0 | No |
Identity Bridge
Deployment/org policy defaults for the two identity planes (see Security → Identity Bridge).
| Name | Purpose | Default | Required |
|---|---|---|---|
IDENTITY_PLATFORM_DEFAULT | Whether a new app uses the authenticated IntelliAsk identity for platform features | true | No |
IDENTITY_APP_CLAIMS_ALLOWED | Org allow-list — the claims an app owner may ever expose to generated app code | id, nickname, display_name, first_name, last_name, email, avatar_url | No |
IDENTITY_APP_DEFAULT_CLAIMS | Claims pre-selected when an owner first enables App Code Identity (intersected with the allow-list) | (full approved profile) | No |
IDENTITY_GUEST_NAME_MAX_CHARS | Max characters for a platform-feature guest display name | 60 | No |
IDENTITY_VIEW_TOKEN_TTL_SECONDS | Lifetime of the signed identity token in an embedded view_url | 600 (10 m) | No |
IDENTITY_COOKIE_TTL_SECONDS | Lifetime of the per-viewer identity cookie set from a valid view token | 28800 (8 h) | No |
IDENTITY_SIGNIN_URL_TEMPLATE | Override for the standalone sign-in handoff URL; blank auto-derives <INTELLIASK_ORIGIN>/intelliapps/view/{app_id}?redirect=1 | (empty) | No |
Connecting to IntelliAsk
IntelliApps is reached by the IntelliAsk container as a native MCP server named
intelliapps, injected automatically at container build when the two variables below
are set on the IntelliAsk side. They are the intelliask-side counterpart of this
service's HTML_APP_MCP_API_KEY.
| Name (set on the IntelliAsk container) | Purpose | Required |
|---|---|---|
INTELLIAPPS_API_URL | Base URL of this IntelliApps service (the injected MCP server points at ${INTELLIAPPS_API_URL}/mcp) | Yes |
INTELLIAPPS_SERVICE_KEY | Shared service key sent as the X-App-Service-Key header — must equal this service's HTML_APP_MCP_API_KEY | Yes |
Legacy names still accepted
The older HTML_APPS_API_URL / HTML_APPS_SERVICE_KEY names are still read as
fallbacks. If an operator declares mcpServers.intelliapps directly in
intelliask.yaml, that entry wins and the auto-injection defers to it.
When both are set, the IntelliAsk startup log shows
[IntelliApps] Native MCP server "intelliapps" injected...; when they're missing it
logs ... NOT injected — missing env: .... See
Adding Environment Variables for how to wire a value
through config/.env into the container.
Last updated on