Skip to content

Configuration Reference

RivetOS uses a single YAML config file for all settings. API keys and secrets go in .env, never in the config file.

Config file locations (checked in order):

  1. --config CLI flag
  2. ./config.yaml (current directory)
  3. ~/.rivetos/config.yaml

Validate without starting: rivetos config validate


runtime:
workspace: ~/.rivetos/workspace
default_agent: opus
agents:
opus:
provider: anthropic
default_thinking: medium
providers:
anthropic:
model: claude-sonnet-4-6
max_tokens: 8192
channels:
discord:
channel_bindings:
"123456789": opus
memory:
postgres: {}

Any string value can reference environment variables with ${VAR_NAME}:

providers:
anthropic:
api_key: ${ANTHROPIC_API_KEY}
memory:
postgres:
connection_string: ${RIVETOS_PG_URL}

Unset variables resolve to empty strings. Recommended: put all secrets in .env and reference them.


Top-level runtime configuration.

KeyTypeDefaultDescription
workspacestringrequiredPath to workspace directory containing CORE.md, USER.md, etc.
default_agentstringrequiredAgent to use when no channel binding matches. Must match a key in agents.
turn_timeoutnumber900Wall-clock timeout for a single agent turn, in seconds.
contextobjectContext-management tuning. context.soft_nudge_pct (number[]) and context.hard_nudge_pct (number) control when the agent is nudged to compact as the window fills.
skill_dirsstring[][~/.rivetos/workspace/skills]Directories to scan for skills.
plugin_dirsstring[][]Additional directories to scan for plugins beyond the default plugins/.

Array of scheduled agent tasks. Each heartbeat triggers the agent periodically.

runtime:
heartbeats:
- agent: opus
schedule: "*/30 * * * *" # Every 30 minutes
prompt: "Check for unread emails and calendar events."
output_channel: discord:123456789
timezone: America/New_York
quiet_hours:
start: 23
end: 8
KeyTypeDefaultDescription
agentstringrequiredWhich agent runs this heartbeat. Must match a key in agents.
schedulestringrequiredCron expression (e.g., */30 * * * * = every 30 min).
promptstringrequiredThe message sent to the agent on each heartbeat tick.
output_channelstringChannel to deliver output (format: platform:channel_id).
timezonestringUTCTimezone for schedule evaluation.
quiet_hours.startnumberHour (0-23) to start quiet period (no heartbeats).
quiet_hours.endnumberHour (0-23) to end quiet period.

Safety hooks configuration.

runtime:
safety:
shellDanger: true
audit: true
workspaceFence:
allowedDirs:
- /home/user/projects
- /tmp
alwaysAllow:
- /usr/bin
tools:
- shell
- file_write
- file_edit
KeyTypeDefaultDescription
shellDangerbooleantrueBlock dangerous shell commands (rm -rf /, etc.).
auditbooleantrueLog all tool executions to audit log.
workspaceFenceobjectRestrict file/shell operations to specific directories.
workspaceFence.allowedDirsstring[]required if fence enabledDirectories the agent can access.
workspaceFence.alwaysAllowstring[][]Paths always allowed regardless of fence.
workspaceFence.toolsstring[]all toolsWhich tools the fence applies to.

Automatic post-tool actions. Run after tool executions complete.

runtime:
auto_actions:
format: true
lint: false
test: false
gitCheck: true
KeyTypeDefaultDescription
formatbooleanfalseAuto-format files after edits.
lintbooleanfalseAuto-lint files after edits.
testbooleanfalseAuto-run tests after code changes.
gitCheckbooleanfalseCheck git status after file operations.

Named agent definitions. Each agent maps to a provider and has optional configuration.

agents:
opus:
provider: anthropic
default_thinking: medium
tools:
exclude:
- shell
grok:
provider: xai
local:
provider: ollama
local: true
KeyTypeDefaultDescription
providerstringrequiredProvider ID. Must match a key in providers.
modelstringprovider defaultModel override — use a specific model from this provider instead of its default. Lets several agents share one provider at different models.
default_thinkingstringoffDefault thinking level: off, low, medium, high.
localbooleanfalseIf true, uses extended workspace context (includes CAPABILITIES.md, daily notes). Use for local models where tokens are free.
tools.excludestring[][]Tool names to block for this agent.
tools.includestring[]allIf set, only these tools are available to this agent.

