Start the server with agentim --config agentim.toml. Every section is optional except [storage]; unknown keys are refused at start. An annotated example: server/agentim.example.toml.
| Key |
Type |
Default |
Description |
control |
string |
|
The database (by name) holding users, devices, units and the conversation directory. |
| Key |
Type |
Default |
Description |
name |
string |
|
A name for this database, used by control and by units. |
url |
string |
|
sqlite://…, postgres://… or mysql://…. |
read_pool |
number |
|
Connections for reads (the writer has its own). |
unsafe_durability |
boolean |
|
Start even if the database is not configured for full durability. |
| Key |
Type |
Default |
Description |
mode |
ReplicationMode |
"auto" |
auto (detect replicas at start), managed_sync (the provider replicates synchronously: RDS Multi-AZ, Cloud SQL HA) or none. |
wait_ms |
number |
5000 |
How long a batch waits for the replicas before answering unavailable (the write stays and is confirmed later). |
replicas_required |
number |
|
Replicas that must have a write (default: all that replicate). |
replica_urls |
string[] |
|
MySQL: each asynchronous replica, checked for the primary’s GTIDs. |
| Key |
Type |
Default |
Description |
name |
string |
|
The unit (an organisation or subsidiary) whose conversations are stored apart. |
database |
string |
|
The database (by name) for the unit’s new conversations. |
| Key |
Type |
Default |
Description |
max_batch |
number |
512 |
Maximum commands committed in one transaction (one fsync). |
queue_capacity |
number |
10000 |
Bounded command queue per database; a full queue answers overloaded. |
commit_delay_us |
number |
0 |
Optional wait before committing to collect a larger batch. 0 = never wait. |
Client compatibility (docs/en/design/messaging.md) and per-person limits.
| Key |
Type |
Default |
Description |
min_versions |
std::collections::BTreeMap<string, String> |
|
Lowest supported version per client name, e.g. agentim-js = "1.2.0". Older clients are refused in hello with client_too_old. |
send_rate |
number |
10.0 |
Messages a person may send per second, and the burst (all their connections together). |
send_burst |
number |
30.0 |
Messages a person may send at once before send_rate applies. |
max_connections |
number |
10 |
Connections (WebSocket and MCP sessions) per user at once. |
max_group_members |
number |
1000 |
Members of a group, at creation and later. |
idle_secs |
number |
90 |
A WebSocket that sends nothing (not even a pong) for this long is closed; the server pings at a third of it. |
The app’s defaults of what people may do in their client.
| Key |
Type |
Default |
Description |
create_groups |
boolean |
true |
Create group conversations. |
create_direct |
boolean |
true |
Start direct conversations. |
add_members |
boolean |
true |
Add members to groups they own or administer. |
find_users |
boolean |
true |
Find other users by exact name. |
create_agents |
boolean |
false |
Create agents of their own and manage their keys (off: the developer hands agents out through the open API). |
edit_minutes |
number |
|
Their own messages can be edited / recalled this long after sending (None: always). |
recall_minutes |
number |
|
Like edit_minutes, for recalling (deleting for everyone). |
direct_to_non_friends |
boolean |
true |
Start direct conversations with, and add to groups, people who are not friends (docs/en/design/agents.md); off: friends only (own agents and the app’s agents once added count as friends). |
| Key |
Type |
Default |
Description |
name |
string |
|
A name for the webhook (logs, metrics, its outbox position). |
url |
string |
|
Where events are POSTed (signed with secret). |
secret |
string |
|
HMAC key for the webhook-signature header: a Standard Webhooks secret (whsec_ + base64, the key being the decoded bytes, as the official verification libraries expect), or any text; at least 16 bytes of key either way. |
events |
string[] |
|
Event types to deliver: exact (msg.created), a prefix (msg.*) or *. |
max_attempts |
number |
|
Attempts per event before it is dropped (and audited). |
timeout_ms |
number |
|
How long one delivery may take before it is retried. |
backoff_ms |
number |
|
First retry delay; doubles per attempt, at most 5 minutes. |
| Key |
Type |
Default |
Description |
url |
string |
|
Called before a message is stored: it may allow, replace or refuse it. |
secret |
string |
|
Signs the requests (Standard Webhooks, base64). |
timeout_ms |
number |
|
How long the hook may take; then fail_open decides. |
on_error |
HookFailure |
|
What to do when the hook cannot be reached or answers badly. |
Open API transport and limits (docs/en/design/open-api.md).
| Key |
Type |
Default |
Description |
behind_proxy |
boolean |
false |
Behind a TLS-terminating proxy: accept plain HTTP from anywhere and take the client address from X-Forwarded-For. |
proxy_hops |
number |
1 |
Trusted proxies in front of the server: the client address is this many entries from the right of X-Forwarded-For (entries further left come from the client and can be forged). |
rate_per_second |
number |
100.0 |
Requests per second per key, and the burst allowed. |
burst |
number |
200.0 |
Requests a key may make at once before rate_per_second applies. |
| Key |
Type |
Default |
Description |
allowed_origins |
string[] |
|
Browser origins allowed besides the server’s own, e.g. https://app.example.com (docs/en/design/security.md). |
public_url |
string |
|
How clients reach this server, e.g. https://im.example.com; used in the connection settings printed for new agents. |
| Key |
Type |
Default |
Description |
cert |
string |
|
PEM certificate chain and private key files. |
key |
string |
|
The private key (PEM) of cert. |
Logging in: client tokens (docs/en/design/access.md) and the console’s admin accounts (docs/en/design/security.md).
| Key |
Type |
Default |
Description |
max_failures |
number |
10 |
Failed admin logins before the account is locked, and for how long. |
lock_minutes |
number |
15 |
How long a console login stays locked after max_failures. |
token_idle_days |
number |
30 |
A person’s device unused this many days is forgotten (0: never): its next connection is a new device. Agent keys do not expire. |
max_token_days |
number |
30 |
Longest lifetime (exp - iat) of a client token. |
max_concurrent_hashes |
number |
0 |
Password hashes computed at once (each takes 19 MiB and a core); 0 means one per core. Callers beyond four times this wait-list are refused with rate_limited. |
Encryption at rest (docs/en/design/security.md). On by default.
| Key |
Type |
Default |
Description |
mode |
EncryptionMode |
|
managed (the default: content encrypted with a master key) or off. |
key_file |
string |
|
File holding the base64 master key. |
key |
string |
|
The base64 master key itself (tests; prefer key_file or the AGENTIM_MASTER_KEY environment variable). |
in the configuration file; days and counts.
| Key |
Type |
Default |
Description |
batch_size |
number |
200 |
Events per conversation per sync round. |
max_unacked |
number |
1000 |
Events sent to a device and not acknowledged yet, per conversation. |
max_gap |
number |
10000 |
A device further behind than this starts over like a new device. |
device_ttl_days |
number |
30 |
Devices that acknowledge nothing for this long lose their positions. |
window_days |
number |
90 |
A new device gets messages from this many days back… |
max_messages |
number |
30 |
…at most this many per conversation. |
older_enabled |
boolean |
false |
Conversations with nothing in the window: give a new device their last few events. |
older_messages |
number |
20 |
How many of those last events. |
older_max |
number |
100 |
At most this many such conversations. |
member_messages |
number |
30 |
Someone added to a group sees this many earlier messages… |
member_days |
number |
30 |
…from at most this many days back. |
share_max |
number |
200 |
Most earlier messages whoever adds someone may share (history). |
rate_per_second |
number |
10.0 |
Sync rounds a person may run a second… |
burst |
number |
20.0 |
…with bursts up to this many. |
agent_rate_per_second |
number |
2.0 |
Sync rounds an agent may run a second… |
agent_burst |
number |
5.0 |
…with bursts up to this many. |
how long the server keeps conversation events.
| Key |
Type |
Default |
Description |
days |
number |
|
0 keeps everything. |
.
| Key |
Type |
Default |
Description |
max_per_owner |
number |
20 |
Agents one person may own. |
conversations_per_hour |
number |
60 |
Conversations one agent may start per hour. |
history_per_minute |
number |
60 |
History and context reads per agent per minute (docs/en/design/agents.md). |
search_per_minute |
number |
30 |
Searches per agent per minute. |
state_keys |
number |
10000 |
Checkpoint keys one agent may keep (docs/en/design/agents.md). |
progress_per_second |
number |
10 |
Progress reports per agent per conversation per second (docs/en/design/agents.md §3). |
takeover_idle_minutes |
number |
30 |
A takeover (or handoff) the person has been silent in for this long goes back to the agent (docs/en/design/agents.md); 0 = never. |
A node of a cluster (docs/en/design/cluster.md). Times are in milliseconds; the defaults keep renew + 2 × op_timeout ≤ stop < lease and lease / stop ≥ 1.5.
| Key |
Type |
Default |
Description |
enabled |
boolean |
false |
Run as one node of a cluster (docs/en/design/cluster.md). |
node_id |
string |
String::new() |
Stable name of this node (letters, digits, -), unique in the cluster. |
listen |
string |
"0.0.0.0:7946" |
Where other nodes connect (cluster traffic, TLS). |
advertise |
string |
|
The address other nodes use for this one (default: listen). |
shards |
number |
256 |
Shards per database; fixed when the cluster is first set up. |
lease_ms |
number |
15000 |
How long a node holds its shards without renewing; must be at least 1.5 × stop_ms. |
renew_ms |
number |
3000 |
How often a node renews its leases; renew_ms + 2 × op_timeout_ms ≤ stop_ms. |
stop_ms |
number |
10000 |
A node that could not renew for this long stops writing (before its lease ends). |
op_timeout_ms |
number |
2000 |
How long a request to another node may take. |
secret |
string |
|
Protects the cluster’s certificate authority in the database (the same on every node); the encryption master key when not set. |
.
| Key |
Type |
Default |
Description |
enabled |
boolean |
true |
Serve the MCP endpoint (POST /mcp). |
rate_per_second |
number |
5.0 |
Tool calls per agent key (token bucket). |
burst |
number |
20.0 |
Calls an agent may make at once before rate_per_second applies. |
.
| Key |
Type |
Default |
Description |
due_hours |
number |
24 |
A report should be handled within this long (App Store: 24 hours). |
keep_days |
number |
180 |
Resolved reports and their evidence are deleted after this long. |
appeal_url |
string |
String::new() |
Written into every decision as the way to appeal; empty: the app tells. |
report_per_hour |
number |
20 |
Reports one user may file per hour. |
.
| Key |
Type |
Default |
Description |
enabled |
boolean |
true |
Off: pages come back empty with before_end = "disabled". |
page_max |
number |
100 |
Most messages on each side of the anchor. |
rate_per_second |
number |
5.0 |
Pages per second per person (all connections), and the burst. |
burst |
number |
20.0 |
Reads at once before rate_per_second applies. |
where files go and their limits.
| Key |
Type |
Default |
Description |
storage |
string |
"local" |
local (a folder; uploads go through the server) or s3 (an S3 compatible store; clients upload to it directly). |
dir |
string |
"./data/files" |
The folder of local, made on first use. |
shared |
boolean |
false |
local on a folder every node of a cluster shares (a network disk). |
max_bytes |
number |
4294967296 |
Largest file, in bytes (4 GiB). |
daily_bytes_per_user |
number |
0 |
Bytes one user may upload a day; 0 = no limit. |
max_open_per_user |
number |
10 |
Uploads one user may have open at once. |
retention_days |
number |
0 |
Files are deleted this many days after upload; 0 = kept. |
allow_metadata |
boolean |
false |
Whether apps may keep EXIF and GPS in images (keep_metadata). |
request traces outside the server (docs/en/design/tracing.md).
| Key |
Type |
Default |
Description |
trace_ui_url |
string |
|
A link to the trace in your tracing UI, with {trace_id} in it (for example https://jaeger.example.com/trace/{trace_id}); shown in a message’s trace. |
otlp_endpoint |
string |
|
Where to send spans over OTLP/HTTP (protobuf), e.g. http://otel-collector:4318/v1/traces; unset: nothing is exported, the logs keep the trace ids. |
sample_ratio |
number |
0.0 |
Share of traces exported, 0 to 1, chosen by trace id (the same on every node). Traces a trusted caller marked sampled, and dyed ones, are always exported. |
service_name |
string |
"agentim" |
service.name of the exported spans. |
one server or cluster for many tenants (docs/en/design/multi-tenancy.md). Off: the one tenant default, as every self-hosted server.
| Key |
Type |
Default |
Description |
enabled |
boolean |
false |
Requests belong to the tenant named by their host: <tenant>.<suffix>. |
host_suffix |
string |
String::new() |
The domain tenants are subdomains of, e.g. agentim.co. |
webhook_private_addresses |
boolean |
false |
Tenants’ webhooks may use http and private, loopback or link-local addresses (only for tests and closed networks: a tenant could reach the deployment’s internal services otherwise). |
webhook_disable_after_ms |
number |
5 * 86400000 |
A tenant’s webhook that has failed for this long without one success is turned off (milliseconds; default 5 days). |
webhooks_per_tenant |
number |
10 |
At most this many webhooks per tenant. |
where tenants’ databases are.
| Key |
Type |
Default |
Description |
name |
string |
|
A name the tenants table records (no address or password stored). |
url |
string |
|
A database URL with {tenant}: sqlite://data/tenants/{tenant}.db, postgres://user:pass@host/agentim_{tenant}, mysql://user:pass@host/agentim_{tenant}. |
read_pool |
number |
|
Read connections per open tenant. |
the model services every app may use (the deployment’s own keys, docs/en/design/assistants.md) and the price table. Apps add their own services in the console.
| Key |
Type |
Default |
Description |
prices_file |
string |
|
A price table replacing the shipped one (builtin/prices.toml format); only priced models can use a built-in key. |
private_addresses |
boolean |
|
Apps’ own services may use http and private, loopback or link-local addresses (tests and closed networks only). |
one provider with the deployment’s key.
| Key |
Type |
Default |
Description |
name |
string |
|
How apps refer to it, e.g. claude (1..64 of a-z 0-9 -). |
provider |
string |
|
anthropic, openai, gemini, deepseek or compatible. |
key_env |
string |
|
The environment variable holding the key (keys never go in files). |
base_url |
string |
|
The provider’s address; the provider’s own by default (required for compatible). |
daily_tokens |
number |
|
Tokens per app per day on this service; 0: no limit. |
limits of reactions and pins (docs/en/design/messaging.md, MSG-20 and MSG-21).
| Key |
Type |
Default |
Description |
reaction_keys |
number |
50 |
Different reaction keys a message may have. |
reactions_per_user |
number |
20 |
Reactions one person may add to one message. |
reaction_mode |
string |
"multi" |
multi, or single: one reaction per person and message, a new one replaces the old. |
reaction_names |
string[] |
|
Short names allowed as keys besides emoji, written :name: (the client draws them). |
reactions_as_feedback |
boolean |
false |
A 👍 or 👎 on an agent’s message also counts as feedback on the agent (docs/en/design/agents.md). |
reactions_per_second |
number |
20.0 |
Reactions (added or removed) one user may make per second. |
pins_per_conv |
number |
100 |
Pinned messages per conversation. |
agents_pin |
boolean |
false |
Agents may pin and unpin messages. |