Configuration
Environment variables, YAML config files, and deployment options for ID Agents
Configuration#
ID Agents is configured through environment variables and YAML deployment files. Environment variables control global settings like database connections and API keys. YAML files define teams, agents, and their capabilities.
Environment Variables#
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | No | PostgreSQL connection string (SQLite used by default if not set) |
ANTHROPIC_API_KEY | No | Anthropic API key (not needed with Claude Max — run claude login instead) |
CLAUDE_MODEL | No | Default Claude model (e.g., claude-opus-4-6) |
OPENAI_API_KEY | No | OpenAI API key (not needed if you use codex login OAuth) |
OWS_REGISTRAR_WALLET | No | OWS wallet name for onchain signing (recommended over raw key) |
ID_REGISTRAR_PRIVATE_KEY | No | Wallet private key for onchain registration (fallback if OWS not used) |
PUBLIC_BASE_URL | No | Public URL base for agents (e.g., https://idbot.live) |
MANAGER_PORT | No | Manager port (default: 4100) |
Set these in a .env file at the project root or export them in your shell environment. Environment variables take precedence over config file values.
Agent Environment Variables#
Each agent process receives these environment variables automatically at deploy time:
| Variable | Description |
|---|---|
ID_AGENT_PORT | The agent's own HTTP port (e.g., 4101) |
ID_AGENT_NAME | The agent's name as defined in the YAML config |
ID_AGENT_ALIAS | The agent's alias (often same as name) |
ID_TEAM | The team name the agent belongs to |
MANAGER_URL | URL of the manager daemon (e.g., http://localhost:4100) |
These are used by skills (e.g., the inter-agent skill uses ID_AGENT_PORT to call /talk-to on the agent's own port).
YAML Configuration#
YAML config files are infrastructure-only -- they define what to deploy and where, not what agents should think or do. Agent personality, role instructions, and behavioral prompts live in template files (see Agent Templates below).
Deploy multiple agents from a single YAML config file. Use /deploy path/to/config.yaml from the CLI.
Minimal Example#
team: myteam
defaults:
runtime: claude-code-cli
skills: [identity, inter-agent, catalog, task-discipline]
agents:
- name: coder
workingDirectory: /path/to/project
heartbeat: 86400
Full Example#
version: "1.0"
team: production-team
parameters:
- name: model_tier
default: sonnet
onchain:
chainId: 8453
registryAddress: "0x92DF3A4CB6827Bf199FdAd429B36622f0C8167F0"
registrarAddress: "0xa6D23f27D3b1780B12488482a008cB3c3787135f"
register: false
defaults:
local: true
runtime: claude-code-cli
model: claude-opus-4-6
skills:
- identity
- inter-agent
- catalog
- task-discipline
agents:
- name: lead
workingDirectory: /path/to/project
heartbeat: 86400
domain: lead.agent-1.xid.eth
tokenId: "0xabcd..."
- name: dev-frontend
workingDirectory: /path/to/frontend
skills: [code-review-skill]
- name: dev-backend
workingDirectory: /path/to/backend
Note: The
claudeMdfield has been removed from YAML config. Agent personality and role instructions now come from agent template files.
Top-Level Fields#
version#
Required. Configuration format version. Currently "1.0".
team#
Team or namespace for the deployment. Defaults to default.
parameters#
Define substitution variables using ${name} syntax throughout the config:
parameters:
- name: environment
default: development
- name: model_tier
default: haiku
team: project-${environment}
agents:
- name: worker-${environment}
model: claude-${model_tier}-4-5-20251001
Each parameter accepts name (required), default, and description fields.
onchain#
Configuration for onchain agent registration:
| Field | Required | Description |
|---|---|---|
chainId | Yes | EVM chain ID (8453 for Base) |
registryAddress | Yes | Agent registry contract address |
registrarAddress | No | Registrar contract address |
register | No | Default registration setting for all agents |
defaults#
Default settings applied to all agents unless overridden at the agent level:
| Field | Type | Description |
|---|---|---|
local | Boolean | Run agents as local processes (default: true) |
runtime | String | Default runtime (claude-code-cli, codex, or cursor-cli) |
model | String | Default LLM model |
skills | Array | Default skills deployed to each agent (runtime-aware location) |
The task-discipline skill is recommended as a default -- it ensures agents use the /tasks lifecycle for all non-trivial work, making the team auditable.
Agent Configuration#
Each agent in the agents array supports these fields:
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | -- | Agent name (unique within team, validated -- see Name Validation) |
model | No | From defaults | LLM model to use |
runtime | No | From defaults | Agent runtime |
skills | No | From defaults | Skills deployed to agent (merged with defaults) |
heartbeat | No | -- | Heartbeat interval in seconds (agent reads HEARTBEAT.md for its checklist) |
address | No | -- | Ethereum address (links to .env file) |
register | No | From onchain | Register agent onchain |
domain | No | -- | ENS domain (preserved across redeploys) |
tokenId | No | -- | Namehash of the ENS domain |
workingDirectory | No | -- | Working directory for the agent |
Name Validation#
Agent names are validated at creation time. The following are rejected:
- Reserved words -- names that conflict with CLI commands or system identifiers
- Shell wildcards -- names containing
*,?, or glob characters - Flag-prefix -- names starting with
-or-- - Length -- names that are empty or exceed the maximum length
Use lowercase alphanumeric names with hyphens (e.g., dev-frontend, lead, auditor).
Runtimes#
ID Agents supports multiple runtimes. Set the runtime at the defaults level or per agent.
| Runtime | CLI command | Auth | Description |
|---|---|---|---|
claude-code-cli | claude | claude login (Pro/Max subscription) or ANTHROPIC_API_KEY | Default. Uses Claude Code CLI with full tool access and session support. |
codex | codex exec | codex login (OAuth) or OPENAI_API_KEY env var | Uses OpenAI Codex CLI with --json for structured output. Supports GPT-5.4 and other OpenAI models. |
cursor-cli | cursor-agent | cursor-agent login or CURSOR_API_KEY env var | Cursor Agent CLI with stream-json output; default model sonnet-4 when not overridden. Accepts Claude- and OpenAI-style model IDs. |
Mixed-Runtime Team#
You can run some agents on Claude, others on Codex, and others on Cursor in the same team:
version: "1.0"
team: mixed-team
defaults:
runtime: claude-code-cli
model: claude-opus-4-6
agents:
- name: architect
runtime: claude-code-cli
description: "System design and architecture"
- name: coder
runtime: codex
model: gpt-5.4
description: "Implementation and code generation"
- name: reviewer
runtime: claude-code-cli
description: "Code review and quality"
All agents share the same REST-AP protocol regardless of runtime, so inter-agent communication works seamlessly across runtimes.
Runtime-Aware Conventions#
Templates and skills deploy to runtime-native locations. The framework detects the runtime and uses the correct paths automatically:
| Convention | Claude Code | Codex | Cursor |
|---|---|---|---|
| Agent template directory | .claude/agents/{name}/ | .agents/{name}/ | .cursor/agents/{name}/ |
| Agent template file (simple) | .claude/agents/{name}.md | .agents/{name}.md | .cursor/agents/{name}.md |
| Skills directory | .claude/skills/ | .agents/skills/ | .cursor/skills/ |
| Personality / role file | CLAUDE.md | AGENTS.md | AGENTS.md |
| Heartbeat checklist | HEARTBEAT.md | HEARTBEAT.md | HEARTBEAT.md |
When you create a template for an agent, place it in the directory matching your runtime. If your team uses mixed runtimes, each agent reads from its own runtime's conventions.
Agent Templates#
Agent personality, role instructions, and behavioral configuration come from template files, not from the YAML config. This separates infrastructure (YAML) from identity (templates).
How Templates Work#
At spawn time, the framework looks for a template matching the agent's name:
- Directory template --
.claude/agents/{name}/(Claude),.agents/{name}/(Codex), or.cursor/agents/{name}/(Cursor). The entire directory is recursively overlaid onto the agent's working directory, copying skills, hooks, memory, and everything else. - File template --
.claude/agents/{name}.md(Claude),.agents/{name}.md(Codex), or.cursor/agents/{name}.md(Cursor). A single Markdown file used as the agent's personality/role file.
Directory templates take precedence over file templates.
Two-Source Model#
Agent behavior comes from two sources:
-
Protocol defaults -- Framework-managed settings injected automatically. These include the
task-disciplinelifecycle (always on), identity information, and inter-agent communication setup. You don't need to configure these; they come from thedefaults.skillslist in your YAML config. -
Agent role file -- The agent's personality and domain instructions, provided by you via a template. For Claude agents this is
CLAUDE.md; for Codex and Cursor agents it'sAGENTS.md.
The YAML config handles only infrastructure: name, working directory, model, runtime, heartbeat interval, and skills list.
Example Template Structure#
.claude/agents/coder/
├── CLAUDE.md # Agent personality and role instructions
├── skills/
│ └── code-review/
│ └── SKILL.md # Custom skill
├── hooks/
│ └── pre-commit.sh # Custom hook
└── memory/
└── MEMORY.md # Seed memory
Everything in this directory is copied to the agent's workspace at deploy time.
Environment Variable References#
Use ${env:VAR_NAME} syntax to reference environment variables in config files:
defaults:
model: ${env:CLAUDE_MODEL}
Org Chart#
Define team structure so agents know who their peers are and who to coordinate with. The org chart is declared under the org: key in your YAML config.
At deploy time, ID Agents generates an ORG_CHART.md file in the shared team folder and injects each agent's group role and tags into their identity skill. Agents use this to understand reporting lines and find the right person to coordinate with.
Groups#
Groups are recursive -- they can nest infinitely. Each group can have a lead, members, description, and nested groups:
org:
groups:
engineering:
lead: lead
description: "Core engineering team"
members: [lead, dev-frontend, dev-backend]
groups:
frontend:
lead: dev-frontend
description: "Frontend squad"
members: [dev-frontend]
backend:
lead: dev-backend
description: "Backend squad"
members: [dev-backend]
security:
lead: auditor
description: "Security and compliance"
members: [auditor, pen-tester]
All group fields are optional except the group name itself. Nest groups inside any group to create sub-teams.
Tags#
Tags are flat labels mapped to a list of agent names. Use them for cross-cutting concerns that don't fit a hierarchy:
org:
tags:
on-call: [lead, dev-backend]
code-review: [lead, dev-frontend, dev-backend]
ops: [dev-backend, auditor]
Generated Org Chart#
At deploy time, the config above produces an ORG_CHART.md in the shared team folder:
# Org Chart
## engineering
Core engineering team
Lead: lead
Members: lead, dev-frontend, dev-backend
### frontend
Frontend squad
Lead: dev-frontend
Members: dev-frontend
### backend
Backend squad
Lead: dev-backend
Members: dev-backend
## security
Security and compliance
Lead: auditor
Members: auditor, pen-tester
## Tags
- on-call: lead, dev-backend
- code-review: lead, dev-frontend, dev-backend
- ops: dev-backend, auditor
Each agent's identity skill is also updated with their own group role and tags, so they can reference their position without reading the full chart.
Scheduling#
Define automated schedules in your YAML config to send recurring messages to agents. There are two schedule types: heartbeats (interval-based) and calendar events (time-of-day-based).
Heartbeats#
Heartbeats use an agent-driven model. There are two ways to configure them:
1. Per-agent heartbeat field (recommended) -- Set the interval directly on the agent. The agent reads its own HEARTBEAT.md file to determine what to do on each tick:
agents:
- name: contracts
workingDirectory: /path/to/contracts
heartbeat: 600 # seconds -- just a number
The agent's HEARTBEAT.md file contains the checklist:
# Heartbeat Checklist
- Run security review on latest commits
- Check for open PRs that need review
- Verify test suite is passing
2. schedules array -- For more control over delivery and sender, define heartbeats under the schedules key:
schedules:
- type: heartbeat
every: 600
message: "Run security review on latest commits"
agents: [contracts]
delivery: internal
| Field | Required | Default | Description |
|---|---|---|---|
type | Yes | -- | Must be heartbeat |
every | Yes | -- | Interval in seconds between deliveries |
message | Yes | -- | Message sent to the agent(s) |
agents | Yes | -- | List of agent names to receive the message |
sender | No | heartbeat | Sender name shown on the message |
delivery | No | talk | Delivery mode: talk (conversational) or internal (non-conversational, no reply expected) |
Note: The per-agent
heartbeatfield is just the interval in seconds (a number), not an object. The old{interval, message}format is no longer used.HEARTBEAT_OKresponses are silently dropped.
Calendar Events#
Calendar events fire at specific times on specific days. Define them with type: calendar:
schedules:
- type: calendar
title: "Morning standup prompt"
time: "09:00"
days: "mon,tue,wed,thu,fri"
timezone: America/New_York
message: "Good morning. Summarize your current tasks and blockers."
agents: [lead, dev-frontend, dev-backend]
- type: calendar
title: "Monthly report"
time: "08:00"
date: "2026-04-01"
timezone: America/New_York
message: "Generate the monthly project report."
agents: [lead]
| Field | Required | Default | Description |
|---|---|---|---|
type | Yes | -- | Must be calendar |
title | No | -- | Human-readable name for the event |
time | Yes | -- | Time of day in HH:MM format (24-hour) |
days | No | -- | Comma-separated days of the week (e.g., mon,wed,fri). Use days or date, not both. |
date | No | -- | Specific date in YYYY-MM-DD format. Use date or days, not both. |
message | Yes | -- | Message sent to the agent(s) |
agents | Yes | -- | List of agent names to receive the message |
timezone | No | System default | IANA timezone (e.g., America/New_York, Europe/London) |
sender | No | schedule | Sender name shown on the message |
delivery | No | talk | Delivery mode: talk or internal |
Sender Field#
The sender field controls what name appears as the message author when the schedule fires:
- Heartbeats default to
heartbeat - Calendar events default to
schedule
Override with the sender field in YAML or the --sender flag in the CLI:
schedules:
- type: heartbeat
every: 300
message: "Check monitoring dashboards"
agents: [ops]
sender: "ops-monitor"
Delivery Modes#
| Mode | Description |
|---|---|
talk | Standard conversational delivery via the /talk endpoint. The agent processes the message and produces a reply. This is the default. |
internal | Non-conversational delivery. The message is injected as context but no reply is expected. Useful for background tasks like periodic reviews. |
Loop Prevention#
All scheduled messages (heartbeats and calendar events) are sent with the noAutoReply flag set. This prevents infinite loops where a scheduled message triggers an agent reply, which triggers another agent, and so on. Agents receiving a noAutoReply message will process it but will not automatically reply back to the sender.
Full Scheduling Example#
version: "1.0"
team: production
agents:
- name: contracts
description: "Smart contract security"
- name: x
description: "Social media engagement"
- name: lead
description: "Team lead"
schedules:
- type: heartbeat
every: 600
message: "Run security scan on recent commits"
agents: [contracts]
delivery: internal
- type: calendar
title: "X engagement"
time: "09:00"
days: "mon,tue,wed,thu,fri"
timezone: America/New_York
message: "Check X for relevant tweets and engage"
agents: [x]
- type: calendar
title: "Weekly review"
time: "17:00"
days: "fri"
timezone: America/New_York
message: "Produce the weekly team summary report"
agents: [lead]
sender: "weekly-review"
Schedules can also be managed at runtime using the /heartbeat and /calendar CLI commands (see CLI Reference).
Updating Your Team#
There are two ways to apply config changes to a running team:
/deploy <config> -- Nuke-and-recreate. Tears down all agents in the team and redeploys from scratch. Use this for clean deploys where you want a guaranteed fresh state.
/sync <config> -- Diff-based reconciliation. Compares the config against the running team, starts new agents, stops removed agents, and restarts only agents whose config changed. Agents with no changes are left running untouched.
Use /deploy when you want a clean slate (e.g., switching configs, debugging state issues). Use /sync for incremental updates (e.g., adding an agent, changing a model, updating a skill list) -- it's faster and avoids disrupting agents mid-task.
Config File Locations#
ID Agents looks for configuration files in this order:
- Path specified via CLI:
/deploy path/to/config.yaml - Team config:
configs/<team-name>.yaml - Default config:
configs/default.yaml