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