LLM provider configuration. Each key is a provider ID referenced by agents.

providers:
anthropic:
model: claude-sonnet-4-6
max_tokens: 8192
KeyTypeDefaultDescription
modelstringclaude-opus-4-7Model identifier.
max_tokensnumber8192Maximum output tokens.
api_keystring${ANTHROPIC_API_KEY}API key. Prefer env var.
context_windownumberOverride the model’s context-window size (advanced; for budgeting).
max_output_tokensnumberHard cap on output tokens, independent of max_tokens.

Auth: Set ANTHROPIC_API_KEY in .env. For subscription/OAuth auth instead of an API key, use the claude-cli provider (below), which delegates auth to the claude binary.

providers:
xai:
model: grok-4.20-reasoning
KeyTypeDefaultDescription
modelstringgrok-4.20-reasoningModel identifier. (grok-4-1-fast-reasoning is a cheaper tier good for compaction.)
api_keystring${XAI_API_KEY}API key.
max_tokensnumber4096Maximum output tokens.
temperaturenumberSampling temperature.
context_windownumberOverride the model’s context-window size (advanced).
max_output_tokensnumberHard cap on output tokens.
providers:
google:
model: gemini-2.5-pro
KeyTypeDefaultDescription
modelstringgemini-2.5-proModel identifier.
api_keystring${GOOGLE_API_KEY}API key.
max_tokensnumber8192Maximum output tokens.
context_windownumberOverride the model’s context-window size (advanced).
max_output_tokensnumberHard cap on output tokens.
providers:
ollama:
model: qwen2.5:32b
base_url: http://localhost:11434
KeyTypeDefaultDescription
modelstringrequiredModel name (must be pulled locally).
base_urlstringhttp://localhost:11434Ollama API endpoint.
temperaturenumberSampling temperature.
num_ctxnumberContext window size passed to Ollama.
keep_alivestringHow long Ollama keeps the model loaded between requests (e.g. 5m, -1 for always).
context_windownumberOverride the context-window size reported to the runtime (advanced).
max_output_tokensnumberHard cap on output tokens.

Dedicated provider for a vLLM server. Exposes the full vLLM surface.

  • Folds any post-first system message into a user message with a [SYSTEM NOTICE] prefix (vLLM/Qwen/Llama templates reject mid-conversation system messages)
  • Consumes vLLM’s native reasoning_content field when a --reasoning-parser is configured server-side
  • model: default auto-discovers the served model (and its context window) from /v1/models
providers:
vllm:
base_url: http://vllm.local:8000 # trailing /v1 optional
model: default
top_k: 40
min_p: 0.05
# api_key: ${VLLM_API_KEY} # only if vLLM started with --api-key
KeyTypeDefaultDescription
base_urlstringrequiredvLLM server URL (/v1 optional).
modelstringdefaultServed model id; default auto-discovers.
api_keystring${VLLM_API_KEY}Bearer token (only if --api-key set).
max_tokensnumber4096Maximum output tokens.
temperaturenumber0.7Sampling temperature.
top_pnumber0.95Nucleus sampling.
top_knumbervLLM sampling extension.
min_pnumbervLLM sampling extension.
presence_penaltynumberStandard OpenAI penalty.
frequency_penaltynumberStandard OpenAI penalty.
repetition_penaltynumbervLLM extension.
min_tokensnumbervLLM extension; minimum output tokens.
stopstring[]Stop sequences.
seednumberReproducible sampling seed.
context_windownumberContext-window size reported to the runtime.
max_output_tokensnumberHard cap on output tokens.
default_tool_choicestringautoauto, none, or required.
verify_model_on_initbooleanfalseProbe /v1/models at boot to confirm the model is served.
namestringDisplay name for the provider.
mm_processor_kwargsobjectvLLM multimodal processor kwargs (passthrough).
chat_template_kwargsobjectvLLM chat-template kwargs (passthrough).
extra_bodyobjectArbitrary JSON merged into the request body (vLLM passthrough).

