Frona is configured through a YAML config file at {FRONA_SERVER_DATA_DIR}/config.yaml, which defaults to data/config.yaml. You can change the path by setting the FRONA_CONFIG environment variable.
Environment variables override YAML fields and built-in defaults. They are documented separately in the Environment Variables reference, including the double-underscore syntax for nested fields.
Use ${ENV_VAR} to reference a variable available to the Frona process. Ordinary YAML references expand at startup; a missing variable expands to an empty string, which can leave an invalid value. Shell expressions such as ${NAME:-default} are not supported. Provider api_key references are preserved for runtime credential resolution. Inside model extra_params, strings are literal data: ${ENV_VAR} is sent unchanged.
The administration UI saves only changed settings. Unrelated explicit overrides and ${ENV_VAR} references are preserved, and inherited environment values are not copied into YAML. Values equal to their defaults are omitted; partial blocks are valid. Inline reset controls remove an override so the setting can inherit its default again.
Saving settings writes the configuration for the next startup. Follow the restart banner to activate it. If the file changes after you open settings, Frona rejects a stale save: reload the settings before trying again. Invalid or unreadable configuration now fails startup with an error instead of silently using defaults.
Server
General server settings. This example serves the frontend and API from one public origin. Leave backend_url and frontend_url unset for this layout. For separate origins, set them to the respective public URLs; backend_url takes precedence over base_url for SSO callbacks, and frontend_url takes precedence for frontend links.
server:
port: 3001
base_url: https://frona.example.com
external_url: https://frona.example.com
static_dir: /app/static
issuer_url: https://frona.example.com
max_concurrent_tasks: 10
sse_pending_events_secs: 60
cors_origins: https://app.example.com
max_body_size_bytes: 104857600
shutdown_timeout_secs: 60
timezone: America/Los_Angeles| Field | Type | Default | Description |
|---|---|---|---|
port | integer | 3001 | HTTP server port |
base_url | string | -- | Public-facing base URL, used for callbacks and links |
backend_url | string | -- | Public backend API URL; overrides base_url, including for SSO callbacks |
frontend_url | string | -- | Public frontend URL; overrides base_url for frontend links |
external_url | string | -- | Externally-reachable URL of the server (e.g., ngrok tunnel, public domain). Default callback target for inbound webhooks (Twilio, Telegram, etc.). Falls back to backend_url then base_url if unset. |
static_dir | string | /app/static | Directory serving the frontend static files |
issuer_url | string | -- | JWT token issuer URL |
max_concurrent_tasks | integer | 10 | Maximum concurrent background tasks across all agents |
sse_pending_events_secs | integer | 60 | How long to buffer SSE events after client disconnects |
cors_origins | string | -- | Allowed CORS origins |
max_body_size_bytes | integer | 104857600 (100 MB) | Maximum HTTP request body size |
shutdown_timeout_secs | integer | 60 | Graceful shutdown timeout |
timezone | string | auto-detect | Server-default IANA timezone used for cron scheduling, reminders, and the <temporal_context> block when a user has no profile timezone and no per-task override. Leave empty to auto-detect from the TZ env var, then /etc/localtime, falling back to UTC. |
Sandbox
Per-process resource limits and global caps for the CLI/Python/Node.js sandboxes. See Sandbox for the security model.
sandbox:
disabled: false
max_cpu_pct: 95.0
max_memory_pct: 80.0
timeout_secs: 0
max_total_cpu_pct: 98.0
max_total_memory_pct: 90.0
default_network_access: true| Field | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Disable filesystem sandboxing. Not recommended for production. Linux uses Syd when available, with Landlock as a fallback; macOS uses sandbox-exec. |
max_cpu_pct | float | 95.0 | Per-principal CPU usage limit as percentage of total system CPU. Sandboxed processes that exceed this are killed. |
max_memory_pct | float | 80.0 | Per-principal memory usage limit as percentage of total system memory. |
timeout_secs | integer | 0 | Default sandbox execution timeout in seconds. 0 means no timeout. |
max_total_cpu_pct | float | 98.0 | Global CPU cap across all sandboxed processes. |
max_total_memory_pct | float | 90.0 | Global memory cap across all sandboxed processes. |
default_network_access | boolean | true | Grant all sandbox principals outbound network access by default. Override with forbid policies. |
Auth
Authentication and token settings.
auth:
encryption_secret: change-this-in-production
access_token_expiry_secs: 900
refresh_token_expiry_secs: 604800
presign_expiry_secs: 86400
ephemeral_token_expiry_secs: 300
allow_registration: true| Field | Type | Default | Description |
|---|---|---|---|
encryption_secret | string | dev-secret-change-in-production | Secret used to derive the AES-256 key protecting signing keypairs, vault configurations, local credentials, and managed provider keys and account tokens. Must be changed in production. |
access_token_expiry_secs | integer | 900 (15 min) | How long access tokens are valid |
refresh_token_expiry_secs | integer | 604800 (7 days) | How long refresh tokens are valid |
presign_expiry_secs | integer | 86400 (24 hours) | How long pre-signed URLs are valid |
ephemeral_token_expiry_secs | integer | 300 (5 min) | Lifetime of stateless ephemeral principal tokens injected into sandboxed processes |
allow_registration | boolean | 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. |
Change the encryption secret in production
encryption_secret is used to derive an AES-256 encryption key (via SHA-256) that protects JWT signing keypairs, vault provider configurations, local credential values, and managed credential payloads, including provider keys and account tokens. 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.
Managed credentials are included in automatic encryption-key rotation. Back up the encryption secret together with the database and configuration; see Backups.
Generate a strong random secret:
openssl rand -base64 32SSO
OpenID Connect single sign-on. Disabled by default.
sso:
enabled: true
authority: https://auth.example.com
client_id: your-client-id
client_secret: your-client-secret
scopes: openid email
disable_local_auth: false
signups_match_email: true
allow_unknown_email_verification: true| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable OIDC authentication |
authority | string | -- | OpenID Connect authority URL |
client_id | string | -- | OAuth client ID |
client_secret | string | -- | OAuth client secret |
scopes | string | openid email | OpenID scopes to request |
disable_local_auth | boolean | false | Force SSO-only authentication. Disables local login |
signups_match_email | boolean | true | Match SSO signups to existing accounts by email |
allow_unknown_email_verification | boolean | true | Accept emails not verified by the identity provider |
client_cache_expiration | integer | 0 | Accepted but unused in v2026.10.0; changing it has no effect on client metadata caching |
Database
database:
path: data/db| Field | Type | Default | Description |
|---|---|---|---|
path | string | {FRONA_SERVER_DATA_DIR}/db | Path to the SurrealDB data directory; defaults to data/db |
Browser
Headless Chrome configuration for browser automation. Optional. If not configured, browser tools are unavailable.
browser:
ws_url: ws://browserless:3333
profiles_path: /profiles
connection_timeout_ms: 30000
api_token: your-browserless-token| Field | Type | Default | Description |
|---|---|---|---|
ws_url | string | -- | WebSocket URL of the Browserless instance |
profiles_path | string | /profiles | Directory for storing browser profiles |
connection_timeout_ms | integer | 30000 (30s) | Timeout for connecting to the browser service |
api_token | string | frona fallback | Authentication token for the Browserless HTTP management API |
Search
Web search provider configuration. If search.provider is unset, Frona selects the first configured option in this order: TAVILY_API_KEY, BRAVE_API_KEY, then search.searxng_base_url (which can also be set through FRONA_SEARCH_SEARXNG_BASE_URL). If none is configured, web search is unavailable.
An explicit provider selection requires its matching key or URL. Frona does not fall back to another provider when that value is missing. Tavily and Brave read their keys from the server environment; see Search environment variables for credential names and container forwarding.
search:
provider: searxng
searxng_base_url: http://searxng:8080| Field | Type | Default | Description |
|---|---|---|---|
provider | string | -- | Search provider: searxng, tavily, or brave |
searxng_base_url | string | -- | Base URL of the SearXNG instance |
Vault
External vault provider configuration. Credentials set here create system-managed vault connections that sync automatically on startup. See Vault Providers for details.
vault:
onepassword_service_account_token: ops_...
onepassword_vault_id: abc123
bitwarden_client_id: user.xxx
bitwarden_client_secret: xxx
bitwarden_master_password: xxx
bitwarden_server_url: https://vault.example.com
hashicorp_address: http://localhost:8200
hashicorp_token: hvs.xxx
hashicorp_mount: secret
keepass_path: /path/to/vault.kdbx
keepass_password: xxx| Field | Type | Default | Description |
|---|---|---|---|
onepassword_service_account_token | string | -- | 1Password service account token |
onepassword_vault_id | string | -- | 1Password default vault ID |
bitwarden_client_id | string | -- | Bitwarden personal API key client ID |
bitwarden_client_secret | string | -- | Bitwarden personal API key client secret |
bitwarden_master_password | string | -- | Bitwarden master password |
bitwarden_server_url | string | -- | Bitwarden server URL (for self-hosted) |
hashicorp_address | string | -- | HashiCorp Vault server address |
hashicorp_token | string | -- | HashiCorp Vault auth token |
hashicorp_mount | string | secret | HashiCorp Vault KV2 mount path |
keepass_path | string | -- | Path to KeePass .kdbx file |
keepass_password | string | -- | KeePass master password |
Storage
File storage paths. As of v2026.5.5 all per-user state lives under a single root, {data_dir}/users/{user_handle}/{subsystem}/.... See Workspaces for the layout.
storage:
data_dir: data
shared_config_dir: resources
skills_dir: data/skills
cache_dir: data/system/cache
ontology_dir: data/ontology| Field | Type | Default | Description |
|---|---|---|---|
data_dir | string | data | Root data directory. Per-user state lives at {data_dir}/users/{user_handle}/... (workspaces, uploaded files, MCP server data, channel sessions, vault, tokens). Browser profiles are kept separately on the browserless container's volume (browser.profiles_path). |
shared_config_dir | string | resources | Read-only shared prompts and agent configurations that ship with the binary |
skills_dir | string | data/skills | Directory for installed shared skills |
cache_dir | string | data/system/cache | Directory for system caches (skill registry, etc.) |
ontology_dir | string | data/ontology | Directory for user-supplied ontologies, loaded alongside bundled ontologies |
The defaults above assume FRONA_SERVER_DATA_DIR=data. Changing that environment variable changes the default config-file, database, storage, skills, cache, and ontology paths. Setting only storage.data_dir does not relocate the other paths; configure them separately when needed. See Environment Variables → Storage.
Scheduler
Background job intervals.
scheduler:
poll_secs: 60| Field | Type | Default | Description |
|---|---|---|---|
poll_secs | integer | 60 (1 min) | How often the scheduler checks for due tasks |
Memory
Select the memory backend and configure background memory work. Existing installations default to basic until PKM is explicitly enabled; fresh installations choose a backend during setup. See Personal Knowledge Management for the PKM architecture and user experience.
memory:
backend: pkm
model_group: memory
basic_compaction_token_threshold: 3000
basic_compaction_secs: 7200
basic_space_compaction_secs: 3600
pkm_search_top_k: 8
pkm_short_memory_half_life_secs: 1209600
pkm_short_memory_demote_threshold: 0.1
pkm_short_memory_top_n: 16
pkm_short_memory_token_cap: 3000
pkm_playbook_index_token_cap: 1500
pkm_consolidate_secs: 60
pkm_consolidate_idle_secs: 300
pkm_consolidation_concurrency: 4
pkm_consolidation_max_tool_turns: 8
pkm_consolidation_max_submissions: 8
pkm_playbook_max_tool_turns: 20
pkm_playbook_max_submissions: 20
pkm_extract_max_tokens: 10000
pkm_extract_max_messages: 300
pkm_extract_agent_evidence_lookback_messages: 10
pkm_extract_agent_evidence_result_token_cap: 4000
pkm_consolidation_max_attempts: 3
pkm_adjudication_max_attempts_per_batch: 40
pkm_consolidation_checkpoint_failure_cap: 2
pkm_consolidation_retry_base_secs: 120
pkm_consolidation_keep_records: 20General and basic memory
| Field | Type | Default | Description |
|---|---|---|---|
backend | string | basic for upgrades | Memory backend: basic or pkm |
model_group | string | memory | Model group for background memory work. When undefined, basic compaction uses the chat agent model and PKM consolidation uses primary |
basic_compaction_token_threshold | integer | 3000 | Skip basic user/agent memory compaction below this token count |
basic_compaction_secs | integer | 7200 | Interval between basic user/agent memory compaction runs |
basic_space_compaction_secs | integer | 3600 | Interval between basic space-memory compaction runs |
PKM retrieval and short memory
| Field | Type | Default | Description |
|---|---|---|---|
pkm_search_top_k | integer | 8 | Maximum results returned by memory_search |
pkm_short_memory_half_life_secs | integer | 1209600 (14 days) | Recency-decay half-life for short memories |
pkm_short_memory_demote_threshold | float | 0.1 | Drop a short memory from prompt injection when its decay score falls below this value |
pkm_short_memory_top_n | integer | 16 | Maximum short-memory lines injected into a prompt |
pkm_short_memory_token_cap | integer | 3000 | Token budget for the short-memory prompt block |
pkm_playbook_index_token_cap | integer | 1500 | Token budget for the available-playbooks index |
PKM consolidation
| Field | Type | Default | Description |
|---|---|---|---|
pkm_consolidate_secs | integer | 60 | How often the sweep scans for eligible chats |
pkm_consolidate_idle_secs | integer | 300 | How long a chat must be idle before consolidation |
pkm_consolidation_concurrency | integer | 4 | Maximum parallel extraction or page-authoring model calls |
pkm_consolidation_max_tool_turns | integer | 8 | Exploration-tool turns allowed for classify and resolve |
pkm_consolidation_max_submissions | integer | 8 | Structured submissions allowed for classify, resolve, and reconcile |
pkm_playbook_max_tool_turns | integer | 20 | Exploration-tool turns allowed for playbook resolution and authoring |
pkm_playbook_max_submissions | integer | 20 | Structured submissions allowed for playbook resolution and authoring |
pkm_extract_max_tokens | integer | 10000 | Maximum estimated transcript tokens in one extraction request |
pkm_extract_max_messages | integer | 300 | Maximum messages consumed by one extraction request |
pkm_extract_agent_evidence_lookback_messages | integer | 10 | Same-chat agent messages searched backward for qualified tool evidence |
pkm_extract_agent_evidence_result_token_cap | integer | 4000 | Token cap for each scoped evidence search or read |
pkm_consolidation_max_attempts | integer | 3 | Failures allowed at the current stage before abandoning a pass |
pkm_adjudication_max_attempts_per_batch | integer | 40 | Submission attempts allowed for each ontology-adjudication batch |
pkm_consolidation_checkpoint_failure_cap | integer | 2 | Fatal post-extraction checkpoint resets allowed before terminal failure |
pkm_consolidation_retry_base_secs | integer | 120 | Base retry delay; doubles per attempt and is quantized by the sweep cadence |
pkm_consolidation_keep_records | integer | 20 | Finished consolidation records retained per user |
Inference
LLM inference settings.
inference:
max_tool_turns: 200
default_max_tokens: 8192
compaction_trigger_pct: 80
history_truncation_pct: 90| Field | Type | Default | Description |
|---|---|---|---|
max_tool_turns | integer | 200 | Maximum tool call iterations per agent response |
default_max_tokens | integer | 8192 | Output-token reservation for context budgeting when the model has no explicit output limit; set model-group max_tokens to impose a generation limit |
compaction_trigger_pct | integer | 80 | Accepted but currently unused by the chat compactor |
history_truncation_pct | integer | 90 | Percentage of the history budget usable after reserving output tokens and system-prompt space |
In v2026.10.0, the chat compactor uses a fixed threshold of 80% of the context window remaining after the output-token reservation. Changing compaction_trigger_pct does not affect it. default_max_tokens is not a universal generation cap for explicitly configured model groups; use the group's max_tokens setting for an output limit.
Voice
Twilio voice call configuration. Optional. If not configured, voice tools are unavailable.
voice:
provider: twilio
twilio_account_sid: your-account-sid
twilio_auth_token: your-auth-token
twilio_from_number: "+15551234567"
twilio_voice_id: Polly.Matthew
twilio_speech_model: enhanced| Field | Type | Default | Description |
|---|---|---|---|
provider | string | -- | Voice provider. Currently only twilio is supported |
twilio_account_sid | string | -- | Twilio account SID |
twilio_auth_token | string | -- | Twilio auth token |
twilio_from_number | string | -- | Twilio phone number for outbound calls (E.164 format) |
twilio_voice_id | string | -- | Twilio voice ID for text-to-speech |
twilio_speech_model | string | -- | Twilio speech recognition model |
Twilio webhook callbacks use server.external_url (falling back to backend_url/base_url). The old voice.callback_base_url field has been removed; set server.external_url instead.
Providers
Providers are named connections. The map key is the connection handle used by model groups; provider identifies the brand. This lets you configure multiple accounts or endpoints for the same provider. For the administration UI and account sign-in steps, see Providers & Models.
providers:
openai-work:
provider: openai
api_key: ${WORK_OPENAI_API_KEY}
openai-personal:
provider: openai
api_key: ${PERSONAL_OPENAI_API_KEY}
anthropic:
api_key: ${ANTHROPIC_API_KEY}
ollama:
base_url: http://localhost:11434Handles must contain 2–32 characters, start with a letter, and use lowercase letters, digits, hyphens, or underscores. Existing entries such as providers.openai remain valid: when provider is omitted, Frona infers the brand from the handle. Legacy handles gemini, together, and moonshot map to google, togetherai, and moonshotai respectively.
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | inferred from handle | Provider brand, such as openai, azure, or amazon-bedrock |
adapter | string | inferred for built-in brands | Request adapter for a custom brand: openai, anthropic, gemini, bedrock, cohere, ollama, or huggingface |
api_key | string | -- | Inline key or ${ENV_VAR} reference; environment references are resolved when credentials are needed |
credential_id | UUID string | -- | ID of an authorized managed credential, normally selected through Saved credential in the UI |
base_url | string | provider default | Custom API endpoint; required for Azure and most custom brands |
enabled | boolean | true | Whether this connection is active |
aws_region | string | AWS configuration | Bedrock region |
aws_profile | string | AWS credential chain | Named AWS profile for Bedrock |
azure_api_version | string | 2024-10-21 | Azure OpenAI API version |
A credential_id cannot be combined with api_key, aws_profile, or azure_credential. The current Azure adapter supports API-key authentication; azure_credential is not supported. Credentials entered or obtained through the provider UI are stored encrypted in the database and referenced by ID. Inline YAML secrets remain in the config file.
Built-in brands include openai, anthropic, azure, amazon-bedrock, github-copilot, kimi-for-coding, google, groq, openrouter, deepseek, cohere, mistral, perplexity, togetherai, xai, hyperbolic, moonshotai, mira, galadriel, huggingface, and ollama. The UI also lists compatible brands from the provider catalogue. A catalogue entry cannot enable a protocol or authentication method that Frona's adapter does not implement.
For a custom OpenAI-compatible endpoint:
providers:
internal-llm:
provider: internal
adapter: openai
base_url: https://llm.example.com/v1
api_key: ${INTERNAL_LLM_API_KEY}
models:
primary:
provider: internal-llm
model: your-model-id
api: completionsAutomatic discovery adds connections from standard environment variables when their handles are not already configured. A default primary group is created only when both configured providers and models are empty. If you configure a provider here, also define its model groups. See LLM provider environment variables.
Models
Model groups define which LLM an agent uses. Each group references a provider connection handle and has a primary model, optional fallbacks, and protocol-specific parameters.
Model groups can be configured in YAML or in the administration UI.
The model selector combines live provider listings, bundled or cached catalogue metadata, and saved or manually entered model IDs. It shows available protocols and supported settings for the selected connection. Catalogue metadata supplies context limits when context_window is unset; if no catalogue limit is available, Frona uses 128,000 tokens. An explicit value takes precedence. Set max_tokens when you need an output limit. Inference uses inference.default_max_tokens to reserve output space in its history budget when that limit is unset. Catalogue defaults shown in the editor are not automatically written into your YAML.
Common fields
These fields are available for all providers:
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | required | Handle of a configured provider connection |
api | string | connection default | Request protocol supported by the connection and model |
extra_params | object | {} | Native request parameters merged after typed settings; see below |
model | string | required | Model ID. For aggregator providers like OpenRouter, use the vendor-namespaced form (e.g. anthropic/claude-sonnet-4-5, qwen/qwen3-coder) |
fallbacks | list of objects | [] | Inline fallback model configurations tried in order if the primary fails; see below |
max_tokens | integer | unset | Explicit maximum tokens to generate per response |
temperature | float | -- | Sampling temperature (0.0-2.0) |
context_window | integer | catalog or 128000 | Group-wide context budget. Uses the primary model's catalog limit when available, otherwise 128,000 tokens |
retry.max_retries | integer | 10 | Maximum retry attempts on failure |
retry.initial_backoff_ms | integer | 1000 (1s) | Initial backoff between retries |
retry.backoff_multiplier | float | 2.0 | Exponential backoff multiplier |
retry.max_backoff_ms | integer | 60000 (60s) | Maximum backoff duration |
Fallbacks
Each fallback specifies its own provider handle, model ID, and request settings. Provider handles must refer to configured or automatically discovered connections. For example:
models:
primary:
provider: openai
model: gpt-5
context_window: 128000
retry:
max_retries: 3
fallbacks:
- provider: anthropic
model: claude-sonnet-4-5
max_tokens: 8192Set retry and context_window on the containing group. These settings inside fallback entries, and any nested fallbacks, are ignored in v2026.10.0. Choose a group context budget that fits every model in the chain; switching to a fallback does not select a new context limit from its catalogue entry.
Anthropic
models:
primary:
provider: anthropic
model: claude-sonnet-4-5
max_tokens: 8192
thinking:
type: enabled
budget_tokens: 4096For ordinary manual extended thinking, use a budget of at least 1,024 tokens and less than max_tokens, leaving room for the final answer. See Anthropic's thinking budget rules for the interleaved-thinking exception and model-specific requirements.
| Property | Type | Description |
|---|---|---|
thinking.type | string | enabled or disabled |
thinking.budget_tokens | integer | Token budget used when thinking is enabled |
top_p | float | Nucleus-sampling probability |
top_k | integer | Limit sampling to the highest-probability tokens |
stop_sequences | list of strings | Sequences that stop generation |
OpenAI
models:
openai_reasoning:
provider: openai
model: gpt-5
api: responses
reasoning_effort: high| Property | Type | Protocols accepted by Frona | Description |
|---|---|---|---|
api | string | Both | responses or completions (chat_completions remains an alias); see API selection below |
top_p | float | Both | Nucleus-sampling probability |
min_p | float | completions only | Minimum probability threshold |
frequency_penalty | float | completions only | Penalize tokens according to their frequency |
presence_penalty | float | completions only | Penalize tokens that have already appeared |
seed | integer | completions only | Sampling seed when supported by the model |
max_completion_tokens | integer | Both | Completion-token limit; mapped to max_output_tokens for Responses |
reasoning_effort | string | Both | Reasoning level such as low, medium, or high; mapped to reasoning.effort for Responses |
logprobs | boolean | completions only | Return token log probabilities |
top_logprobs | integer | Both | Number of most likely tokens included with log probabilities |
stop | list of strings | completions only | Sequences that stop generation |
Frona rejects typed settings that are unsupported by the selected protocol. Acceptance by Frona does not guarantee support by every endpoint or model; use settings supported by your selected model.
For the openai provider, api selects the request protocol:
| Value | Behavior |
|---|---|
responses | Use the OpenAI Responses API, including its reasoning and tool-call representation |
completions | Use the Chat Completions API; chat_completions remains accepted |
The field is optional. Connections with the openai brand default to responses, including manually entered models. Set api: completions for a proxy or endpoint that only supports Chat Completions. Custom brands using adapter: openai default to completions. ChatGPT account credentials support Responses only.
The api field is available across providers, but only protocols implemented by the selected connection are accepted. Other protocol IDs are anthropic-messages, google-generate-content, amazon-bedrock-converse, cohere-chat, ollama, and huggingface.
Azure OpenAI
Configure the Azure resource endpoint and API key, then use the exact deployment name as the model. Azure's base-model catalogue is not a deployment inventory. This adapter supports completions and API-key authentication.
providers:
azure-work:
provider: azure
base_url: https://your-resource.openai.azure.com
api_key: ${AZURE_OPENAI_API_KEY}
azure_api_version: "2024-10-21"
models:
primary:
provider: azure-work
model: your-deployment-name
api: completionsAmazon Bedrock
Bedrock uses the Converse protocol. Configure a region and either a bearer API key through api_key or the server's AWS credential chain, optionally selecting a profile. The container must have access to the selected credentials and region configuration.
providers:
bedrock-work:
provider: amazon-bedrock
aws_region: us-west-2
aws_profile: frona
models:
primary:
provider: bedrock-work
model: your-bedrock-model-or-inference-profile-id
api: amazon-bedrock-converse
max_tokens: 4096
top_p: 0.9Bedrock supports the common max_tokens and temperature fields plus top_p and stop_sequences.
Custom request parameters
Use extra_params for native JSON fields that do not have a typed Frona setting. The UI exposes these under Custom request parameters. Objects merge recursively after typed settings; arrays, scalar values, and explicit null values replace the corresponding value. A custom value can override a typed setting, and the editor reports these overlaps.
Values in extra_params are literal request data, including in fallback entries. Strings such as ${ENV_VAR} are sent unchanged and are not expanded from the server environment.
Use the selected protocol's native field names and nesting. For example, this overrides the typed reasoning setting for Responses:
models:
primary:
provider: openai
model: gpt-5
api: responses
reasoning_effort: medium
extra_params:
reasoning:
effort: highFrona rejects custom parameters that replace the model, conversation, tools, streaming controls, or other request fields it owns. Structured calls also protect their output-schema and required-tool controls. Unsupported typed settings produce a validation error; custom parameters remain subject to validation by the provider.
Groq
Groq supports top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, and stop. Its supported protocol is completions.
models:
fast:
provider: groq
model: llama-3.3-70b-versatile
top_p: 0.9OpenRouter
OpenRouter supports top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, and stop. Use vendor-namespaced model IDs.
models:
routed:
provider: openrouter
model: anthropic/claude-sonnet-4-6
reasoning_effort: highDeepSeek
DeepSeek supports top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, and stop.
models:
deepseek:
provider: deepseek
model: deepseek-chat
top_p: 0.9xAI
xAI supports top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, and stop.
models:
grok:
provider: xai
model: grok-2-latest
temperature: 0.7Together AI
Together AI supports top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, and stop.
models:
together:
provider: together
model: meta-llama/Llama-3.3-70B-Instruct-Turbo
top_p: 0.9Hyperbolic
Hyperbolic supports top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, and stop.
models:
hyperbolic:
provider: hyperbolic
model: meta-llama/Llama-3.3-70B-Instruct
temperature: 0.7Gemini
models:
reasoning:
provider: gemini
model: gemini-2.5-pro
thinking_config:
thinking_budget: 10000
include_thoughts: true| Property | Type | Description |
|---|---|---|
thinking_config.thinking_budget | integer | Token budget reserved for thinking |
thinking_config.include_thoughts | boolean | Include thought summaries in the response |
top_p | float | Nucleus-sampling probability |
top_k | integer | Limit sampling to the highest-probability tokens |
stop_sequences | list of strings | Sequences that stop generation |
candidate_count | integer | Number of response candidates to generate |
Ollama
models:
local:
provider: ollama
model: llama3.1
num_ctx: 8192
num_predict: 4096| Property | Type | Description |
|---|---|---|
think | boolean | Enable model thinking when supported |
num_ctx | integer | Ollama context-window size |
num_predict | integer | Maximum tokens to predict |
num_batch | integer | Prompt-processing batch size |
num_keep | integer | Prompt tokens retained during context shifting |
num_thread | integer | CPU threads used by the model |
num_gpu | integer | Model layers offloaded to the GPU |
top_k, top_p, min_p | integer/float | Sampling controls |
repeat_penalty, repeat_last_n | float/integer | Repetition controls |
frequency_penalty, presence_penalty | float | Token penalties |
mirostat, mirostat_eta, mirostat_tau | integer/float | Mirostat sampling controls |
tfs_z | float | Tail-free sampling value |
seed | integer | Sampling seed |
stop | list of strings | Sequences that stop generation |
use_mmap, use_mlock | boolean | Model memory-loading controls |
Cohere
Cohere has no additional model-group properties. Use the common fields.
Mistral
Mistral has no additional model-group properties. Use the common fields.
Perplexity
Perplexity has no additional model-group properties. Use the common fields.
Moonshot
Moonshot has no additional model-group properties. Use the common fields.
Mira
Mira has no additional model-group properties. Use the common fields.
Galadriel
Galadriel has no additional model-group properties. Use the common fields. It uses an OpenAI-compatible Chat Completions endpoint; when providers.galadriel.base_url is unset, Frona uses https://api.galadriel.com/v1/verified.
Hugging Face
Hugging Face has no additional model-group properties. Use the common fields.
Apps
Settings for agent-deployed applications.
app:
port_range_start: 4000
port_range_end: 4100
health_check_timeout_secs: 30
max_restart_attempts: 2
hibernate_after_secs: 259200| Field | Type | Default | Description |
|---|---|---|---|
port_range_start | integer | 4000 | Start of the port range for app allocation |
port_range_end | integer | 4100 | End of the port range for app allocation |
health_check_timeout_secs | integer | 30 | Maximum time to wait for an app to become healthy during deployment |
max_restart_attempts | integer | 2 | How many times to restart a crashed app before marking it as failed |
hibernate_after_secs | integer | 259200 (3 days) | Inactivity duration before auto-hibernating an app |
Cache
Entity caching settings.
cache:
entity_ttl_secs: 300
entity_max_capacity: 1000| Field | Type | Default | Description |
|---|---|---|---|
entity_ttl_secs | integer | 300 (5 min) | Time-to-live for cached entities |
entity_max_capacity | integer | 1000 | Maximum number of cached entities |
Channel
Default retry policy for channel connections. Per-channel overrides on the channel detail page take precedence. See Channels.
channel:
retry:
max_retries: 4294967295
initial_backoff_ms: 1000
backoff_multiplier: 2.0
max_backoff_ms: 60000| Field | Type | Default | Description |
|---|---|---|---|
retry.max_retries | integer | unlimited | Total retry attempts before a channel is marked Failed for good. |
retry.initial_backoff_ms | integer | 1000 (1s) | Delay before the first retry. |
retry.backoff_multiplier | float | 2.0 | Delay multiplier between attempts. |
retry.max_backoff_ms | integer | 60000 (60s) | Cap on the delay between attempts. |
Share
Short share links and preview pages. Channel adapters mint /s/{id} and /p/{id} URLs through this service when they need to point a user at a workspace file or chat snapshot — most visibly when an SMS reply overflows the segment limit and the overflow needs a stable link.
share:
ttl_secs: 2592000
cleanup_interval_secs: 21600| Field | Type | Default | Description |
|---|---|---|---|
ttl_secs | integer | 2592000 (30 days) | Lifetime of a newly-issued share row. Expired links return a non-leaking 404. |
cleanup_interval_secs | integer | 21600 (6 hours) | How often the scheduler deletes expired share rows. |
Signal
Safety caps for the signal matcher.
signal:
max_pending_per_user: 50
default_max_evaluations: 50
default_max_continuous_evaluations: 1000| Field | Type | Default | Description |
|---|---|---|---|
max_pending_per_user | integer | 50 | Maximum number of pending signal watches per user. |
default_max_evaluations | integer | 50 | Default safety cap on candidates a one-shot watch is evaluated against before auto-failing. |
default_max_continuous_evaluations | integer | 1000 | Default safety cap on fires a continuous-mode watch can absorb before auto-completing. |
MCP
MCP server hosting (see MCP).
mcp:
enabled: true
cache_path: data/system/mcp-cache
max_servers_per_user: 32
startup_timeout_secs: 30
health_check_interval_secs: 10
max_restart_attempts: 3
default_transport: stdio
port_range_start: 4100
port_range_end: 4200
bridge_mode: truePer-MCP-server workspaces live under {data_dir}/users/{user_handle}/mcps/{mcp_handle}/ and are not separately configurable. The package cache is shared across all users.
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable MCP server support. |
cache_path | string | {data_dir}/system/mcp-cache | Shared package cache directory (npm, uv). |
max_servers_per_user | integer | 32 | Maximum number of MCP servers a single user can install. |
startup_timeout_secs | integer | 30 | Seconds to wait for an MCP server's initialize handshake before failing. |
health_check_interval_secs | integer | 10 | Interval between MCP server liveness checks. |
max_restart_attempts | integer | 3 | Maximum process restart attempts before marking a server as failed. |
default_transport | string | stdio | Default transport for new MCP servers: stdio or http. |
port_range_start | integer | 4100 | Start of port range for local HTTP MCP servers. |
port_range_end | integer | 4200 | End of port range (exclusive) for local HTTP MCP servers. |
bridge_mode | boolean | true | Expose MCP tools via the mcpctl CLI bridge instead of individual tool definitions. Reduces LLM context token usage. See Bridge mode. |
Sensitive values
These fields are automatically redacted in logs: auth.encryption_secret, sso.client_secret, voice.twilio_account_sid, voice.twilio_auth_token, all vault.* credential fields, and all providers[*].api_key values.