Configuration¶
Every Imbi service reads its configuration from environment variables and,
for some settings classes, from a config.toml file. This page is the full
reference. For the minimum set that starts each service,
see Configuration in Getting Started.
Sources and precedence¶
The settings classes use pydantic-settings. Each service reads values from these sources:
- Environment variables.
- A
.envfile in the working directory. An environment variable wins over the same name in.env. - A
config.tomlfile, for the settings classes in the next section. An environment variable or a.enventry wins over the same key inconfig.toml. - Built-in defaults. The tables below show them.
The settings classes accept variable names in upper or lower case. Some
variables are read directly from the process environment, for example
ENVIRONMENT, SENTRY_DSN, and IMBI_PROMPT_*. Those must be in upper case,
and the .env file does not set them.
config.toml¶
Each section of config.toml sets one settings class. The key is the field
name, which is the variable name without the prefix, in lower case:
| Section | Settings | Services |
|---|---|---|
[auth] |
The IMBI_AUTH_* fields |
All |
[clickhouse] |
The CLICKHOUSE_* fields |
All |
[embeddings] |
The EMBEDDINGS_* fields |
All |
[plugins] |
imbi_plugins, imbi_plugins_disabled (lists) |
All |
[postgres] |
The POSTGRES_* fields |
All |
[releases] |
The IMBI_RELEASES_* fields |
All |
[ssl] |
cert_dir |
All |
[valkey] |
The VALKEY_* fields |
All |
[server] |
The IMBI_API_* fields, url, ui_url |
imbi-api |
[email] |
The IMBI_EMAIL_* fields |
imbi-api |
[storage] |
The S3_* fields |
imbi-api |
Other settings classes, for example Iggy, ConfigSecrets, and the
Anthropic settings, do not read config.toml. Use their environment
variables.
Each service looks for the file in these places, in this order. A key in an earlier file wins over the same key in a later file:
./config.toml~/.config/imbi/config.toml/etc/imbi/config.toml
An environment variable always wins over the same key in config.toml.
The file supplies only the keys that the environment does not set.
imbi-api reads [server] one time, when the application starts. The route
prefix (the path of url), the CORS origins, the forwarded IPs, the OAuth
URLs, and the cookie path all come from that one read.
Example:
ENVIRONMENT and production¶
ENVIRONMENT has no prefix. Every service reads it. The default is
development. Set it to production in production.
ENVIRONMENT |
IMBI_AUTH_JWT_SECRET, IMBI_AUTH_ENCRYPTION_KEY, IMBI_CONFIG_ENCRYPTION_KEY |
Mailpit auto-configuration |
|---|---|---|
development (or unset) |
Generated per process when not set, with a warning | On |
| Any other value | Required. The service does not start without them | Off |
A generated key is different in each process and after each restart. Then:
- every issued token becomes invalid,
- a value encrypted by one process cannot be decrypted by another process or after a restart (OAuth tokens, AI provider keys, MCP server credentials).
Generate the three values once and store them in your secret store:
python -c "import secrets; print(secrets.token_urlsafe(32))" # IMBI_AUTH_JWT_SECRET
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" # IMBI_AUTH_ENCRYPTION_KEY
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" # IMBI_CONFIG_ENCRYPTION_KEY
Use a different key for IMBI_AUTH_ENCRYPTION_KEY and
IMBI_CONFIG_ENCRYPTION_KEY, so that you can rotate them separately.
IMBI_API_ENVIRONMENT is a different variable
imbi-api also reads IMBI_API_ENVIRONMENT ([server] environment).
It controls only the Secure flag of the auth cookies: the flag is set
when the value is not development. Set IMBI_API_ENVIRONMENT=production
too when the UI is served over HTTPS. The Helm chart sets both from its
environment value, which defaults to production.
IMBI_ENVIRONMENT is not read
No code reads IMBI_ENVIRONMENT. Use ENVIRONMENT.
Production checklist¶
- Set
ENVIRONMENT=productionandIMBI_API_ENVIRONMENT=production. - Set
IMBI_AUTH_JWT_SECRET,IMBI_AUTH_ENCRYPTION_KEY, andIMBI_CONFIG_ENCRYPTION_KEYfrom your secret store. Use the same values in every service and every replica. - Set
IMBI_API_URLto the public API URL with its path, for examplehttps://imbi.example.com/api, andIMBI_UI_URLto the public UI URL. - Behind a proxy, set
IMBI_API_FORWARDED_ALLOW_IPSto the proxy addresses. Otherwise rate limits and OAuth URLs use the proxy address. - Set
IMBI_API_CORS_ALLOWED_ORIGINSto the exact origins that call the API. - Set
VALKEY_URL. If imbi-api cannot reach Valkey, the background workers that need it do not start, and imbi-api logs a warning.
Environment variables¶
The tables come from scripts/docs_env_table.py. Run it after you add or
change a setting, and paste its output here:
The Shared table lists the settings in imbi-common. Each service reads
the shared settings that it uses: for example, every service that opens
PostgreSQL reads POSTGRES_*. The other tables list the settings that only
that service reads. Some variables, for example IMBI_INTERNAL_API_URL, show
in more than one table because more than one service reads them.
In the type column, list[str] values are a JSON array, except
IMBI_PLUGINS, IMBI_PLUGINS_DISABLED, and IMBI_IGGY_CONNECTORS_API_KEYS,
which are comma-separated. A default of "none" means that the setting is
unset.
Shared (imbi-common)¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_AUTH_JWT_SECRET |
str | generated | Secret that signs access and refresh tokens. Required when ENVIRONMENT is not development. |
IMBI_AUTH_JWT_ALGORITHM |
str | HS256 |
JWT signing algorithm |
IMBI_AUTH_ACCESS_TOKEN_EXPIRE_SECONDS |
int | 3600 |
Access token lifetime |
IMBI_AUTH_REFRESH_TOKEN_EXPIRE_SECONDS |
int | 2592000 |
Refresh token lifetime. Refresh tokens rotate on each use. |
IMBI_AUTH_LAST_USED_THROTTLE_SECONDS |
int | 60 |
Minimum seconds between two writes of the last_used time of an API key. 0 writes on each request. |
IMBI_AUTH_ENCRYPTION_KEY |
str | none | Fernet key that encrypts OAuth tokens and client secrets. Required when ENVIRONMENT is not development; generated per process in development. |
IMBI_CONFIG_ENCRYPTION_KEY |
str | none | Fernet key that encrypts configuration secrets, for example AI provider keys and MCP server credentials. Required when ENVIRONMENT is not development; generated per process in development. |
POSTGRES_URL |
PostgresDsn | postgresql://postgres:secret@localhost:5432/imbi |
PostgreSQL DSN |
POSTGRES_GRAPH_NAME |
str | imbi |
Apache AGE graph name |
POSTGRES_MIN_POOL_SIZE |
int | 2 |
Minimum connection pool size |
POSTGRES_MAX_POOL_SIZE |
int | 10 |
Maximum connection pool size |
CLICKHOUSE_URL |
ClickHouseDsn | clickhouse+http://localhost:8123 |
ClickHouse DSN. Credentials in the URL are used. |
CLICKHOUSE_CONNECT_TIMEOUT |
float | 10.0 |
Connection timeout in seconds |
CLICKHOUSE_MAX_CONNECT_ATTEMPTS |
int | 10 |
Connection attempts at startup |
CLICKHOUSE_CLUSTER_NAME |
str | none | Cluster name. When set, setup-clickhouse creates the schema ON CLUSTER <name> with Replicated table engines. Leave unset for one node. |
IGGY_URL |
IggyDSN | iggy+tcp://iggy:iggy@localhost:8090 |
Apache Iggy connection string. The scheme selects the transport: iggy, iggy+tcp, iggy+quic, iggy+http, iggy+ws. |
IGGY_CONNECT_TIMEOUT |
float | 10.0 |
Connection timeout in seconds |
IGGY_MAX_CONNECT_ATTEMPTS |
int | 10 |
Connection attempts at startup |
VALKEY_URL |
ValkeyDSN | valkey://localhost:6379/0 |
Valkey DSN |
IMBI_PLUGINS |
list[str] | [] |
Comma-separated package.module:Attr paths of plugins that do not use the imbi_plugin_* package name |
IMBI_PLUGINS_DISABLED |
list[str] | [] |
Comma-separated plugin slugs not to load |
IMBI_RELEASES_VERSION_FORMAT |
semver or commitish |
semver |
Version format that Release.version must match |
EMBEDDINGS_ENABLED |
bool | true |
Generate embeddings for vector search |
EMBEDDINGS_DEFAULT_MODEL |
str | text |
Key in EMBEDDINGS_MODELS to use |
EMBEDDINGS_MODELS |
dict[str, EmbeddingModelConfig] | {"text": {"fastembed_id": "BAAI/bge-small-en-v1.5", "dimensions": 384}} |
JSON map of model key to {fastembed_id, dimensions} |
SSL_CERT_DIR |
Path | none | Directory of CA certificates that every TLS context loads, in addition to the defaults |
ANTHROPIC_API_KEY |
SecretStr | none | Anthropic API key |
IMBI_ANTHROPIC_DEFAULT_MODEL |
str | claude-haiku-4-5-20251001 |
Model for structured completions, for example release-note drafts |
IMBI_ANTHROPIC_TIMEOUT |
float | 30.0 |
Request timeout in seconds |
IMBI_ANTHROPIC_MAX_RETRIES |
int | 2 |
Retries for each request |
IMBI_CLIENT_API_BASE_URL |
HttpUrl | http://imbi-api:8000/ |
Imbi API URL for the imbi.common.api client |
IMBI_CLIENT_API_TOKEN |
SecretStr | required | Bearer token for the imbi.common.api client |
IMBI_CLIENT_USER_AGENT |
str | none | User-Agent for the imbi.common.api client. Unset: imbi-common/<version>. |
IMBI_PROMPT_RENDER_INPROCESS |
str | '' |
true renders in the service process. For debugging only: it removes the isolation. |
IMBI_PROMPT_WORKERS |
int | 2 |
Prompt render worker processes per service process |
IMBI_PROMPT_WORKER_MAX_RENDERS |
int | 500 |
Renders before a worker is replaced |
IMBI_PROMPT_WORKER_MEMORY_MB |
int | 256 |
Address space in MiB that a worker can add after it starts. Linux only. |
SENTRY_TRACES_SAMPLE_RATE |
float | 0.0 |
Trace sample rate, 0.0 to 1.0. /status requests are never sampled. |
SENTRY_DSN |
str | none | Sentry DSN. Unset: Sentry is off. |
SERVICE |
str | unknown |
Server name sent to Sentry |
IMBI_RELOAD_DIRS |
str | '' |
Extra directories to watch with serve --dev, separated by the OS path separator |
ENVIRONMENT |
str | development |
Anything other than development makes the auth and config encryption keys required and turns off the Mailpit auto-configuration. The status pages show it. |
imbi-api¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_API_ENVIRONMENT |
str | development |
Anything other than development sets the Secure flag on the auth cookies |
IMBI_API_HOST |
str | localhost |
Host of the fallback public URL when IMBI_API_URL is unset. It does not set the bind address: use serve --host. |
IMBI_API_PORT |
int | 8000 |
Port of the fallback public URL. A tcp://ip:port value from Kubernetes service discovery is read as its port. |
IMBI_API_CORS_ALLOWED_ORIGINS |
list[str] | [] |
JSON array of allowed CORS origins. Also the trusted hosts for per-request OAuth URLs. |
IMBI_API_FORWARDED_ALLOW_IPS |
str | '' |
Comma-separated proxy IPs (or *) whose X-Forwarded-* headers are trusted. Empty: off. |
IMBI_API_URL |
str | '' |
Public imbi-api URL with its path prefix, for example https://imbi.example.com/api. The path is the API route prefix. |
IMBI_UI_URL |
str | '' |
Public UI URL, no path. Used for deep links. |
IMBI_AUTH_PASSWORD_MIN_LENGTH |
int | 12 |
Minimum password length |
IMBI_AUTH_PASSWORD_REQUIRE_UPPERCASE |
bool | true |
Require an uppercase letter |
IMBI_AUTH_PASSWORD_REQUIRE_LOWERCASE |
bool | true |
Require a lowercase letter |
IMBI_AUTH_PASSWORD_REQUIRE_DIGIT |
bool | true |
Require a digit |
IMBI_AUTH_PASSWORD_REQUIRE_SPECIAL |
bool | true |
Require a special character |
IMBI_AUTH_API_KEY_MAX_LIFETIME_DAYS |
int | 365 |
Maximum lifetime of an API key or client credential |
IMBI_AUTH_MFA_ISSUER_NAME |
str | Imbi |
Issuer name in authenticator apps |
IMBI_AUTH_MFA_TOTP_PERIOD |
int | 30 |
TOTP time step in seconds |
IMBI_AUTH_MFA_TOTP_DIGITS |
int | 6 |
TOTP code length |
IMBI_AUTH_RATE_LIMIT_LOGIN |
str | 5/minute |
Password login rate |
IMBI_AUTH_RATE_LIMIT_TOKEN_REFRESH |
str | 10/minute |
Token refresh rate |
IMBI_AUTH_RATE_LIMIT_OAUTH_INIT |
str | 3/minute |
OAuth flow start rate |
IMBI_AUTH_OAUTH_AUTO_LINK_BY_EMAIL |
bool | true |
Link an SSO sign-in to the user with the same email |
IMBI_AUTH_OAUTH_AUTO_CREATE_USERS |
bool | true |
Create a user at the first SSO sign-in |
IMBI_AUTH_DCR_ENABLED |
bool | true |
Let OAuth clients register at /auth/register (RFC 7591) |
IMBI_EMAIL_ENABLED |
bool | true |
Send email. false stops all email. |
IMBI_EMAIL_DRY_RUN |
bool | false |
Log messages, do not send them |
IMBI_EMAIL_SMTP_HOST |
str | localhost |
SMTP host |
IMBI_EMAIL_SMTP_PORT |
int | 587 |
SMTP port |
IMBI_EMAIL_SMTP_USE_TLS |
bool | true |
Use STARTTLS |
IMBI_EMAIL_SMTP_USE_SSL |
bool | false |
Use implicit TLS (usually port 465) |
IMBI_EMAIL_SMTP_USERNAME |
str | none | SMTP user name |
IMBI_EMAIL_SMTP_PASSWORD |
str | none | SMTP password |
IMBI_EMAIL_SMTP_TIMEOUT |
int | 30 |
SMTP timeout in seconds |
IMBI_EMAIL_FROM_EMAIL |
EmailStr | noreply@imbi.example.com |
Sender address |
IMBI_EMAIL_FROM_NAME |
str | Imbi |
Sender name |
IMBI_EMAIL_REPLY_TO |
EmailStr | none | Reply-To address |
IMBI_EMAIL_MAX_RETRIES |
int | 3 |
Send attempts after the first |
IMBI_EMAIL_INITIAL_RETRY_DELAY |
float | 1.0 |
First retry delay in seconds |
IMBI_EMAIL_MAX_RETRY_DELAY |
float | 60.0 |
Maximum retry delay in seconds |
IMBI_EMAIL_RETRY_BACKOFF_FACTOR |
float | 2.0 |
Retry delay multiplier |
S3_ENDPOINT_URL |
str | none | S3-compatible endpoint. Unset: AWS S3. |
S3_ACCESS_KEY |
str | none | Access key ID. Unset: the default AWS credential chain. |
S3_SECRET_KEY |
str | none | Secret access key |
S3_BUCKET |
str | imbi-uploads |
Bucket name |
S3_REGION |
str | us-east-1 |
AWS region |
S3_CREATE_BUCKET_ON_INIT |
bool | true |
Create the bucket at startup if it does not exist |
S3_MAX_FILE_SIZE |
int | 52428800 |
Upload size limit in bytes |
S3_ALLOWED_CONTENT_TYPES |
list[str] | ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml", "application/pdf"] |
JSON array of MIME types accepted for upload |
S3_THUMBNAIL_MAX_SIZE |
int | 256 |
Largest thumbnail side in pixels |
S3_THUMBNAIL_QUALITY |
int | 85 |
WEBP quality of thumbnails, 0 to 100 |
IMBI_IGGY_CONNECTORS_API_KEYS |
list[str] | [] |
Comma-separated bearer keys of the iggy-connect runtime. Empty: the connector config endpoint answers 503. |
IMBI_INTERNAL_ASSISTANT_URL |
str | '' |
Internal URL of imbi-assistant, for the status dashboard. Empty: not probed. |
IMBI_INTERNAL_GATEWAY_URL |
str | '' |
Internal URL of imbi-gateway, for the status dashboard |
IMBI_INTERNAL_MCP_URL |
str | '' |
Internal URL of imbi-mcp, for the status dashboard |
IMBI_INTERNAL_SCHEDULER_URL |
str | '' |
Internal URL of imbi-scheduler, for the status dashboard |
IMBI_INTERNAL_SLACKBOT_URL |
str | '' |
Internal URL of imbi-slackbot, for the status dashboard |
IMBI_INTERNAL_WORKFLOWS_URL |
str | '' |
Internal URL of imbi-workflows, for the status dashboard |
IMBI_AI_PROVIDER_API |
str | '' |
Id of the Anthropic AI provider (workload identity) of the imbi-api client. Empty: ANTHROPIC_API_KEY. |
IMBI_AI_PROVIDER_ASSISTANT |
str | '' |
Id of the AI provider whose token imbi-assistant gets |
IMBI_AI_PROVIDER_SLACKBOT |
str | '' |
Id of the AI provider whose token imbi-slackbot gets |
IMBI_HARNESS_EGRESS_PROXY_SECRET |
SecretStr | '' |
HS256 key that signs the proxy token of a runner claim. The egress proxy has the same key. Unset: no claim gets a proxy token, so host name egress destinations do not work. See Agent runners. |
IMBI_GATEWAY_API_TOKEN |
str | none | imbi-api setup and setup-service-accounts store this value as the API key of the imbi-gateway service account. Unset, they generate one and print it. |
IMBI_SCHEDULER_SA_CLIENT_ID |
str | none | setup stores this pair as the client credential of the imbi-scheduler service account. Unset, it generates a pair and prints it. |
IMBI_SCHEDULER_SA_CLIENT_SECRET |
str | none | See IMBI_SCHEDULER_SA_CLIENT_ID. |
IMBI_WORKFLOWS_SA_CLIENT_ID |
str | none | The same, for the imbi-workflows service account. |
IMBI_WORKFLOWS_SA_CLIENT_SECRET |
str | none | See IMBI_WORKFLOWS_SA_CLIENT_ID. |
IMBI_ASSISTANT_API_TOKEN |
str | none | The same as IMBI_GATEWAY_API_TOKEN, for the imbi-assistant service account. |
IMBI_SLACKBOT_API_TOKEN |
str | none | The same as IMBI_GATEWAY_API_TOKEN, for the imbi-slackbot service account. |
IMBI_PLUGIN_CACHE_TTL |
int | 60 |
Seconds that Valkey keeps the configuration key list of a project |
IMBI_PLUGIN_TIMEOUT_SECONDS |
int | 10 |
Timeout of one plugin call in seconds |
IMBI_PLUGINS_INDEX_URL |
str | https://pypi.org/simple |
Package index for plugin installs |
IMBI_PLUGINS_INSTALL_TIMEOUT |
int | 120 |
Timeout of one plugin install in seconds |
IMBI_PLUGINS_INSTALL_ENABLED |
bool | true |
false turns off plugin install at runtime |
MAILPIT_SMTP_PORT |
str | none | In development, with the default SMTP host and port, use this port and no TLS (Mailpit) |
IMBI_SECRETS_AWS_ENDPOINT_URL |
str | none | AWS endpoint of the secrets broker, for LocalStack. Unset: AWS. |
IMBI_SECRETS_GITHUB_GHES_HOSTS |
str | '' |
Comma-separated GitHub Enterprise Server hosts that a GitHub App binding can use |
imbi-assistant¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_ASSISTANT_ENABLED |
bool | false |
Turn the assistant on. ANTHROPIC_API_KEY turns it on too. |
IMBI_ASSISTANT_MODEL |
str | claude-sonnet-4-6 |
Claude model |
IMBI_ASSISTANT_MAX_TOKENS |
int | 16384 |
Maximum response tokens |
IMBI_ASSISTANT_MAX_CONVERSATION_TURNS |
int | 100 |
Maximum turns in one conversation |
IMBI_ASSISTANT_MAX_TOOL_ROUNDS |
int | 10 |
Maximum tool rounds for one message |
IMBI_ASSISTANT_MAX_TOOL_RESULT_CHARS |
int | 120000 |
Longer tool results are cut |
IMBI_ASSISTANT_SYSTEM_PROMPT |
str | none | Jinja system prompt that replaces the CMS and packaged prompts |
IMBI_ASSISTANT_PROMPT_REF |
str | imbi-assistant/system@stable |
Prompt CMS reference of the system prompt |
IMBI_ASSISTANT_API_TOKEN |
str | '' |
API key of the imbi-assistant service account. Set: the assistant uses the token of its AI provider from imbi-api instead of ANTHROPIC_API_KEY. |
IMBI_INTERNAL_API_URL |
str | http://localhost:8000 |
In-cluster origin of imbi-api |
IMBI_ASSISTANT_URL |
str | '' |
Public assistant URL. Its path is the route prefix. |
IMBI_UI_URL |
str | '' |
Public UI URL, no path. Used for deep links. |
IMBI_INTERNAL_UI_URL |
str | '' |
In-cluster UI URL for llms.txt. Unset: IMBI_UI_URL. |
imbi-gateway¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_INTERNAL_API_URL |
HttpUrl | http://localhost:8000/ |
In-cluster origin of imbi-api |
IMBI_API_URL |
str | '' |
Public imbi-api URL with its path prefix, for example https://imbi.example.com/api. The path is the API route prefix. |
IMBI_GATEWAY_API_TOKEN |
str | required | API key of the imbi-gateway service account. Required. |
imbi-mcp¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_INTERNAL_API_URL |
str | http://localhost:8000 |
In-cluster origin of imbi-api (--api-url) |
IMBI_MCP_PUBLIC_URL |
str | none | Public base URL of the host in front of imbi-mcp, without the /mcp path (--public-url). OAuth is on only when this and IMBI_MCP_AUTH_SERVER_URL are both set. |
IMBI_MCP_AUTH_SERVER_URL |
str | none | Imbi OAuth issuer URL, for example https://imbi.example.com (--auth-server-url) |
imbi-scheduler¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_SCHEDULER_SCHEMA |
str | scheduler |
Postgres schema of the task tables |
IMBI_SCHEDULER_API_PREFIX |
str | /api |
Route prefix of the task and run routes |
IMBI_INTERNAL_API_URL |
str | http://localhost:8000 |
In-cluster origin of imbi-api |
IMBI_API_URL |
str | '' |
Public imbi-api URL with its path prefix, for example https://imbi.example.com/api. The path is the API route prefix. |
IMBI_SCHEDULER_GATEWAY_URL |
str | http://localhost:8003 |
imbi-gateway URL for gateway targets |
IMBI_SCHEDULER_SA_SLUG |
str | imbi-scheduler |
Slug of the scheduler service account |
IMBI_SCHEDULER_SA_CLIENT_ID |
str | none | Client ID of the scheduler service account |
IMBI_SCHEDULER_SA_CLIENT_SECRET |
SecretStr | none | Its client secret |
IMBI_SCHEDULER_MAX_CONCURRENT_RUNS |
int | 20 |
Active runs per process |
IMBI_SCHEDULER_CONSECUTIVE_SKIPS_LIMIT |
int | 5 |
Skipped runs in a row before a task is disabled |
IMBI_SCHEDULER_CONSECUTIVE_NO_EFFECT_LIMIT |
int | 5 |
No-effect runs in a row before a warning |
IMBI_SCHEDULER_POLL_INTERVAL |
int | 30 |
Maximum seconds between polls |
imbi-slackbot¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_SLACKBOT_ENABLED |
bool | false |
Turn the bot on. ANTHROPIC_API_KEY and both Slack tokens turn it on too. |
IMBI_SLACKBOT_MODEL |
str | claude-sonnet-4-6 |
Claude model |
IMBI_SLACKBOT_MAX_TOKENS |
int | 16384 |
Maximum response tokens |
IMBI_SLACKBOT_MAX_TOOL_ROUNDS |
int | 10 |
Maximum tool rounds for one message |
IMBI_SLACKBOT_MAX_TOOL_RESULT_CHARS |
int | 200000 |
Longer tool results are replaced with an error |
IMBI_SLACKBOT_MAX_THREAD_MESSAGES |
int | 30 |
Thread messages sent to Claude as context |
IMBI_SLACKBOT_PROGRESS_UPDATES |
bool | true |
Post and update a status message while a request runs |
IMBI_SLACKBOT_STATUS_EMOJI |
str | hourglass_flowing_sand |
Reaction emoji while a request runs |
IMBI_SLACKBOT_IDENTITY_CACHE_TTL |
int | 900 |
Seconds to cache a Slack user to Imbi user match |
IMBI_SLACKBOT_SYSTEM_PROMPT |
str | none | Jinja system prompt that replaces the CMS and packaged prompts |
IMBI_SLACKBOT_PROMPT_REF |
str | imbi-slackbot/system@stable |
Prompt CMS reference of the system prompt |
IMBI_SLACKBOT_API_TOKEN |
str | '' |
API key of the imbi-slackbot service account. Set: the bot uses the token of its AI provider from imbi-api instead of ANTHROPIC_API_KEY. |
SLACK_BOT_TOKEN |
str | '' |
Slack bot token (xoxb-) |
SLACK_APP_TOKEN |
str | '' |
Slack app-level token for Socket Mode (xapp-) |
IMBI_INTERNAL_API_URL |
str | http://localhost:8000 |
In-cluster origin of imbi-api |
IMBI_UI_URL |
str | '' |
Public UI URL, no path. Used for deep links. |
IMBI_INTERNAL_UI_URL |
str | '' |
In-cluster UI URL for llms.txt. Unset: IMBI_UI_URL. |
imbi-workflows¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_INTERNAL_API_URL |
str | http://localhost:8000 |
In-cluster origin of imbi-api |
IMBI_API_URL |
str | '' |
Public imbi-api URL with its path prefix, for example https://imbi.example.com/api. The path is the API route prefix. |
IMBI_WORKFLOWS_SA_CLIENT_ID |
str | none | Client ID of the imbi-workflows service account. Deploy and rollback steps fail without it. |
IMBI_WORKFLOWS_SA_CLIENT_SECRET |
SecretStr | none | Its client secret |
IMBI_WORKFLOWS_WORKERS |
int | 10 |
Runs worked on at the same time |
IMBI_WORKFLOWS_POLL_INTERVAL |
float | 10.0 |
Upper bound in seconds on the sleep between polls. A lost NOTIFY costs latency, not a run. |
IMBI_WORKFLOWS_LEASE_SECONDS |
int | 300 |
How long a claim lasts. One step call must end inside it. |
IMBI_WORKFLOWS_DEPLOY_POLL_SECONDS |
int | 15 |
Seconds between deployment polls |
IMBI_WORKFLOWS_AGENT_POLL_SECONDS |
int | 30 |
Seconds between agent task polls |
IMBI_WORKFLOWS_SCHEDULER_URL |
str | http://localhost:8005/api |
imbi-scheduler's task API, with its route prefix |
IMBI_WORKFLOWS_RECONCILE_INTERVAL |
float | 300.0 |
Seconds between passes of the trigger reconciler. imbi-api also wakes it after each activation and pause. |
imbi-harness (agent runner pods)¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_API_URL |
str | none | Public imbi-api URL with its path prefix, for example https://imbi.example.com/api. The path is the API route prefix. |
POD_NAMESPACE |
str | none | Pod namespace, from the Kubernetes downward API |
IMBI_HARNESS_CLIENT_ID |
str | none | Client ID of the runner service account (egress sync) |
IMBI_HARNESS_CLIENT_SECRET |
str | none | Its client secret |
POD_NAME |
str | none | Pod name, from the Kubernetes downward API |
IMBI_HARNESS_END_OF_CHAIN |
str | '' |
delete_pod or exit at the end of a chain |
IMBI_HARNESS_EGRESS_ENFORCED |
str | '' |
true labels the pod with the egress destinations of each chain and runs the startup self-test |
IMBI_HARNESS_EGRESS_CANARY |
str | '' |
host:port that the startup self-test must not reach. Required when egress is enforced. |
IMBI_HARNESS_POOL |
str | general |
Runner pool name |
HOSTNAME |
str | runner |
Runner instance name |
IMBI_HARNESS_IDLE_EXIT_SECONDS |
str | none | Exit after this many idle seconds. Empty or 0: never. |
IMBI_HARNESS_MODEL |
str | none | Model override for the runner |
IMBI_HARNESS_MCP_URL |
str | none | imbi-mcp URL that agents use |
IMBI_HARNESS_EGRESS_PROXY_URL |
str | none | http://host:port of the egress proxy. Set: the agent CLI, run_with_secret, and git clone use the proxy for HTTPS, and the MCP client uses it for host name destinations. Unset: no proxy. |
POD_UID |
str | none | Pod uid, from the Kubernetes downward API. The runner sends it with each claim; the proxy token holds it. |
IMBI_HARNESS_EXTRA_CA |
str | none | PEM file of extra CA certificates |
Container (entrypoint, Caddy, UI)¶
| Variable | Type | Default | Description |
|---|---|---|---|
IMBI_SERVICE |
str | all |
Service the image runs: all, api, assistant, gateway, mcp, scheduler, slackbot, ui, workflows |
SENTRY_AUTH_TOKEN |
str | none | With SENTRY_ORG and SENTRY_PROJECT, the all and ui modes upload the UI source maps to Sentry at start |
SENTRY_ORG |
str | none | Sentry organization for the upload |
SENTRY_PROJECT |
str | none | Sentry project for the upload |
SENTRY_RELEASE |
str | none | Sentry release for the upload |
SENTRY_URL |
str | none | Sentry server URL for the upload |
IMBI_API_UPSTREAM |
str | 127.0.0.1:8000 |
Caddy upstream of imbi-api (ui mode) |
IMBI_ASSISTANT_UPSTREAM |
str | 127.0.0.1:8002 |
Caddy upstream of imbi-assistant |
IMBI_GATEWAY_UPSTREAM |
str | 127.0.0.1:8003 |
Caddy upstream of imbi-gateway |
IMBI_SCHEDULER_UPSTREAM |
str | 127.0.0.1:8005 |
Caddy upstream of imbi-scheduler |
IMBI_MCP_UPSTREAM |
str | 127.0.0.1:8001 |
Caddy upstream of imbi-mcp |
SERVE_SOURCE_MAPS |
str | none | true serves the UI *.map files. Otherwise Caddy answers 404. |
VITE_API_URL |
str | none | API URL that Caddy writes into index.html at request time. The UI does not start without it. |
VITE_SENTRY_DSN |
str | none | Sentry DSN of the UI, written into index.html |
VITE_DRIFT_STALE_AFTER |
str | none | Drift that waits longer than this (90m, 12h, 3d, 2w) shows red on the Projects page. Empty: never. |
Notes on some settings¶
Public and internal URLs¶
IMBI_API_URL is the URL that a browser uses, with the path that the API is
mounted under. imbi-api mounts its routes under that path. When it is unset,
imbi-api uses http://<IMBI_API_HOST>:<IMBI_API_PORT> with no path. The
/docs and /openapi.json pages are always at the root.
The other services call imbi-api at IMBI_INTERNAL_API_URL, an in-cluster
origin with no path. imbi-gateway, imbi-scheduler, and imbi-workflows add the
path of IMBI_API_URL to it. So set IMBI_API_URL in those services too.
The health check of imbi-api follows the path: with
IMBI_API_URL=https://imbi.example.com/api it is /api/status.
Mailpit auto-configuration¶
When ENVIRONMENT is development (or unset), IMBI_EMAIL_SMTP_HOST is
localhost, and IMBI_EMAIL_SMTP_PORT is 587, imbi-api uses the port in
MAILPIT_SMTP_PORT. It also turns off STARTTLS, unless
IMBI_EMAIL_SMTP_USE_TLS is set. moon run root:services writes
MAILPIT_SMTP_PORT to .env.test.
Sign-in providers¶
Sign-in providers (Google, GitHub, OIDC, AWS) and local login are not
environment variables. You configure them in the database. See
Authentication. The OAuth callback URL is
<IMBI_API_URL>/auth/oauth/<provider-slug>/callback.
OAuth 2.0 authorization server (MCP login)¶
imbi-api is an OAuth 2.0 authorization server, so that MCP clients can sign
a user in with the browser. The flow is the authorization code flow with
PKCE (S256). Clients register themselves with RFC 7591 dynamic client
registration, unless IMBI_AUTH_DCR_ENABLED=false. The discovery document
is at /.well-known/oauth-authorization-server, at the host root. The
endpoints are /auth/authorize, /auth/token, and /auth/register, under
the API path. /auth/authorize uses the usual Imbi sign-in, so MFA and the
provider rules apply.
imbi-mcp turns on OAuth only when IMBI_MCP_PUBLIC_URL and
IMBI_MCP_AUTH_SERVER_URL are both set.
More than one public host¶
A deployment can have more than one host. For example, an internal host serves the UI, and a public host serves the MCP OAuth sign-in for remote clients. Remote MCP clients connect from the cloud of the vendor, so the MCP and OAuth endpoints must be public.
imbi-api makes the discovery URLs, the sign-in redirects, and the IdP
callback URL from the host of each request. It uses the request host only
when it is a trusted origin: the origin of IMBI_API_URL, or an entry in
IMBI_API_CORS_ALLOWED_ORIGINS. For other hosts, it uses IMBI_API_URL.
IMBI_API_FORWARDED_ALLOW_IPS must be set, so that imbi-api trusts the
scheme and host from the proxy.
To add a public sign-in host:
- Add the public origin to
IMBI_API_CORS_ALLOWED_ORIGINS, for examplehttps://imbi-public.example.com. KeepIMBI_API_URLon the internal host. - Route
/mcp,/.well-known/oauth-*, and<api-path>/auth/*on the public host to Imbi.<api-path>is the path ofIMBI_API_URL, for example/api. For browser sign-in on that host, also serve the UI (index.htmlat/and/login, and its static files). - If sign-in uses an IdP, register the callback of the public host with
the IdP:
https://<public-host><api-path>/auth/oauth/<slug>/callback.
Known limit
The flow that connects an extra identity from the account settings page
does not use the request host. It always uses IMBI_API_URL, so its
callback must be registered on that origin.
System prompts¶
imbi-assistant and imbi-slackbot read their system prompt from the prompt CMS
at IMBI_ASSISTANT_PROMPT_REF and IMBI_SLACKBOT_PROMPT_REF. If the CMS does
not supply the prompt, they use the packaged prompt. imbi-api setup-prompts
seeds the defaults. IMBI_ASSISTANT_SYSTEM_PROMPT and
IMBI_SLACKBOT_SYSTEM_PROMPT replace both. See Prompts.
Prompt rendering¶
imbi-api, imbi-assistant, imbi-slackbot, and imbi-workflows render prompt
templates in worker processes, so that a template cannot stop the service.
IMBI_PROMPT_* sets the pool of each service process.
Other per-service references¶
- imbi-scheduler: Scheduler configuration.
- imbi-workflows: Workflows.
- Secrets broker (
IMBI_SECRETS_*): Secrets. - Plugins (
IMBI_PLUGINS*): Plugins. - Agent runner pods (
IMBI_HARNESS_*): Agent runners.
Tracing and metrics (OTEL_*)¶
The images install the OpenTelemetry distro and the FastAPI, httpx, MCP,
psycopg, and redis instrumentations. When OTEL_TRACES_EXPORTER or
OTEL_METRICS_EXPORTER is set and is not none, the container entrypoint
starts each Python service under opentelemetry-instrument. The standard
OTEL_* variables configure the SDK. A signal that is not set is not
exported: the entrypoint sets it to none.
| Variable | Value |
|---|---|
OTEL_TRACES_EXPORTER |
otlp |
OTEL_EXPORTER_OTLP_PROTOCOL |
http/protobuf |
OTEL_EXPORTER_OTLP_ENDPOINT |
The collector, for example http://collector:4318 |
OTEL_METRICS_EXPORTER |
prometheus to serve /metrics for scraping, or unset |
OTEL_EXPORTER_PROMETHEUS_PORT |
Optional. The /metrics port, default 9464 |
OTEL_EXPORTER_PROMETHEUS_HOST |
Optional. The /metrics bind address, default 0.0.0.0 |
OTEL_SERVICE_NAME |
Optional. Defaults to the service command, for example imbi-mcp |
Set OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
The images include only the OTLP/HTTP exporter. Without a protocol,
otlp selects the gRPC exporter, which is not installed, and the
service does not send traces.
With OTEL_METRICS_EXPORTER=prometheus, each service serves its HTTP server
and client metrics on :<OTEL_EXPORTER_PROMETHEUS_PORT>/metrics (default
:9464/metrics). Use it with one service per
container: in all mode every service tries to bind the same port.
Development stack¶
moon run root:services starts the backing services in compose.ci.yaml
on random host ports. Then it writes the ports, and a JWT secret and an
encryption key, to .env.test. Load that file when you run a service:
| Service | Container ports | Purpose |
|---|---|---|
postgres |
5432 | PostgreSQL with Apache AGE, pg_cron, and pgvector |
clickhouse |
8123 | Analytics, operations log, audit |
valkey |
6379 | Cache |
iggy |
3000, 8090, 8092 | Apache Iggy message streams (8090 is TCP) |
iggy-config-server |
8080 | Serves the sink configuration to iggy-connect, in place of imbi-api |
iggy-connect |
8081 | Iggy connectors runtime with the ClickHouse sink. In the connect profile: moon run root:services starts it after it creates the topics |
ministack |
4566 | S3-compatible storage |
mailpit |
1025 (SMTP), 8025 (web UI) | SMTP capture |
jaeger |
4318 (OTLP/HTTP), 16686 (UI) | Tracing |
To find a host port, run
docker compose -f compose.ci.yaml port <service> <container-port>, or read
.env.test.
IMBI_RELOAD_DIRS adds directories that serve --dev watches for changes.