Dedicated provider for llama.cpp’s llama-server. Lean by design — standard OpenAI sampling plus llama.cpp’s top_k / min_p and a generic extra_body escape hatch. None of the vLLM-only machinery (no mm_processor_kwargs, chat_template_kwargs, repetition_penalty, min_tokens, or video).

For native <think> reasoning, start llama-server with --reasoning-format deepseek.

providers:
llama-server:
base_url: http://localhost:8080
model: default
top_k: 40
min_p: 0.05
KeyTypeDefaultDescription
base_urlstringrequiredllama-server URL (/v1 optional).
modelstringdefaultServed model id; default auto-discovers.
api_keystring${LLAMA_SERVER_API_KEY}Bearer token (only if --api-key set).
max_tokensnumber4096Maximum output tokens.
temperaturenumber0.7Sampling temperature.
top_pnumber0.95Nucleus sampling.
top_knumberllama.cpp sampling extension.
min_pnumberllama.cpp sampling extension.
presence_penaltynumberStandard OpenAI penalty.
frequency_penaltynumberStandard OpenAI penalty.
stopstring[]Stop sequences.
seednumberReproducible sampling seed.
context_windownumberContext-window size reported to the runtime.
max_output_tokensnumberHard cap on output tokens.
default_tool_choicestringautoauto, none, or required.
verify_model_on_initbooleanfalseProbe /v1/models at boot to confirm the model is served.
namestringDisplay name for the provider.
extra_bodyobjectArbitrary JSON merged into the request body (e.g. grammar, n_probs).

Drives the local claude binary (Claude Code CLI) using the user’s subscription OAuth token — the sanctioned third-party-harness pattern per Anthropic’s April 2026 policy. The CLI owns auth, session caching, and the wire protocol; this provider drives it via stream-json and brings up a per-spawn embedded MCP server that exposes every executable RivetOS tool to claude-cli through --mcp-config.

providers:
claude-cli:
binary: claude # path or name on PATH
model: claude-opus-4-7 # optional — defaults to whatever the CLI picks
KeyTypeDefaultDescription
binarystringclaudePath to the claude binary.
modelstringModel alias to pass to the CLI.
extra_argsstring[][]Additional CLI flags (advanced).

Auth: claude login (via the CLI itself). RivetOS does not handle the OAuth flow — the CLI does.


Messaging channel configuration. Each key is a channel ID.

channels:
discord:
channel_bindings:
"123456789012345678": opus
"987654321098765432": grok
owner_id: "111222333444555666"
KeyTypeDefaultDescription
channel_bindingsobjectrequiredMaps Discord channel IDs to agent names.
owner_idstringDiscord user ID for owner-only features.
bot_tokenstring${DISCORD_BOT_TOKEN}Bot token. Prefer env var.
allowed_guildsstring[]If set, only these guild (server) IDs may interact.
allowed_channelsstring[]If set, only these channel IDs may interact (beyond channel_bindings).
allowed_usersstring[]If set, only these user IDs may interact.
mention_onlybooleanfalseOnly respond when the bot is @-mentioned.
mention_only_channelsstring[]Channel IDs where mention-only mode applies (overrides the global setting per-channel).

Setup: Create a bot at discord.com/developers, copy the token, invite the bot to your server.

channels:
telegram:
owner_id: "123456789"
KeyTypeDefaultDescription
owner_idstringrequiredTelegram user ID. Only this user can talk to the bot.
bot_tokenstring${TELEGRAM_BOT_TOKEN}Bot token from @BotFather.
allowed_usersstring[]Additional Telegram user IDs permitted to interact, beyond owner_id.
agentstringdefault_agentAgent that handles this channel.

Inter-agent communication channel. Enables delegation between agents and mesh networking.

Note: for cross-node (mesh) auth, secret is superseded by mutual TLS (mesh.tls) as of Phase 0.5 — configure mesh: for node-to-node traffic. The standalone channels.agent plugin still enforces its bearer secret when configured; it is deprecated, not dead. The plugin’s fate is decided when the gateway subsumes agent HTTP ingress (phase 1/5).

