Frona is configured through environment variables. All variables use the FRONA_ prefix and are organized by component.
General
| Variable | Default | Description |
|---|---|---|
FRONA_SERVER_DATA_DIR | data | Base data directory. Defaults for FRONA_CONFIG, database.path, storage.workspaces_path, and storage.files_path are derived from this path |
FRONA_CONFIG | {data_dir}/config.yaml | Path to the YAML config file |
FRONA_LOG_LEVEL | -- | Log verbosity level |
FRONA_LOG_CONFIG | -- | Path to a custom log configuration file |
Server
| Variable | Default | Description |
|---|---|---|
FRONA_SERVER_PORT | 3001 | Port the backend API listens on |
FRONA_SERVER_BASE_URL | -- | Public base URL of the server (used for callbacks) |
FRONA_SERVER_MAX_BODY_SIZE_BYTES | 104857600 (100 MB) | Maximum request body size |
FRONA_SERVER_CORS_ORIGINS | -- | Comma-separated list of allowed CORS origins |
FRONA_SERVER_MAX_CONCURRENT_TASKS | 10 | Maximum concurrent tasks across all agents |
FRONA_SERVER_BACKEND_URL | -- | Override backend API URL |
FRONA_SERVER_FRONTEND_URL | -- | Override frontend URL |
FRONA_SERVER_EXTERNAL_URL | -- | Externally-reachable URL of the server (e.g., ngrok tunnel, public domain). Used as the default callback target for inbound webhooks (Twilio, Telegram, etc.) when no per-feature override is set |
FRONA_SERVER_ISSUER_URL | -- | JWT token issuer URL |
FRONA_SERVER_SSE_PENDING_EVENTS_SECS | 60 | How long to buffer SSE events after client disconnects |
FRONA_SERVER_SHUTDOWN_TIMEOUT_SECS | 60 | Graceful shutdown timeout |
FRONA_SERVER_TIMEZONE | auto-detect | Server-default IANA timezone (e.g. America/Los_Angeles). Used for cron, reminders, and the <temporal_context> block when a user has no profile timezone set. Empty auto-detects from TZ, then /etc/localtime, falling back to UTC. |
Sandbox
| Variable | Default | Description |
|---|---|---|
FRONA_SANDBOX_DISABLED | false | Disable filesystem sandboxing. Not recommended for production. |
FRONA_SANDBOX_MAX_CPU_PCT | 95.0 | Per-principal CPU usage limit (% of total system CPU). |
FRONA_SANDBOX_MAX_MEMORY_PCT | 80.0 | Per-principal memory usage limit (% of total system memory). |
FRONA_SANDBOX_TIMEOUT_SECS | 0 | Default sandbox execution timeout (0 = no timeout). |
FRONA_SANDBOX_MAX_TOTAL_CPU_PCT | 98.0 | Global CPU cap across all sandboxed processes. |
FRONA_SANDBOX_MAX_TOTAL_MEMORY_PCT | 90.0 | Global memory cap across all sandboxed processes. |
FRONA_SANDBOX_DEFAULT_NETWORK_ACCESS | true | Grant sandbox principals outbound network access by default. Override with forbid policies. |
Authentication
| Variable | Default | Description |
|---|---|---|
FRONA_AUTH_ENCRYPTION_SECRET | -- | Secret used to derive the AES-256 key that encrypts JWT signing keypairs at rest. Must be changed in production. |
FRONA_AUTH_ACCESS_TOKEN_EXPIRY_SECS | 900 (15 min) | Access token lifetime |
FRONA_AUTH_REFRESH_TOKEN_EXPIRY_SECS | 604800 (7 days) | Refresh token lifetime |
FRONA_AUTH_PRESIGN_EXPIRY_SECS | 86400 (24 hours) | Pre-signed URL lifetime |
FRONA_AUTH_EPHEMERAL_TOKEN_EXPIRY_SECS | 300 (5 min) | Ephemeral principal token lifetime injected into sandboxed processes. |
FRONA_AUTH_RUNTIME_TOKENS_DIR | data/runtime/tokens | Directory for per-invocation ephemeral token files (created with mode 0700 at startup). |
FRONA_AUTH_ALLOW_REGISTRATION | true | Allow anyone to sign up from the Register page. Set to false on shared installs so only admins can create accounts. See Managing Users. |
:::caution[Change the encryption secret in production] FRONA_AUTH_ENCRYPTION_SECRET is used to derive an AES-256 encryption key (via SHA-256) that protects the JWT signing keypairs stored in the database. It is not used directly for JWT signing; instead it encrypts the private keys that do the signing.
A built-in default is provided for local development, but you must set your own value in production. If the default is left in place and database files are ever exposed (backup leak, file traversal, shared host), an attacker could decrypt the signing keypairs and forge authentication tokens for any user.
Generate a strong random secret:
openssl rand -base64 32:::
SSO (OpenID Connect)
| Variable | Default | Description |
|---|---|---|
FRONA_SSO_ENABLED | false | Enable OIDC authentication |
FRONA_SSO_AUTHORITY | -- | OpenID Connect authority URL |
FRONA_SSO_CLIENT_ID | -- | OIDC client ID |
FRONA_SSO_CLIENT_SECRET | -- | OIDC client secret |
FRONA_SSO_SCOPES | openid email | OpenID scopes to request |
FRONA_SSO_DISABLE_LOCAL_AUTH | false | Force SSO-only authentication, disables local login |
FRONA_SSO_SIGNUPS_MATCH_EMAIL | true | Match SSO signups to existing accounts by email |
FRONA_SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION | true | Accept unverified emails from the IdP |
FRONA_SSO_CLIENT_CACHE_EXPIRATION | 0 | Client metadata cache expiration in seconds |
Database
| Variable | Default | Description |
|---|---|---|
FRONA_DATABASE_PATH | data/db | Path to the SurrealDB data directory |
Browser
| Variable | Default | Description |
|---|---|---|
FRONA_BROWSER_WS_URL | -- | WebSocket URL of the Browserless instance |
FRONA_BROWSER_PROFILES_PATH | /profiles | Path for storing browser profiles |
FRONA_BROWSER_CONNECTION_TIMEOUT_MS | 30000 | Timeout for connecting to the browser |
FRONA_BROWSER_API_TOKEN | -- | Authentication token for the Browserless HTTP API |
Search
| Variable | Default | Description |
|---|---|---|
FRONA_SEARCH_PROVIDER | -- | Search provider: searxng, tavily, or brave |
FRONA_SEARCH_SEARXNG_BASE_URL | -- | Base URL of the SearXNG instance |
Vault
| Variable | Default | Description |
|---|---|---|
FRONA_VAULT_ONEPASSWORD_SERVICE_ACCOUNT_TOKEN | -- | 1Password service account token |
FRONA_VAULT_ONEPASSWORD_VAULT_ID | -- | 1Password default vault ID |
FRONA_VAULT_BITWARDEN_CLIENT_ID | -- | Bitwarden personal API key client ID |
FRONA_VAULT_BITWARDEN_CLIENT_SECRET | -- | Bitwarden personal API key client secret |
FRONA_VAULT_BITWARDEN_MASTER_PASSWORD | -- | Bitwarden master password |
FRONA_VAULT_BITWARDEN_SERVER_URL | -- | Bitwarden server URL (for self-hosted instances) |
FRONA_VAULT_HASHICORP_ADDRESS | -- | HashiCorp Vault server address |
FRONA_VAULT_HASHICORP_TOKEN | -- | HashiCorp Vault auth token |
FRONA_VAULT_HASHICORP_MOUNT | -- | HashiCorp Vault KV2 mount path (default: secret) |
FRONA_VAULT_KEEPASS_PATH | -- | Path to KeePass .kdbx file |
FRONA_VAULT_KEEPASS_PASSWORD | -- | KeePass master password |
Storage
| Variable | Default | Description |
|---|---|---|
FRONA_STORAGE_WORKSPACES_PATH | data/workspaces | Path for workspace file storage |
FRONA_STORAGE_FILES_PATH | data/files | Path for file uploads |
FRONA_STORAGE_SHARED_CONFIG_DIR | resources | Path for shared prompts and agent configs |
FRONA_STORAGE_SKILLS_DIR | data/skills | Path for installed shared skills |
FRONA_STORAGE_CACHE_DIR | data/system/cache | Path for system caches |
FRONA_STORAGE_CHANNELS_DATA_PATH | data/channels | Directory for per-channel adapter data (Signal/WhatsApp sessions, etc.) |
Scheduler
| Variable | Default | Description |
|---|---|---|
FRONA_SCHEDULER_POLL_SECS | 60 | How often the scheduler checks for due tasks |
FRONA_SCHEDULER_SPACE_COMPACTION_SECS | 3600 (1 hour) | Interval for space context compaction |
FRONA_SCHEDULER_MEMORY_COMPACTION_SECS | 7200 (2 hours) | Interval for memory compaction |
Inference
| Variable | Default | Description |
|---|---|---|
FRONA_INFERENCE_MAX_TOOL_TURNS | 200 | Maximum tool call iterations per response |
FRONA_INFERENCE_DEFAULT_MAX_TOKENS | 8192 | Default max tokens for LLM responses |
FRONA_INFERENCE_COMPACTION_TRIGGER_PCT | 80 | Context usage percentage that triggers compaction |
FRONA_INFERENCE_HISTORY_TRUNCATION_PCT | 90 | Context usage percentage that triggers truncation |
Voice (Twilio)
| Variable | Default | Description |
|---|---|---|
FRONA_VOICE_PROVIDER | -- | Voice provider. Currently only twilio is supported |
FRONA_VOICE_TWILIO_ACCOUNT_SID | -- | Twilio account SID |
FRONA_VOICE_TWILIO_AUTH_TOKEN | -- | Twilio auth token |
FRONA_VOICE_TWILIO_FROM_NUMBER | -- | Twilio phone number for outbound calls (E.164 format) |
FRONA_VOICE_TWILIO_VOICE_ID | -- | Twilio voice ID for text-to-speech |
FRONA_VOICE_TWILIO_SPEECH_MODEL | -- | Twilio speech recognition model |
Twilio webhook callbacks now use FRONA_SERVER_EXTERNAL_URL instead of the old FRONA_VOICE_CALLBACK_BASE_URL.
LLM Providers
Frona supports 17 LLM providers. Set the API key for any provider you want to use. Providers are auto-discovered from environment variables on startup. At least one is required.
| Variable | Provider |
|---|---|
ANTHROPIC_API_KEY | Anthropic (Claude) |
OPENAI_API_KEY | OpenAI (GPT) |
GROQ_API_KEY | Groq |
OPENROUTER_API_KEY | OpenRouter |
DEEPSEEK_API_KEY | DeepSeek |
GEMINI_API_KEY | Google Gemini |
COHERE_API_KEY | Cohere |
MISTRAL_API_KEY | Mistral |
PERPLEXITY_API_KEY | Perplexity |
TOGETHER_API_KEY | Together AI |
XAI_API_KEY | xAI (Grok) |
HYPERBOLIC_API_KEY | Hyperbolic |
MOONSHOT_API_KEY | Moonshot |
MIRA_API_KEY | Mira |
GALADRIEL_API_KEY | Galadriel |
HUGGINGFACE_API_KEY | Hugging Face |
OLLAMA_API_BASE_URL | Ollama (self-hosted, no API key needed) |
You can also configure providers via the config file or the setup wizard.
Apps
| Variable | Default | Description |
|---|---|---|
FRONA_APP_PORT_RANGE_START | 4000 | Start of the port range for app allocation |
FRONA_APP_PORT_RANGE_END | 4100 | End of the port range for app allocation |
FRONA_APP_HEALTH_CHECK_TIMEOUT_SECS | 30 | Maximum time to wait for an app to become healthy |
FRONA_APP_MAX_RESTART_ATTEMPTS | 2 | Restart attempts before marking a crashed app as failed |
FRONA_APP_HIBERNATE_AFTER_SECS | 259200 (3 days) | Inactivity duration before auto-hibernating an app |
Cache
| Variable | Default | Description |
|---|---|---|
FRONA_CACHE_ENTITY_TTL_SECS | 300 (5 min) | Time-to-live for cached entities |
FRONA_CACHE_ENTITY_MAX_CAPACITY | 1000 | Maximum number of cached entities |
Channel
Default retry policy for channel connections. Per-channel overrides on the channel detail page take precedence.
| Variable | Default | Description |
|---|---|---|
FRONA_CHANNEL_RETRY_MAX_RETRIES | unlimited | Total retry attempts before a channel is marked Failed. |
FRONA_CHANNEL_RETRY_INITIAL_BACKOFF_MS | 1000 (1s) | Delay before the first retry. |
FRONA_CHANNEL_RETRY_BACKOFF_MULTIPLIER | 2.0 | Delay multiplier between attempts. |
FRONA_CHANNEL_RETRY_MAX_BACKOFF_MS | 60000 (60s) | Cap on the delay between attempts. |
Signal
Safety caps for the signal matcher.
| Variable | Default | Description |
|---|---|---|
FRONA_SIGNAL_MAX_PENDING_PER_USER | 100 | Maximum number of pending signal watches per user. |
FRONA_SIGNAL_DEFAULT_MAX_EVALUATIONS | 100 | Default cap on candidates a one-shot watch can be evaluated against. |
FRONA_SIGNAL_DEFAULT_MAX_CONTINUOUS_EVALUATIONS | 10000 | Default cap on fires a continuous-mode watch can absorb. |
MCP
| Variable | Default | Description |
|---|---|---|
FRONA_MCP_ENABLED | true | Enable MCP server support. |
FRONA_MCP_WORKSPACES_PATH | data/mcp | Base path for per-MCP-server workspace directories. |
FRONA_MCP_CACHE_PATH | {workspaces_path}/cache | Shared package cache directory (npm, uv). |
FRONA_MCP_MAX_SERVERS_PER_USER | 32 | Maximum MCP servers per user. |
FRONA_MCP_STARTUP_TIMEOUT_SECS | 30 | Seconds to wait for the initialize handshake. |
FRONA_MCP_HEALTH_CHECK_INTERVAL_SECS | 10 | Interval between liveness checks. |
FRONA_MCP_MAX_RESTART_ATTEMPTS | 3 | Restart attempts before marking a server as failed. |
FRONA_MCP_DEFAULT_TRANSPORT | stdio | Default transport for new MCP servers: stdio or http. |
FRONA_MCP_PORT_RANGE_START | 4100 | Start of port range for local HTTP MCP servers. |
FRONA_MCP_PORT_RANGE_END | 4200 | End of port range (exclusive). |
FRONA_MCP_BRIDGE_MODE | true | Expose MCP tools via the mcpctl CLI bridge. See Bridge mode. |
Model groups
Model groups cannot be set via environment variables. They must be configured in the config file. Each group defines a provider, model, fallbacks, and provider-specific parameters like thinking budgets and sampling settings.