Skip to content

Config schema

Every field in agentx.json. Source of truth: src/daemon/config.ts and src/business/config.ts.

Environment variables are expanded inline: ${MY_TOKEN}process.env.MY_TOKEN. A .env file in the working directory is auto-loaded.

Top-level shape

json
{
  "node":          { "id": "...", "name": "...", "bind": "0.0.0.0:19900", "defaultAgent": "..." },
  "providers":     { "<provider>": { "apiKey": "", "defaultModel": "", "baseUrl": "" } },
  "agents":        { "<agentId>":  { ... } },
  "channels":      { "telegram": {...}, "whatsapp": {...}, "discord": {...}, "gitlab": {...} },
  "crons":         { "<cronId>":   { ... } },
  "services":      { "<serviceId>":{ ... } },
  "notifications": { ... },
  "mesh":          { ... },
  "business":      { ... }
}

node

FieldTypeDefaultPurpose
idstringShort slug identifying this node (used in mesh agent cards)
namestringHuman-readable node name
bindstring127.0.0.1:18800HTTP bind address. Use 0.0.0.0:… for mesh or multi-interface
defaultAgentstringAgent for endpoints that don't specify one (e.g. POST /ask)

providers

Keyed by provider name (claude, openai, ollama, …). Each entry:

FieldTypePurpose
apiKeystringUsed by sdk and orchestrator tiers
defaultModelstringModel id if the agent doesn't specify one
baseUrlstringOverride endpoint (Ollama, proxies)

agents.<id>

FieldTypeDefaultPurpose
namestringDisplay name
workspacestringDirectory with CLAUDE.md, skills, MCP config
tierclaude-code | sdk | orchestratorclaude-codeExecution strategy
providerstringFor sdk/orchestrator: which providers[] entry
modelstringModel id
systemPromptstringInline override (normally live in CLAUDE.md)
mentionsstring[][]@handles that route to this agent
maxConcurrentnumber1Parallel turns allowed
permissionModestringdefaultClaude Code permission mode (default, acceptEdits, plan, bypassPermissions)
queueModecollect | followup | dropcollectBehavior when messages arrive during a turn
heartbeat.enabledboolfalseEnable periodic in-session check-ins
heartbeat.intervalMinutesnumber30
heartbeat.promptstringstock prompt
heartbeat.channelstringheartbeatVirtual channel tag

channels.telegram

FieldTypeDefault
enabledboolfalse
accounts.<name>.tokenstringBot token (env expansion OK)
accounts.<name>.agentBindingstringAgent id this bot speaks for
policy.dmpair | blockpairDM policy
policy.groupmention-required | allmention-requiredGroup policy

channels.whatsapp

FieldTypeDefault
enabledboolfalse
sessionDirstring.agentx/whatsapp-sessions
defaultAgentstring
allowFromstring[]Contact allowlist
routes[].contact / .groupstringMatch
routes[].agentstringTarget agent

channels.discord

FieldType
enabledbool
tokenstring
agentBindingstring

channels.gitlab

FieldTypeDefault
enabledboolfalse
hoststringhttps://gitlab.com
webhookPortnumber18810
webhookSecretstring
tokenstringFallback API token
routes[].project / .agentstring
agentMappings[].agentIdstring
agentMappings[].gitlabUsernamesstring[][]
agentMappings[].keywordsstring[][]
agentMappings[].tokenstringPer-agent GitLab PAT

crons.<id>

FieldTypeDefault
enabledbooltrue
schedulestring5-field cron
timezonestringUTC
agentstring
promptstring
timeoutnumber600seconds
modelstring
onErrorstring | string[]logAny of log, notify, disable. See Journey 2
notify.channel / .chatId / .accountIdstringWhere failures get pushed

services.<id>

Deterministic handlers that intercept messages before agent routing — no LLM call for the match.

FieldType
namestringHuman label
triggers[].patternstring (regex)
triggers[].channelstringRestrict to a channel
allowedContactsstring[]Whitelist
agentstringDispatch target
promptstringKnown prompt (not user text)
schedulestringOptional cron — run on timer too
timezonestring
notify.channel / .chatId / .accountIdstringPush result

mesh

FieldTypeDefault
enabledboolfalse
peers[].urlstringe.g. http://100.x.x.x:19900
peers[].namestring
peers[].tokenstringShared secret (${MESH_TOKEN})
discoverystatic | mdnsstatic
healthCheck.intervalnumber60seconds
healthCheck.timeoutnumber10

notifications

Daemon-wide defaults for long-task notifications.

FieldTypeDefault
longTaskThresholdnumber30seconds; 0 disables
destination.channel / .chatId / .accountIdstring
on.taskComplete / on.taskError / on.taskQueuedbooltrue/true/false

business (optional)

See Journey 7 — Business layer for worked examples.

FieldTypeDefault
enabledboolfalse
timezonestringUTC
mainChannel.channel / .chatId / .accountIdstringDaily summary destination
workSource.typebacklog | gitlab | wikiTask source
workSource.pathstring.agentx/backlog.md (for backlog)
workSource.projectsstring[][] (for gitlab)Empty = all configured projects
workSource.globstring**/*.md (for wiki)
roles.<role>.titlestring
roles.<role>.responsibilitiesstring[][]
roles.<role>.sopPathstring
roles.<role>.kpisstring[][]
orgChart.<agentId>.rolestring
orgChart.<agentId>.reportsTostring
orgChart.<agentId>.schedule.daysday[]mon–fri
orgChart.<agentId>.schedule.start / .endHH:MM
orgChart.<agentId>.schedule.lunch.start / .endHH:MMOptional
orgChart.<agentId>.utilizationTargetnumber (0–1)0.8
workTickMinutesnumber15
idleQueueThresholdnumber0Skip work-tick if queue depth exceeds this

Environment variables

VariablePurpose
AGENTX_DEBUGComma-separated debug categories (webhook,cron,mesh,all)
MESH_TOKENShared secret between mesh peers (referenced as ${MESH_TOKEN} in agentx.json)
TG_*_BOT_TOKEN, DISCORD_*_TOKEN, GITLAB_*_TOKENConvention for channel secrets referenced via ${…}

Anonymized example

A full production-shaped config with tokens scrubbed lives at /examples/agentx.example.json. Use it as a starting point for multi-agent, multi-channel, cron + business deployments.

Released under the MIT License.