channels:
agent:
port: 3100
secret: ${AGENT_CHANNEL_SECRET} # still enforced by this plugin when set
KeyTypeDefaultDescription
portnumber3100HTTPS port for agent-to-agent messaging.
secretstringDeprecated but enforced. Bearer token checked by the standalone agent channel plugin when set. Mesh node-to-node auth uses mTLS via mesh.tls instead.

Multi-node mesh networking. Allows agents on different nodes to delegate tasks to each other via mTLS. See docs/mesh.md for full documentation.

mesh:
enabled: true
node_name: ct110 # must match the cert CN
tls: true # use default cert paths derived from node_name
agent_channel_port: 3000
storage_dir: /rivet-shared
heartbeat_interval_ms: 30000
stale_threshold_ms: 90000
discovery:
mode: seed
seed_host: ct110.mesh # use .mesh DNS — matches cert SAN
seed_port: 3000
KeyTypeDefaultDescription
mesh.enabledboolfalseEnable mesh networking.
mesh.node_namestringhostnameNode name — must match cert CN.
mesh.tlsbool | objectmTLS config. Required when mesh.enabled: true.
mesh.tls.ca_pathstring/rivet-shared/rivet-ca/intermediate/ca-chain.pemCA chain PEM.
mesh.tls.cert_pathstring/rivet-shared/rivet-ca/issued/<node_name>.crtNode cert PEM.
mesh.tls.key_pathstring/rivet-shared/rivet-ca/issued/<node_name>.keyNode private key PEM.
mesh.agent_channel_portnumber3000HTTPS port for the agent channel.
mesh.storage_dirstring/rivet-sharedDirectory containing mesh.json.
mesh.heartbeat_interval_msnumber30000Heartbeat write interval.
mesh.stale_threshold_msnumber90000Age before a node is marked stale.
mesh.discovery.modestringseed | static | mdns.
mesh.discovery.seed_hoststringSeed node hostname (use <nodeName>.mesh).
mesh.discovery.seed_portnumber3100Seed node port.
mesh.secretstringIgnored — mesh agent-channel auth is mTLS only. Accepted with a warning for back-compat; remove it from your config.

Memory backend configuration. Currently supports PostgreSQL.

memory:
postgres:
connection_string: ${RIVETOS_PG_URL}
# Optional — point the background memory loop at your own endpoints:
# embed_endpoint: http://your-embed-host:9402/v1
# delegation_tracking: true
KeyTypeDefaultDescription
connection_stringstring${RIVETOS_PG_URL}PostgreSQL connection URL.
embed_endpointstringOpenAI-compatible embeddings endpoint used by the embedding worker. Overrides the built-in default.
delegation_trackingbooleanfalsePersist delegation events into memory (ros_messages, channel delegation) for auditing.

Required extensions: pgvector (for embedding storage and similarity search).

The memory plugin handles schema creation and migration automatically on first boot.


Durable task engine (phase 1). The embedded run-task runner starts when Postgres is configured and the 0002_ros_tasks migration has been applied (rivetos-memory-migrate); on unmigrated nodes it logs a warning and stays inert instead of failing boot.

KeyTypeDefaultDescription
enabledbooleantrueStart the embedded task runner. Inert while nothing creates tasks.

Env knobs: RIVETOS_TASKS_CONCURRENCY (default 4), RIVETOS_TASKS_POLL_MS (default 2000).

Inbound surfaces that expose RivetOS tools to external clients. Currently: the MCP server transport (@rivetos/mcp-server) — a StreamableHTTP MCP server that exposes memory_*, web_*, skill_*, and runtime tools to any MCP-speaking client (Claude Code, Cursor, etc.).

transports:
mcp:
port: 4321
bind: 127.0.0.1 # default localhost
tls: # optional mTLS
ca_path: /rivet-shared/rivet-ca/intermediate/ca-chain.pem
cert_path: /rivet-shared/rivet-ca/issued/<node>.crt
key_path: /rivet-shared/rivet-ca/issued/<node>.key

