packages/docs/configuration.mdx
Eliza uses a primary JSON5 config file for runtime and bootstrap settings. This page documents the config file, environment variable overrides, and the canonical runtime routing fields that now drive hosting and provider selection.
By default, Eliza stores its configuration at:
~/.eliza/eliza.json
Two environment variables control where Eliza looks for configuration:
| Variable | Purpose | Default |
|---|---|---|
ELIZA_STATE_DIR | Override the entire state directory | ~/.eliza |
ELIZA_CONFIG_PATH | Override the config file path directly | ~/.eliza/eliza.json |
ELIZA_CONFIG_PATH takes precedence over ELIZA_STATE_DIR. Both support ~ expansion for the home directory. For backwards compatibility, the legacy names MILADY_STATE_DIR and MILADY_CONFIG_PATH are also accepted as fallbacks.
# Use a custom state directory (config lives at /opt/eliza/eliza.json)
ELIZA_STATE_DIR=/opt/eliza eliza start
# Point to a specific config file
ELIZA_CONFIG_PATH=~/projects/bot/config.json5 eliza start
The state directory also contains:
| Path | Purpose |
|---|---|
~/.eliza/models/ | Cached model provider lists (per-provider JSON files) |
~/.eliza/credentials/ | OAuth credentials (overridable via ELIZA_OAUTH_DIR) |
~/.eliza/credentials/oauth.json | OAuth token storage |
Eliza's saved runtime topology is no longer inferred from a single
connection blob, and the root connection field is no longer part of the
persisted config schema. The canonical persisted fields are:
| Field | Purpose |
|---|---|
deploymentTarget | Where the active server runs: local, cloud, or remote |
linkedAccounts | Which provider or cloud accounts are available to that server |
serviceRouting | Which backend handles each capability (llmText, tts, media, embeddings, rpc) |
{
deploymentTarget: {
runtime: "cloud",
provider: "elizacloud",
},
linkedAccounts: {
elizacloud: {
status: "linked",
source: "oauth",
},
},
serviceRouting: {
llmText: {
backend: "anthropic",
transport: "direct",
primaryModel: "anthropic/claude-sonnet-4.6",
},
tts: {
backend: "elizacloud",
transport: "cloud-proxy",
accountId: "elizacloud",
},
},
}
That means a server can be hosted on Eliza Cloud while still using Anthropic, OpenAI, OpenRouter, or a local model for chat inference.
The config file supports JSON5 syntax, which allows:
// and /* */){
// Agent configuration
agent: { name: "mila" },
// API keys (prefer .env for secrets)
env: {
ANTHROPIC_API_KEY: "<ANTHROPIC_API_KEY>",
},
}
$include DirectiveConfigs support modular composition via $include. Included files are deep-merged in order, with later values overriding earlier ones.
{
"$include": "./base.json5",
// Local overrides merged on top
agents: { list: [{ id: "custom", name: "Custom Agent" }] }
}
// Array form: merge multiple base configs
{
"$include": ["./base.json5", "./connectors.json5"],
env: { MY_KEY: "override" }
}
Includes support up to 10 levels of nesting. Circular includes are detected and rejected.
Eliza loads environment variables from two sources:
<Tabs> <Tab title="Inline in config (env section)"> Set variables directly in `eliza.json`. They are applied to the process environment if not already set:```json5
{
env: {
ANTHROPIC_API_KEY: "<ANTHROPIC_API_KEY>",
OPENAI_API_KEY: "<OPENAI_API_KEY>",
// Structured form under vars:
vars: {
BRAVE_API_KEY: "<BRAVE_API_KEY>",
},
},
}
```
Both top-level string values and values under `env.vars` are merged into the process environment.
```json5
{
env: {
shellEnv: {
enabled: true,
timeoutMs: 15000, // default: 15s
},
},
}
```
This runs `$SHELL -l -c 'env -0'` and imports missing variables.
Here is every top-level key in ElizaConfig:
{
meta: {}, // Config metadata (version tracking)
auth: {}, // Auth profiles and provider credentials
env: {}, // Environment variables and shell env import
wizard: {}, // Onboarding wizard state
diagnostics: {}, // Diagnostics, OpenTelemetry, cache tracing
logging: {}, // Log levels, file output, redaction
update: {}, // Auto-update channel and check interval
browser: {}, // Browser automation (CDP, profiles, headless)
ui: {}, // UI theme, assistant name/avatar
skills: {}, // Skill loading, allowlists, per-skill config
plugins: {}, // Plugin loading, allow/deny lists, slots
models: {}, // Custom model providers, Bedrock discovery
nodeHost: {}, // Node host browser proxy settings
agents: {}, // Agent definitions, defaults, personality
deploymentTarget: {}, // Canonical hosting target (local/cloud/remote)
linkedAccounts: {}, // Canonical linked account inventory
serviceRouting: {}, // Canonical per-capability routing
tools: {}, // Tool profiles, web search/fetch, exec, media
bindings: [], // Agent-to-channel routing rules
broadcast: {}, // Multi-agent broadcast configuration
audio: {}, // Audio settings (placeholder)
messages: {}, // Response prefix, queue, TTS, debounce
commands: {}, // Command toggles (bash, config, debug)
approvals: {}, // Exec approval forwarding to chat channels
session: {}, // Session-level configuration
web: {}, // WebSocket/WhatsApp web provider settings
cron: {}, // Cron job scheduling
hooks: {}, // Webhook hooks, Gmail integration
discovery: {}, // mDNS and wide-area service discovery
talk: {}, // ElevenLabs voice/Talk mode
gateway: {}, // Gateway server (port, bind, TLS, auth)
memory: {}, // Memory backend (builtin vs qmd)
embedding: {}, // Local embedding model (GGUF, GPU layers)
database: {}, // Database provider (PGLite or Postgres)
cloud: {}, // Cloud integration (remote provisioning)
x402: {}, // HTTP payment protocol
media: {}, // Media generation (image, video, audio, vision)
connectors: {}, // Messaging connectors (Telegram, Discord, etc.)
channels: {}, // [deprecated] Use connectors instead
mcp: {}, // MCP server configuration
registry: {}, // ERC-8004 agent registry
features: {}, // Feature flags (auto-enable plugins)
customActions: [], // User-defined custom actions
}
Agents are defined under agents.list. The agents.defaults section provides shared defaults.
{
agents: {
defaults: {
model: { primary: "anthropic/claude-sonnet-4.6" },
workspace: "~/projects/my-agent",
thinkingDefault: "medium",
timeoutSeconds: 120,
maxConcurrent: 1,
},
list: [
{
id: "mila",
default: true,
name: "Mila",
model: "anthropic/claude-opus-4.7",
workspace: "~/projects/mila-workspace",
// Personality (set during onboarding)
bio: ["A helpful AI assistant"],
system: "You are Mila, a thoughtful assistant.",
style: { all: ["concise", "friendly"] },
adjectives: ["helpful", "creative"],
// Identity for display
identity: { name: "Mila" },
// Per-agent tool overrides
tools: {
profile: "standard",
exec: { security: "allowlist" },
},
// Per-agent sandbox settings
sandbox: {
mode: "non-main",
workspaceAccess: "ro",
scope: "session",
},
},
],
},
}
| Field | Type | Description |
|---|---|---|
id | string | Unique agent identifier (required) |
default | boolean | Mark as the default agent |
name | string | Display name |
model | string | { primary, fallbacks[] } | Model selection with optional fallbacks |
workspace | string | Working directory for agent runs |
skills | string[] | Allowlist of skills (omit for all, empty for none) |
bio | string[] | Agent bio lines |
system | string | System prompt |
style | { all?, chat?, post? } | Communication style rules |
identity | object | Display identity (name, etc.) |
tools | AgentToolsConfig | Per-agent tool policy overrides |
sandbox | object | Sandbox isolation settings |
heartbeat | object | Periodic background heartbeat runs |
memorySearch | MemorySearchConfig | Per-agent memory search overrides |
agents.defaults controls global behavior for all agents:
{
agents: {
defaults: {
model: { primary: "anthropic/claude-sonnet-4.6", fallbacks: ["openai/gpt-5"] },
workspace: "~/agent-workspace",
thinkingDefault: "medium", // off | minimal | low | medium | high | xhigh
verboseDefault: "off", // off | on | full
elevatedDefault: "off", // off | on | ask | full
blockStreamingDefault: "off", // off | on
timeoutSeconds: 120,
maxConcurrent: 1,
userTimezone: "America/New_York",
timeFormat: "auto", // auto | 12 | 24
// Heartbeat (periodic background runs)
heartbeat: {
every: "30m",
model: "anthropic/claude-haiku-4-5-20251001",
target: "last",
},
// Sandbox defaults
sandbox: {
mode: "non-main",
workspaceAccess: "ro",
scope: "session",
docker: {
image: "node:20-slim",
network: "none",
},
},
// Sub-agent defaults
subagents: {
maxConcurrent: 1,
archiveAfterMinutes: 60,
model: "anthropic/claude-haiku-4-5-20251001",
},
},
},
}
The simplest way to configure models is through agents.defaults.model:
{
agents: {
defaults: {
model: {
primary: "anthropic/claude-sonnet-4.6",
fallbacks: ["openai/gpt-5", "groq/openai/gpt-oss-120b"],
},
},
},
}
The models section at the top level lets you define custom providers, override model definitions, and configure Bedrock:
{
models: {
// "merge" (default) adds to built-in providers; "replace" uses only what's defined here
mode: "merge",
// Quick model aliases set during onboarding
small: "claude-haiku",
large: "claude-sonnet-4-6",
// Custom or self-hosted providers
providers: {
"my-provider": {
baseUrl: "https://api.example.com/v1",
apiKey: "<OPENAI_API_KEY>",
api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai | bedrock-converse-stream
models: [
{
id: "my-model-v1",
name: "My Model v1",
reasoning: false,
input: ["text", "image"],
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
contextWindow: 200000,
maxTokens: 8192,
},
],
},
},
// AWS Bedrock model discovery
bedrockDiscovery: {
enabled: true,
region: "us-east-1",
providerFilter: ["anthropic", "meta"],
refreshInterval: 3600,
},
},
}
Each custom provider can specify an authentication mode:
| Mode | Description |
|---|---|
api-key | Static API key (default) |
aws-sdk | AWS SDK credentials (for Bedrock) |
oauth | Refreshable OAuth credentials |
token | Static bearer token |
Plugins extend Eliza with connectors, providers, and feature capabilities.
{
plugins: {
enabled: true, // Master switch
allow: ["telegram", "anthropic"], // Allowlist (plugin short ids)
deny: ["experimental"], // Denylist (takes priority over allow)
// Per-plugin configuration
entries: {
telegram: {
enabled: true,
config: { /* plugin-specific */ },
},
browser: {
enabled: false, // Disable a specific plugin
},
},
// Plugin loading
load: {
paths: ["/path/to/custom-plugin"], // Additional plugin paths
},
// Slot assignments
slots: {
memory: "builtin", // Which plugin owns the memory slot ("none" disables)
},
},
}
Eliza automatically enables plugins based on your configuration. You do not need to manually add plugins to the allowlist in most cases.
Connector plugins are auto-enabled when a connector is configured with credentials. Connectors marked with * are upstream elizaOS plugins not included in the Eliza bundled registry — they must be installed first (eliza plugins install <package>):
| Connector | Plugin | Auto-Enable Trigger |
|---|---|---|
telegram | @elizaos/plugin-telegram | connectors.telegram.botToken |
discord | @elizaos/plugin-discord | connectors.discord.token (or botToken/apiKey) |
slack | @elizaos/plugin-slack | connectors.slack.botToken |
twitter * | @elizaos/plugin-x | connectors.twitter.apiKey |
whatsapp | @elizaos/plugin-whatsapp | connectors.whatsapp.authDir (or authState, sessionPath, or accounts with authDir) |
signal | @elizaos/plugin-signal | connectors.signal.account (or httpUrl, httpHost, httpPort, cliPath, or accounts with enabled entries) |
farcaster | @elizaos/plugin-farcaster | connectors.farcaster.apiKey (or token/botToken) |
matrix | @elizaos/plugin-matrix | connectors.matrix.token (or botToken/apiKey) |
nostr | @elizaos/plugin-nostr | connectors.nostr.token (or botToken/apiKey); actual auth uses NOSTR_PRIVATE_KEY env var |
msteams | @elizaos/plugin-msteams | connectors.msteams.botToken (or token/apiKey) |
googlechat | @elizaos/plugin-google-chat | connectors.googlechat.apiKey (or token/botToken) |
imessage | @elizaos/plugin-imessage | connectors.imessage.cliPath |
lens | @elizaos/plugin-lens | connectors.lens.apiKey (or token/botToken) |
mattermost | @elizaos/plugin-mattermost | connectors.mattermost.botToken (or token/apiKey) |
feishu | @elizaos/plugin-feishu | connectors.feishu.apiKey (or token/botToken) |
blooio | @elizaos/plugin-blooio | connectors.blooio.apiKey (or token/botToken) |
twitch | @elizaos/plugin-twitch | connectors.twitch.accessToken or clientId or enabled: true |
wechat | @elizaos/plugin-wechat | connectors.wechat.apiKey (or accounts with apiKey) |
Provider plugins are auto-enabled when the corresponding API key environment variable is set:
| Env Variable | Plugin |
|---|---|
ANTHROPIC_API_KEY / CLAUDE_API_KEY | @elizaos/plugin-anthropic |
OPENAI_API_KEY | @elizaos/plugin-openai |
AI_GATEWAY_API_KEY / AIGATEWAY_API_KEY | @elizaos/plugin-vercel-ai-gateway |
GOOGLE_API_KEY / GOOGLE_GENERATIVE_AI_API_KEY | @elizaos/plugin-google-genai |
GOOGLE_CLOUD_API_KEY | @elizaos/plugin-google-antigravity |
GROQ_API_KEY | @elizaos/plugin-groq |
XAI_API_KEY / GROK_API_KEY | @elizaos/plugin-xai |
OPENROUTER_API_KEY | @elizaos/plugin-openrouter |
OLLAMA_BASE_URL | @elizaos/plugin-ollama |
ZAI_API_KEY | @elizaos/plugin-zai |
DEEPSEEK_API_KEY | @elizaos/plugin-deepseek |
TOGETHER_API_KEY | @elizaos/plugin-together |
MISTRAL_API_KEY | @elizaos/plugin-mistral |
COHERE_API_KEY | @elizaos/plugin-cohere |
PERPLEXITY_API_KEY | @elizaos/plugin-perplexity |
ELIZAOS_CLOUD_API_KEY / ELIZAOS_CLOUD_ENABLED | @elizaos/plugin-elizacloud |
CUA_API_KEY / CUA_HOST | @elizaos/plugin-cua |
OBSIDIAN_VAULT_PATH | @elizaos/plugin-obsidian |
REPOPROMPT_CLI_PATH | @elizaos/plugin-repoprompt |
Feature plugins are auto-enabled via the features flag map:
{
features: {
browser: true,
cron: true,
shell: true,
imageGen: true,
tts: true,
webhooks: true,
computeruse: true,
},
}
| Feature Flag | Plugin |
|---|---|
browser | @elizaos/plugin-browser |
cua | @elizaos/plugin-cua |
obsidian | @elizaos/plugin-obsidian |
shell | @elizaos/plugin-shell |
imageGen | @elizaos/plugin-image-generation |
tts | @elizaos/plugin-tts |
stt | @elizaos/plugin-stt |
agentSkills | @elizaos/plugin-agent-skills |
commands | @elizaos/plugin-commands |
diagnosticsOtel | @elizaos/plugin-diagnostics-otel |
webhooks | @elizaos/plugin-webhooks |
gmailWatch | @elizaos/plugin-gmail-watch |
experience | built-in advanced capabilities |
form | built-in advanced capabilities |
x402 | @elizaos/plugin-x402 |
fal | @elizaos/plugin-fal |
suno | @elizaos/plugin-suno |
vision | @elizaos/plugin-vision |
computeruse | @elizaos/plugin-computeruse |
repoprompt | @elizaos/plugin-repoprompt |
Connectors integrate Eliza with messaging platforms. Configure them under connectors:
{
connectors: {
telegram: {
enabled: true,
botToken: "<TELEGRAM_BOT_TOKEN>",
// Additional connector-specific options
},
discord: {
enabled: true,
token: "<DISCORD_BOT_TOKEN>",
},
slack: {
enabled: true,
botToken: "<SLACK_BOT_TOKEN>",
appToken: "<SLACK_APP_TOKEN>",
},
whatsapp: {
enabled: true,
authDir: "~/.eliza/whatsapp-auth",
},
},
}
Route specific conversations to specific agents using bindings:
{
bindings: [
{
agentId: "support-bot",
match: {
channel: "telegram",
peer: { kind: "group", id: "-100123456" },
},
},
{
agentId: "dm-agent",
match: {
channel: "discord",
peer: { kind: "dm", id: "user-id" },
},
},
],
}
The gateway is the central server that handles WebSocket connections, HTTP API, and the Control UI.
{
gateway: {
port: 18789, // Default: 18789
mode: "local", // "local" | "remote"
bind: "loopback", // "auto" | "lan" | "loopback" | "tailnet" | "custom"
customBindHost: "10.0.0.5", // Only used when bind: "custom"
// TLS configuration
tls: {
enabled: true,
autoGenerate: true, // Auto self-signed cert
certPath: "/path/to/cert.pem",
keyPath: "/path/to/key.pem",
},
// Authentication
auth: {
mode: "token", // "token" | "password"
token: "<API_TOKEN>",
allowTailscale: false,
},
// Control UI (web dashboard)
controlUi: {
enabled: true,
basePath: "/",
allowedOrigins: ["https://my-domain.com"],
allowInsecureAuth: false,
},
// Config reload strategy
reload: {
mode: "hybrid", // "off" | "restart" | "hot" | "hybrid"
debounceMs: 300,
},
// Tailscale integration
tailscale: {
mode: "off", // "off" | "serve" | "funnel"
resetOnExit: false,
},
// Remote gateway connection
remote: {
url: "wss://remote-host:18789",
transport: "direct", // "ssh" | "direct"
token: "<REMOTE_AUTH_TOKEN>",
sshTarget: "user@host",
sshIdentity: "~/.ssh/id_ed25519",
},
// HTTP API endpoints
http: {
endpoints: {
chatCompletions: { enabled: false },
responses: {
enabled: false,
maxBodyBytes: 20971520, // 20MB
},
},
},
// Trusted reverse proxies (for x-forwarded-for)
trustedProxies: ["172.17.0.1"],
},
}
| Mode | Behavior |
|---|---|
auto | Loopback if available, else all interfaces |
loopback | 127.0.0.1 only (default) |
lan | 0.0.0.0 — all interfaces |
tailnet | Tailnet IPv4 (100.64.0.0/10) if available, else loopback |
custom | User-specified IP via customBindHost |
The tools section controls tool availability, web search/fetch, exec permissions, media understanding, and more.
{
tools: {
profile: "standard", // Base tool profile
allow: ["web_search", "web_fetch"],
deny: ["dangerous_tool"],
alsoAllow: ["extra_tool"], // Merged into allow + profile allowlist
// Web search
web: {
search: {
enabled: true,
provider: "brave", // "brave" | "perplexity"
apiKey: "<BRAVE_API_KEY>",
maxResults: 5,
cacheTtlMinutes: 15,
},
fetch: {
enabled: true,
maxChars: 30000,
maxCharsCap: 50000,
timeoutSeconds: 30,
readability: true,
firecrawl: {
enabled: true,
apiKey: "<FIRECRAWL_API_KEY>",
},
},
},
// Exec tool
exec: {
host: "sandbox", // "sandbox" | "gateway" | "node"
security: "allowlist", // "deny" | "allowlist" | "full"
ask: "on-miss", // "off" | "on-miss" | "always"
timeoutSec: 60,
backgroundMs: 5000,
pathPrepend: ["/usr/local/bin"],
safeBins: ["cat", "ls", "echo"],
},
// Elevated exec
elevated: {
enabled: true,
},
// Media understanding
media: {
concurrency: 2,
image: {
enabled: true,
maxBytes: 10485760,
models: [
{ provider: "openai", model: "gpt-5" },
{ provider: "google", model: "gemini-2.5-flash" },
],
},
audio: { enabled: true },
video: { enabled: true },
},
// Sub-agent defaults
subagents: {
model: "anthropic/claude-haiku-4-5-20251001",
tools: { allow: ["web_search"], deny: [] },
},
},
}
{
logging: {
level: "error", // silent | fatal | error | warn | info | debug | trace
consoleLevel: "info", // Independent console log level
consoleStyle: "pretty", // "pretty" | "compact" | "json"
file: "/var/log/eliza.log",
redactSensitive: "tools", // "off" | "tools"
redactPatterns: ["sk-[a-zA-Z0-9]+"],
},
}
Eliza supports two database backends:
<Tabs> <Tab title="PGLite (default)"> Local embedded PostgreSQL with no external dependencies:```json5
{
database: {
provider: "pglite",
pglite: {
dataDir: "~/.eliza/workspace/.eliza/.elizadb",
},
},
}
```
```json5
{
database: {
provider: "postgres",
postgres: {
// Option 1: Connection string
connectionString: "postgresql://user:pass@localhost:5432/eliza",
// Option 2: Individual fields
host: "localhost",
port: 5432,
database: "eliza",
user: "eliza",
password: "<DB_PASSWORD>",
ssl: true,
},
},
}
```
{
memory: {
backend: "builtin", // "builtin" | "qmd"
citations: "auto", // "auto" | "on" | "off"
qmd: {
command: "qmd",
includeDefaultMemory: true,
paths: [
{ path: "~/notes", name: "Notes", pattern: "**/*.md" },
],
sessions: {
enabled: true,
exportDir: "~/.eliza/qmd-sessions",
retentionDays: 30,
},
update: {
interval: "30m",
debounceMs: 500,
onBoot: true,
embedInterval: "1h",
},
limits: {
maxResults: 10,
maxSnippetChars: 500,
maxInjectedChars: 10000,
timeoutMs: 5000,
},
},
},
}
Configure the local embedding model for vector memory search:
{
embedding: {
model: "nomic-embed-text-v1.5.Q5_K_M.gguf",
modelRepo: "nomic-ai/nomic-embed-text-v1.5-GGUF",
dimensions: 768,
gpuLayers: "auto", // number | "auto" | "max"
idleTimeoutMinutes: 30, // 0 = never unload
},
}
Configure browser automation via Chrome DevTools Protocol:
{
browser: {
enabled: true,
headless: false,
noSandbox: false, // Required for Linux containers
attachOnly: false, // Only attach, never launch
executablePath: "/usr/bin/google-chrome",
defaultProfile: "chrome",
evaluateEnabled: true, // Allow arbitrary JS evaluation
// Named browser profiles
profiles: {
chrome: {
cdpPort: 9222,
driver: "eliza",
color: "#FF4500",
},
remote: {
cdpUrl: "ws://remote-host:9222",
},
},
snapshotDefaults: {
mode: "efficient",
},
},
}
Configure image, video, audio generation, and vision:
{
media: {
image: {
enabled: true,
mode: "own-key", // "cloud" | "own-key"
provider: "fal", // "cloud" | "fal" | "openai" | "google" | "xai"
defaultSize: "1024x1024",
fal: { apiKey: "<FAL_API_KEY>", model: "flux/schnell" },
},
video: {
enabled: true,
mode: "own-key",
provider: "fal",
fal: { apiKey: "<FAL_API_KEY>" },
},
audio: {
enabled: true,
mode: "own-key",
provider: "suno",
suno: { apiKey: "<SUNO_API_KEY>" },
},
vision: {
enabled: true,
provider: "openai",
openai: { apiKey: "<OPENAI_API_KEY>", model: "gpt-5" },
},
},
}
{
messages: {
responsePrefix: "[{model}]", // Template: {model}, {provider}, {thinkingLevel}, {identityName}
ackReaction: "eyes", // Emoji reaction on inbound messages (empty disables)
ackReactionScope: "group-mentions", // "group-mentions" | "group-all" | "direct" | "all"
removeAckAfterReply: false,
// Message queue behavior
queue: {
mode: "steer", // steer | followup | collect | steer-backlog | steer+backlog | queue | interrupt
debounceMs: 1500,
cap: 20,
drop: "old", // old | new | summarize
},
// Text-to-speech
tts: {
auto: "off", // off | always | inbound | tagged
provider: "elevenlabs", // elevenlabs | openai | edge
elevenlabs: {
voiceId: "21m00Tcm4TlvDq8ikWAM",
modelId: "eleven_turbo_v2_5",
},
maxTextLength: 5000,
timeoutMs: 30000,
},
},
}
Hooks enable webhook integrations and Gmail watching:
{
hooks: {
enabled: true,
path: "/hooks",
token: "<WEBHOOK_TOKEN>",
maxBodyBytes: 1048576,
// Webhook-to-agent mappings
mappings: [
{
match: { path: "/github", source: "github" },
action: "agent",
sessionKey: "github-events",
messageTemplate: "GitHub event: {{body}}",
},
],
// Gmail integration
gmail: {
account: "[email protected]",
label: "INBOX",
includeBody: true,
},
// Internal agent event hooks
internal: {
enabled: true,
handlers: [
{ event: "session:start", module: "./hooks/on-start.js" },
],
entries: {
"my-hook": { enabled: true, env: { KEY: "value" } },
},
},
},
}
Configure Model Context Protocol (MCP) servers:
{
mcp: {
servers: {
filesystem: {
type: "stdio",
command: "bunx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user"],
},
"remote-server": {
type: "sse",
url: "https://mcp.example.com/sse",
headers: { Authorization: "Bearer token" },
timeoutInMillis: 30000,
},
},
},
}
{
cloud: {
enabled: false,
provider: "elizacloud",
baseUrl: "https://elizacloud.ai/api/v1",
inferenceMode: "byok", // "cloud" | "byok" | "local"
autoProvision: false,
bridge: {
reconnectIntervalMs: 3000,
maxReconnectAttempts: 20,
heartbeatIntervalMs: 30000,
},
backup: {
autoBackupIntervalMs: 3600000, // 1 hour
maxSnapshots: 10,
},
},
}
{
update: {
channel: "stable", // "stable" | "beta" | "nightly"
checkOnStart: true,
checkIntervalSeconds: 14400, // 4 hours
},
}
{
diagnostics: {
enabled: false,
flags: ["telegram.http"], // Ad-hoc diagnostic flags
otel: {
enabled: true,
endpoint: "https://otel.example.com",
protocol: "http/protobuf", // "http/protobuf" | "grpc"
serviceName: "eliza",
traces: true,
metrics: true,
logs: true,
sampleRate: 1.0,
flushIntervalMs: 30000,
},
cacheTrace: {
enabled: false,
filePath: "/tmp/cache-trace.jsonl",
includeMessages: true,
includePrompt: false,
includeSystem: false,
},
},
}
{
cron: {
enabled: true,
store: "~/.eliza/cron-store.json",
maxConcurrentRuns: 3,
},
}
{
discovery: {
mdns: {
mode: "minimal", // "off" | "minimal" | "full"
},
wideArea: {
enabled: false,
domain: "eliza.internal",
},
},
}
{
talk: {
voiceId: "21m00Tcm4TlvDq8ikWAM",
modelId: "eleven_turbo_v2_5",
outputFormat: "mp3_44100_128",
interruptOnSpeech: true,
voiceAliases: {
narrator: "yoZ06aMxZJJ28mfd3POQ",
},
},
}
{
ui: {
seamColor: "#FF4500",
theme: "eliza", // eliza | qt314 | web2000 | programmer | haxor | psycho
assistant: {
name: "Mila",
avatar: "https://example.com/avatar.png",
},
},
}
Configure multi-profile authentication with cooldown/backoff:
{
auth: {
profiles: {
"anthropic-main": {
provider: "anthropic",
mode: "api_key", // "api_key" | "oauth" | "token"
email: "[email protected]",
},
},
order: {
anthropic: ["anthropic-main", "anthropic-backup"],
},
cooldowns: {
billingBackoffHours: 5,
billingMaxHours: 24,
failureWindowHours: 24,
},
},
}
Forward exec approval requests to chat channels:
{
approvals: {
exec: {
enabled: true,
mode: "session", // "session" | "targets" | "both"
targets: [
{ channel: "telegram", to: "123456789" },
],
},
},
}
{
skills: {
allowBundled: ["web", "code"], // Only load these bundled skills
denyBundled: ["experimental"], // Block specific bundled skills
load: {
extraDirs: ["~/my-skills"], // Additional skill directories
watch: true, // Watch for changes
watchDebounceMs: 500,
},
install: {
preferBrew: false,
nodeManager: "npm", // "npm" | "yarn" | "bun"
},
entries: {
"my-skill": {
enabled: true,
apiKey: "<OPENAI_API_KEY>",
env: { CUSTOM_VAR: "value" },
config: { maxRetries: 3 },
},
},
},
}
Toggle CLI and chat commands:
{
commands: {
native: "auto", // Enable native command registration
nativeSkills: "auto",
text: true, // Enable text command parsing
bash: false, // Allow bash command (!)
bashForegroundMs: 2000,
config: false, // Allow /config command
debug: false, // Allow /debug command
restart: false, // Allow restart commands
useAccessGroups: true,
},
}
Key environment variables that affect Eliza behavior:
| Variable | Purpose |
|---|---|
ELIZA_STATE_DIR | Override state directory (~/.eliza) |
ELIZA_CONFIG_PATH | Override config file path directly |
ELIZA_OAUTH_DIR | Override OAuth credentials directory |
| Variable | Default | Purpose |
|---|---|---|
ELIZA_API_PORT | 31337 | API + WebSocket port. Used in dev mode (bun run dev) where the API and UI run on separate ports. In production (eliza start) the API is served on ELIZA_PORT instead |
ELIZA_PORT | 2138 | Dashboard (Web UI) port. In production this port also serves the API. In dev mode this port is the Vite dev server only |
ELIZA_GATEWAY_PORT | 18789 | Gateway port |
ELIZA_HOME_PORT | 2142 | Home Dashboard port |
ELIZA_WECHAT_WEBHOOK_PORT | 18790 | WeChat Webhook port |
# Custom ports
ELIZA_GATEWAY_PORT=19000 ELIZA_PORT=3000 eliza start
| Variable | Provider |
|---|---|
ANTHROPIC_API_KEY | Anthropic (Claude) |
OPENAI_API_KEY | OpenAI (GPT) |
AI_GATEWAY_API_KEY | Vercel AI Gateway |
GOOGLE_API_KEY | Google Gemini |
GROQ_API_KEY | Groq |
XAI_API_KEY | xAI (Grok + Twitter/X) |
OPENROUTER_API_KEY | OpenRouter (200+ models via one key) |
OLLAMA_BASE_URL | Ollama (local) |
| Variable | Purpose |
|---|---|
BRAVE_API_KEY | Brave Search (web search tool) |
FIRECRAWL_API_KEY | Firecrawl (web fetch fallback) |
ELEVENLABS_API_KEY | ElevenLabs (TTS and Talk mode) |
FAL_KEY | FAL.ai (image/video generation) |
See the Model Providers page for a full list of supported providers.
Eliza provides CLI commands to inspect configuration without editing JSON directly:
# Configuration guidance (common env vars and usage)
eliza configure
# Read a config value (dot-notation)
eliza config get agents.defaults.model
eliza config get gateway.port
# Print the resolved config file path
eliza config path
# Display all config values grouped by section
eliza config show
eliza config show --all # Include advanced/hidden fields
eliza config show --json # Raw JSON output
To change values, edit ~/.eliza/eliza.json directly (it supports JSON5 with comments).
A complete configuration showing the most common options:
{
// Metadata
meta: { lastTouchedVersion: "1.0.0" },
// Environment variables
env: {
ANTHROPIC_API_KEY: "<ANTHROPIC_API_KEY>",
},
// Logging
logging: { level: "info", consoleStyle: "pretty" },
// Agent configuration
agents: {
defaults: {
model: { primary: "anthropic/claude-sonnet-4.6" },
workspace: "~/agent-workspace",
thinkingDefault: "medium",
sandbox: { mode: "non-main" },
},
list: [
{
id: "mila",
default: true,
name: "Mila",
bio: ["A capable AI assistant"],
system: "You are Mila.",
},
],
},
// Gateway
gateway: {
port: 18789,
bind: "loopback",
auth: { mode: "token" },
},
// Connectors
connectors: {
telegram: { botToken: "<TELEGRAM_BOT_TOKEN>" },
},
// Tools
tools: {
exec: { security: "allowlist" },
web: {
search: { enabled: true, provider: "brave" },
},
},
// Feature flags
features: {
browser: true,
cron: true,
},
// Update channel
update: { channel: "stable" },
}