ADL — Agent Definition Language
Define custom agents, workflows, MCP assets, and HITL in YAML.
ADL (Agent Definition Language) is nui’s YAML schema for describing agents. Definitions live in ~/.nui/agents/*.yaml or are contributed by extensions. The UI form editor and headless CLI both use the same schema.
Minimal agent
id: my-agent
name: My Agent
description: A simple Claude Code agent
harness:
type: claude-code
model: claude-sonnet-4-6
systemPrompt: |
You are a helpful coding assistant.
Harness types
harness.type |
Description |
|---|---|
claude-code |
Anthropic Claude Code CLI |
pi |
Pi agent (pi --mode rpc) |
codex |
OpenAI Codex CLI |
opencode |
OpenCode CLI |
api |
In-process LLM (Anthropic, OpenAI, Gemini, OpenRouter, Ollama) |
docker |
Custom HTTP/SSE harness in a Docker container |
remote |
Remote HTTP/SSE harness (no lifecycle management) |
devcontainer |
Builtin CLI inside a nui-provisioned dev container |
ext:<extension>/<harness-id> |
Extension harness (stdio, TCP, or HTTP) |
API harness example
id: api-claude
name: API Claude
harness:
type: api
provider: anthropic
model: claude-sonnet-4-20250514
Set ANTHROPIC_API_KEY (and optionally ANTHROPIC_BASE_URL) in the environment.
Session harness override (allowedHarnesses)
Top-level harness is always the default runtime. For CLI agents, the New Session panel and CLI may swap harness.type among compatible CLI runtimes:
adl: "1.0"
id: portable-coder
name: Portable Coder
harness:
type: claude-code
model: claude-sonnet-4-6
allowedHarnesses:
- claude-code
- pi
| Rule | Behavior |
|---|---|
| Omitted | Any CLI harness (claude-code, pi, codex, opencode) is allowed when harness.type is itself a CLI harness |
| Present | Whitelist — override may only be a listed entry (use a single entry to pin) |
| Built-in CLI agents | Pinned to their matching harness (singleton list) |
Non-CLI defaults (api, docker, remote, devcontainer, ext:…) |
No CLI session override |
Override replaces harness.type only; other harness fields (model, env, permissions, sandbox) stay from the authored block. Per-step steps[].harness is never overridden.
nui run -a portable-coder --harness pi -m "Review README"
nui server -a portable-coder --harness pi --open
Extension harness example
id: echo-bot
name: Echo Bot
harness:
type: ext:corp-pack/echo
aiAssets — MCP, skills, rules, mentions
Reference extension contributions with ref::
aiAssets:
mcpServers:
- name: corp-tools
ref: ext:corp-pack/corp-tools
skills:
- name: deploy-checklist
ref: ext:corp-pack/deploy-checklist
rules:
- name: corp-guidelines
ref: ext:corp-pack/corp-guidelines
mentionProviders:
- ref: ext:corp-pack/corp-refs
Inline MCP servers (same schema as extensions):
aiAssets:
mcpServers:
- name: local-tools
command: ["npx", "-y", "my-mcp-server"]
env:
API_KEY: ${localEnv:MY_API_KEY}
Multi-step workflows
id: review-and-fix
name: Review and Fix
steps:
- id: review
harness:
type: claude-code
systemPrompt: Review the code and list issues.
outputs:
- name: issues
description: List of issues found
- id: fix
dependsOn: [review]
harness:
type: claude-code
inputs:
- from: review.issues
systemPrompt: Fix the issues from the review.
HITL (human-in-the-loop)
hitl:
mode: interactive
channels:
- nui-ui
- ext:hitl-demo/demo-slack
When mode: interactive, builtin harnesses receive an injected nui-hitl MCP server. Extension harnesses can call ask_user() via the Python SDK or the REST API. See HITL.
Sandbox
harness:
type: claude-code
sandbox: none # default — runs on host
# sandbox: bubblewrap # Linux only
# sandbox: docker # nui-managed container
Evals
evals:
- id: smoke
input: "Say hello"
graders:
- type: contains
value: hello
Run from CLI: nui agent eval my-agent or POST /api/agents/:id/evals/run.
Agent IDs from extensions
Extension-contributed agents are namespaced: ext:<extension>/<agent-id>. They appear in GET /api/agent-types alongside builtins and user agents.
Further reading
- ADL design doc — full schema in the repository
- ADL examples — workflow, API, docker, and more
- Harness protocols — wire formats for custom harnesses
- Extension API — contributing agents via extensions