Iris Docs

Configuration

Environment variables, CLI flags, and the security posture of the internal API.

Iris reads configuration from /iris/.env (written by bootstrap) and CLI flags (--provider, --model, --sandbox, --transport, --api-port). Flags override env vars.

Environment variables

VariableDefaultPurpose
IRIS_PROVIDER / IRIS_MODELanthropic / provider defaultLLM provider and model (see data/models.json)
IRIS_SLACK_APP_TOKEN / IRIS_SLACK_BOT_TOKENSlack tokens; presence enables the Slack transport
TELEGRAM_BOT_TOKENTelegram token; presence enables the Telegram transport
IRIS_WEBUI_PORTPresence enables the built-in web chat transport, bound to 127.0.0.1
IRIS_WEBUI_PASSWORDShared-secret login for the web UI. Unset = no auth gate (fine for loopback-only use; set before exposing via serve-public)
IRIS_ENVprodpreview | prod
IRIS_API_PORT / IRIS_API_HOST3000 / 127.0.0.1Internal HTTP API bind (always on)
IRIS_API_TOKENWhen set, API requires Authorization: Bearer <token> (except /health)
IRIS_BRIDGE_PORT / IRIS_BRIDGE_HOST— / 127.0.0.1Sub-agent bridge server (sub-agents only)
IRIS_LLM_TIMEOUT_SECS90Per-attempt LLM timeout
IRIS_LLM_MAX_RETRIES / IRIS_LLM_RETRY_BASE_MS3 / 2000Retry with exponential backoff on 429/timeout/transient errors
IRIS_COMPACT_THRESHOLD / IRIS_COMPACT_TARGET0.6 / 0.1Pre-run auto-compaction trigger/target (fraction of context window)
IRIS_SLACK_MAX_CHARS30000Safe Slack message length before splitting
IRIS_TELEGRAM_FORCE_RECLAIMSet true + restart to transfer bot ownership
IRIS_GITHUB_ORG / IRIS_GITHUB_REPOThe repo Iris commits her own skills, sub-agents, and self-edits to (the github skill's push target — see Extending Iris). Use a fork of iris-core or your own private overlay repo, never the upstream you cloned from. Prompted by bootstrap alongside the GitHub token; also injected into the constitution as Iris's identity source
IRIS_KEY_VAULTAzure Key Vault name (Key Vault profile only)
IRIS_SECRETS_MODEenvenv | store | proxy — opt-in credential broker, see Secrets
IRIS_SECRET_KEY_FILE / IRIS_SECRET_STORE_FILE/iris/secret.key / /iris/secrets.json.encEncrypted store paths (store mode)
IRIS_BROKER_PORT / IRIS_BROKER_HOST9099 / 127.0.0.1iris-broker daemon bind (proxy mode)
IRIS_BROKER_SERVICES_FILE/iris/broker/services.jsonOperator overrides for the injection gateway's service map
IRIS_SECRET_BROKER_URL / IRIS_SECRET_BROKER_TOKENWhen set, GET /secrets/:name proxies here instead of env/Key Vault/store — points at the bundled iris-broker (proxy mode), Vault, Infisical, or any HTTP service speaking the same tiny contract
IRIS_BASE_DOMAIN / IRIS_EMAIL_FROMPublic serving domain / outbound email sender
PASSTHROUGH_API_KEYFallback API key for passthrough channels (see Channel Modes)

Models and providers

The runtime loads provider endpoints and model definitions from <workspace>/models.json (generated from data/models.json.template at bootstrap). Anthropic and OpenAI work out of the box; custom endpoints (Azure AI Foundry, DeepSeek, Mistral, AWS Bedrock) are defined in the template. Switch with:

IRIS_PROVIDER=anthropic
IRIS_MODEL=claude-sonnet-4-5

For Azure AI Foundry (azure-foundry), bootstrap asks for the bare account name (e.g. my-account-eastus2), not the full endpoint URL. Pasted URLs or hostnames are trimmed automatically, and the generated baseUrl is validated — bootstrap aborts on a malformed hostname and warns if it doesn't resolve in DNS.

DeepSeek (deepseek) and Mistral (mistral, including Devstral) need only an API key — both go through pi-ai's openai-completions provider module, since Mistral's /v1/chat/completions endpoint is OpenAI-compatible and pi-ai's native mistral provider module hangs indefinitely on every call (see the Fixed entry in iris-runtime/CHANGELOG.md — do not switch Mistral's api back to "mistral"). Both ship ready-to-use model entries in the template (deepseek-chat / deepseek-reasoner, devstral-medium-latest / mistral-large-latest).

For any other OpenAI-compatible endpoint (Kimi/Moonshot direct, a self-hosted vLLM/Ollama gateway, etc.), pick custom — bootstrap asks for a short provider name (used as the models.json key), the base URL, the API key, and the exact model id the endpoint expects, and writes a fresh openai-completions provider block. To add one without bootstrap, add a block by hand — see data/README.md for the shape.

azure-foundry was named foundry-e2 before this repo supported more than one custom provider; the name was a leftover from its original eastus2 deployment. Bootstrap migrates IRIS_PROVIDER=foundry-e2 and the FOUNDRY_E2_KEY/FOUNDRY-E2-KEY secret automatically on re-run, but a hand-edited models.json needs its foundry-e2 key renamed manually.

MCP servers

External toolsets connect via <workspace>/data/mcp.json (optional, hot-reloaded per message; secrets referenced as ${VAR} from .env) — see MCP Servers.

Internal API security

The internal API binds to loopback by default. If sub-agent containers reach Iris via the Docker gateway (172.18.0.1:3000), set IRIS_API_HOST=0.0.0.0 and IRIS_API_TOKEN — never expose the API beyond loopback without a token. Iris logs a warning at startup if you do.

LLM resilience

Two mechanisms keep long-running channels healthy:

  • Retry with backoff — failed LLM calls (429, timeout, connection reset) retry up to IRIS_LLM_MAX_RETRIES times with jittered exponential backoff, posting a visible _Retrying (n/3)..._ notice.
  • Auto-compaction — before each prompt, if the estimated context exceeds IRIS_COMPACT_THRESHOLD of the model window, Iris summarises older history down toward IRIS_COMPACT_TARGET (up to 3 passes). A post-run check at ≥70% real usage acts as a backstop.
Edit this page on GitHub