The transport is only activated when the matching transports.<name> slice is present. The MCP server can also run standalone via the rivetos-mcp-server bin shipped by @rivetos/mcp-server.


Outbound Model Context Protocol — RivetOS connects to external MCP servers and exposes their tools to agents (the inverse of the transports.mcp plugin above).

mcp:
servers:
memory:
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-memory"]
toolPrefix: mcp_memory
github:
transport: streamable-http
url: http://localhost:8080/mcp
connectTimeout: 5000
autoReconnect: true
KeyTypeDefaultDescription
transportstringrequiredstdio, streamable-http, or sse.
commandstringCommand to launch (stdio transport).
argsstring[][]Command arguments (stdio transport).
envobject{}Environment variables for the spawned process.
cwdstringWorking directory for the spawned process.
urlstringServer URL (HTTP/SSE transport).
toolPrefixstringPrefix for tool names (prevents collisions between servers).
connectTimeoutnumber10000Connection timeout in milliseconds.
autoReconnectbooleantrueAuto-reconnect on disconnect.

Optional. Captures the desired runtime topology (datahub host, agent placement, networking) for documentation and tooling. Provisioning is currently driven by the Compose files under infra/docker/ and the scripts under infra/scripts/.

deployment:
target: docker
datahub:
postgres: true
shared_storage: true
shared_mount_path: /rivet-shared
image:
build_from_source: true
docker:
network: rivetos-net
postgres_port: 5432
KeyTypeDefaultDescription
targetstringrequireddocker, proxmox, kubernetes, or manual.
KeyTypeDefaultDescription
postgresbooleantrueInclude PostgreSQL in the datahub container.
postgres_versionstring16PostgreSQL major version.
shared_storagebooleantrueCreate shared storage volume.
shared_mount_pathstring/rivet-sharedMount path for shared storage inside containers.
KeyTypeDefaultDescription
build_from_sourcebooleantrueBuild container images from local source tree.
registrystringContainer registry for pre-built images (e.g., ghcr.io/philbert440).
agent_imagestringrivetos-agentAgent image name.
tagstringlatestImage tag.
KeyTypeDefaultDescription
networkstringrivetos-netDocker network name.
postgres_portnumber5432Host port for PostgreSQL.
project_namestringrivetosDocker Compose project name.
KeyTypeDefaultDescription
api_urlstringProxmox API URL (e.g., https://192.168.1.1:8006).
nodesarrayNode definitions (see below).
network.bridgestringvmbr0Network bridge.
network.subnetstringSubnet for container IPs.
network.gatewaystringDefault gateway.

Node definition:

KeyTypeDescription
namestringNode name (e.g., pve1).
hoststringNode IP or hostname.
rolestringdatahub, agents, or both.
ctid_startnumberStarting container ID.
KeyTypeDefaultDescription
namespacestringrivetosKubernetes namespace.
storage_classstringStorage class for PVCs.
resources.cpustring500mCPU request per agent pod.
resources.memorystring512MiMemory request per agent pod.

These are typically set in .env:

VariableUsed ByDescription
ANTHROPIC_API_KEYprovider-anthropicAnthropic API key
XAI_API_KEYprovider-xaixAI API key
GOOGLE_API_KEYprovider-googleGoogle AI API key
DISCORD_BOT_TOKENchannel-discordDiscord bot token
TELEGRAM_BOT_TOKENchannel-telegramTelegram bot token
RIVETOS_PG_URLmemory-postgresPostgreSQL connection string
RIVETOS_AGENT_SECRETchannel-agentDeprecated — was the bearer secret for agent mesh. No longer used for agent-channel auth (replaced by mTLS).
RIVETOS_LOG_LEVELcoreLog level: error, warn, info, debug
RIVETOS_LOG_FORMATcoreLog format: pretty (default) or json
GOOGLE_CSE_IDtool-web-searchGoogle Custom Search Engine ID
GOOGLE_CSE_KEYtool-web-searchGoogle CSE API key
OPENAI_API_KEYmemory-postgres (embeddings)OpenAI API key for embeddings

See config.example.yaml in the repository root for a complete annotated config file with all options commented.