Docs navigation

The agent format

A UAP agent is one YAML document — agent.uap.yaml — plus the files it references. Together they form a bundle: plain, committable, secret-free.

This page tours every component. The normative specification (grammar, canonical form, digests, adapter contract) lives in SPEC.md, with a machine-readable JSON Schema.

The document

From the smallest valid agent to every component in one document — the spec's Appendix A example — annotated section by section:

uap: 1 agent: name: Docs Helper description: Answers questions about the docs/ folder.
instructions: - name: core content: text: | You are the docs helper. Answer using the docs/ folder. Cite file paths. If unsure, say so.
Version & identity

Only uap and agent are required — with these two fields this is already a valid, installable bundle.

Inline content

Any content-bearing field takes content: { text: ... } inline or content: { file: uap/... } pointing at a sidecar file — exactly one of the two.

Instructions

The agent's standing guidance — what harnesses variously call the system prompt, CLAUDE.md, AGENTS.md, or rules. UAP models it as an ordered list of blocks with an activation mode, so one schema covers single-file harnesses and rules-directory harnesses alike:

instructions:
  - name: core                       # always active (default)
    content: { file: uap/instructions.md }

  - name: frontend-rules             # attached when matching files are touched
    description: Conventions for the web app
    activation: auto
    paths: ["apps/web/**"]
    content: { file: uap/rules/frontend.md }

  - name: release-checklist          # only when explicitly invoked
    activation: manual
    content: { file: uap/rules/release.md }

always · auto (with paths globs or a routing description) · manual — these map 1:1 onto Cursor's four rule types, and fold into a managed region of CLAUDE.md/AGENTS.md elsewhere with their scope preserved for a lossless round-trip.

Commands

Reusable prompts invoked by name (slash commands):

commands:
  - name: triage
    description: Triage an incoming bug report
    arguments_hint: "<issue-url>"
    content: { file: uap/commands/triage.md }

Bodies may use $ARGUMENTS (everything after the command) and $1$9 (positional). Adapters translate to their harness's substitution syntax or report the command emulated.

Subagents

Named delegates the main agent can hand tasks to:

subagents:
  - name: reviewer
    description: Deep code reviewer for risky diffs   # the routing signal
    model: { id: claude-opus-4-8 }
    tools: [read, grep, glob]                          # neutral tool names
    content: { file: uap/agents/reviewer.md }

tools uses harness-neutral names (read, bash, web_fetch, …); adapters map them to native tool names where the harness supports an allowlist.

Skills

References to skill packages — a directory with a SKILL.md plus supporting files, per the cross-harness Agent Skills convention:

skills:
  - source: ./uap/skills/lint-fixer          # local, in-bundle
  - source: registry:acme/summarize@^2.0     # registry (pinned range)
  - source: github:owner/repo/skills#main    # git hosts

MCP servers

The agent's tool connections. Transports: stdio, http, and legacy sse:

mcp_servers:
  - name: filesystem
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-filesystem", "."]

  - name: search
    transport: http
    url: https://search.example.com/mcp
    headers:
      Authorization: "Bearer ${SEARCH_TOKEN}"    # placeholder, never a value

Secrets — declared, never valued

Bundles are designed to be committed, so secret values are banned by the spec. Credentials appear only as ${NAME} placeholders, declared under secrets and resolved at install time (environment → local secrets file → prompt). The validator scans for real-looking credentials and fails the bundle if it finds any.

secrets:
  - name: SEARCH_TOKEN
    description: API token for the search MCP
    used_by: [mcp_servers/search]

Hooks, setup, permissions, env, files

The remaining components round out the agent's runtime shape:

hooks:                        # lifecycle commands
  - event: pre_tool_use
    matcher: bash
    run: { command: "./uap/hooks/guard.sh" }

setup:                        # one-time bootstrap (never auto-run)
  commands:
    - pnpm install

permissions:                  # tool rules: deny > ask > allow
  allow: [{ tool: bash, match: "pnpm *" }]
  deny:  [{ tool: bash, match: "rm -rf *" }]

env:                          # non-secret environment
  NODE_ENV: development

files:                        # verbatim extras
  - source: uap/files/ONBOARDING.md
    target: ONBOARDING.md

Format guarantees

  • Canonical form — fixed key order and emission rules mean two semantically equal documents are byte-identical.
  • Round-trip law — for every component an adapter declares native, pack(unpack(D)) ≡ D, verified by digest in the conformance suite.
  • Forward compatibility — unknown fields are preserved, never rejected; x-* keys and a namespaced extensions block carry harness-specific data.

See the full worked example — examples/showcase — an engineering agent using every component, then check where each piece lands per harness.