> ## Documentation Index
> Fetch the complete documentation index at: https://personal-f2f22caf.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How to add subagents support to your harness

> A guide for adding Harness Subagents support to an AI agent harness.

This guide walks through how to add subagents support to an AI agent harness. It covers the full lifecycle: discovering subagent files and syncing them into a catalog, adapting them into your harness, telling the parent agent about them, spawning the subagent when the parent delegates, and handling what comes back.

The core integration is the same regardless of your architecture. The implementation details vary based on two factors:

* **Where do subagent files live?** A locally-running harness can scan the filesystem. A cloud-hosted harness needs alternative discovery — an API, a registry or bundled assets.
* **How does your harness run a subagent?** You need a way to spawn a model session with a custom system prompt, a task input and an isolated context. Most harnesses have this internally already; the work is exposing it as delegation.

**Prerequisites**: Familiarity with the [Harness Subagents specification](https://personal-f2f22caf.mintlify.site/specification.md), which defines the subagent file format and the lifecycle.

## The core principle: delegation, not activation

Subagents invert the skills model. Skills activate *into* the current context; subagents run *outside* it:

| | Skills | Subagents |
| - | - | - |
| What the parent sees | Name + description | Name + description |
| What loads on use | Instructions into the current context | Body as system prompt of a new, isolated context |
| Who the output serves | The same conversation | The parent, via a report |
| Human in the loop | Yes (steering, approval) | None |

The isolation is the product. Search noise, long tool output and intermediate drafts stay inside the subagent; the parent's context only grows by the report. Everything in this guide serves that principle.

## Step 1: Discover subagent files

At session startup, find all available subagent files and load their metadata.

### Where to scan

Scan the harness-neutral location first. This is a convention this format proposes, modeled on `.agents/skills/`; it is not yet established elsewhere:

| Scope | Location |
| - | - |
| User | `~/.agents/agents/` |
| Project | `.agents/agents/` |

Then scan the harness-specific directories in addition. Existing harnesses scan:

| Harness | Location |
| - | - |
| Claude Code | `.claude/agents/` (project), `~/.claude/agents/` (user) |
| GitHub Copilot / VS Code | `.github/agents/` (workspace), `~/.copilot/agents/` (user) |
| Gemini CLI | `.gemini/agents/` (project), `~/.gemini/agents/` (user) |
| OpenCode | `.opencode/agents/` (project), `~/.config/opencode/agents/` (global) |

Subagents bundled with your harness form the base layer. When the same `name` appears in more than one layer, the most specific source wins: project-level files override user-level files, and both override what your harness provides. Log a warning when a collision occurs.

Practical scanning rules:

* Look for files ending in `.md` (or your harness's native extension)
* Skip directories that won't contain subagents, such as `.git/` and `node_modules/`
* Set reasonable bounds on depth and directory count

### Sync the catalog

Discovery is a sync, not a one-shot load. Persist what you load, attributed by source, and keep user and project subagents separate from the ones your harness provides. The catalog is the union of the layers; precedence decides which entry wins a shared `name`.

Sync each source independently, so the catalog mirrors what that source currently provides:

* The project provides A and B; your harness provides C. The catalog is A, B, C.
* The project changes and now provides A and D. After a sync, the catalog is A, C, D. B leaves with its source; C is untouched.

Removal is scoped to the source that stopped providing the subagent — a sync never touches entries from other sources. A harness update reconciles only your bundled subagents and never rewrites user or project entries.

Sync at startup at minimum. You may also track changes in `.agents/agents/` and sync automatically as files change; if you don't, tell the user when a sync is due. Knowing an update is required is useful even when it is applied manually.

### Trust considerations

Project-level subagent files come from the repository being worked on, which may be untrusted. Their bodies are instructions that will be run as a system prompt. Gate project-level discovery on a trust check, the same way you'd treat other instruction files in a repository.

## Step 2: Parse subagent files

For each discovered file, extract the frontmatter and the body.

### Frontmatter extraction

A subagent file has two parts: YAML frontmatter between `---` delimiters, and a Markdown body after the closing delimiter. To parse:

1. Find the opening `---` at the start of the file and the closing `---` after it.
2. Parse the YAML block between them. Extract `name` and `description` (required), plus any optional fields.
3. Everything after the closing `---`, trimmed, is the body — the system prompt you will spawn the subagent with.

### Lenient validation

Warn on issues but still load the subagent when possible:

* `name` doesn't match the file name → warn, load anyway
* `complexity` is missing → no warning needed; judge from the whole file. Outside the enum → warn, then treat as missing
* `tools` is neither a boolean nor an array of names → warn, treat as inherit. An empty array is valid and means `false`
* Unknown frontmatter fields → ignore (or keep them if your harness maps them; this is what `metadata` is for)
* `description` is missing or empty → skip the subagent (a description is essential for delegation), log the error
* YAML is completely unparseable → skip the subagent, log the error

Record diagnostics so they can be surfaced to the user, but don't block loading on cosmetic issues.

### What to store

At minimum, each subagent record needs:

| Field | Description |
| - | - |
| `name` | From frontmatter (or the file name) |
| `description` | From frontmatter |
| `complexity` | From frontmatter, or empty when omitted |
| `body` | The system prompt text |
| `tools` | From frontmatter — boolean or whitelist; `[]` is `false`, absent inherits |

Read the body at discovery time or at spawn time. Reading at spawn time picks up edits made between delegations.

## Step 3: Adapt the subagents into your harness

Once the files are parsed, adapting each subagent into your harness is your job, not the file's. The `complexity` field suggests how much capability the work needs; your harness is responsible for finding the model and reasoning effort that match it, from your own model lineup and policy.

### Mapping complexity to model and effort

The tier names describe the work, not a model size. Translate them into your own model lineup and effort controls. The values below are examples, and providers differ: effort values and defaults are model-dependent, so check the model's page.

| Tier | Model tendency | Effort tendency | Example mappings |
| - | - | - | - |
| `mundane` | Smallest, fastest model | None or lowest | OpenAI `reasoning.effort: none`/`minimal` where supported; a small local model |
| `routine` | Fast model | Low | OpenAI `reasoning.effort: low`; Claude `effort: low` |
| `interpreting` | Default model | Medium or high, per model | OpenAI `reasoning.effort: medium`; Claude `effort: medium` or `high` |
| `judgment` | Strong model | High | OpenAI `reasoning.effort: high`; Claude `effort: high` or `xhigh` |
| `critical` | Strongest available | Highest the model offers | OpenAI `reasoning.effort: xhigh` or `max`; Claude `effort: max` |

Read the description together with the tier. The tier is the big picture; the description adjusts it. A narrow, well-bounded `interpreting` subagent can get a smart, light-effort setup, while an open-ended one can get a stronger model at higher effort. Two subagents on the same tier may resolve differently.

When `complexity` is missing, do not assume a tier. Read the entire file, description and body, and choose the model and effort by judgment.

If the chosen model is not available (retired, not licensed, over quota), ask the user whether to continue or to select a model. The default is to inherit the parent's model. Whether and how you ask depends on your harness; a non-interactive harness can apply the default and log it.

The mapping is yours to make. Your model lineup, availability, latency budget and cost policy all belong in the decision, and the mapping can adapt per task: a harness may run an `interpreting` subagent on a stronger model when the delegation involves mutating state, or downgrade when usage caps are near. Complexity is a hint you consume, not a contract you owe the file.

> [!NOTE]
>
> Model identifiers are deliberately absent from the format. They don't port across harnesses, and they rot quickly. If your harness routes subagents across providers, expose that configuration through `metadata` keys of your own naming — the field exists for exactly this.

A note on heterogeneous models: any model that can run your agent loop — including small, fast, cheap ones — can host a subagent. Models that *can't* (OCR engines, transcribers, one-shot VLMs, batch classifiers) are not subagents; they are tools. Expose them through MCP servers or scripts, and let subagents and parents call them.

Treat the mapping as a living decision. Your model catalog changes over time — new models land, others retire — and a sync may bring in subagents written against an older lineup. Re-map the levels when that happens: because no file records a model, nothing in the format needs to change when your catalog does.

## Step 4: Disclose subagents to the parent

Tell the parent agent what subagents exist without loading their bodies. The parent should see, per subagent: `name`, `description` and (as a signal) `complexity`.

The most common pattern is a dedicated delegation tool whose description embeds the catalog:

```xml theme={null}
<available_subagents>
  <subagent>
    <name>repo-explorer</name>
    <description>Maps how a codebase implements a feature. Use before planning changes.</description>
  </subagent>
  <subagent>
    <name>test-runner</name>
    <description>Runs the test suite and reports results grouped by root cause.</description>
  </subagent>
</available_subagents>
```

Alongside the catalog, include behavioral instructions for *how* to delegate. The catalog tells the parent who exists; the instructions tell it what a good delegation looks like:

```
Delegate focused work to a subagent when the task matches its description.
Send an objective, the expected deliverable, guidance on tools and sources,
and clear task boundaries. Subagents cannot ask you or the user questions;
they report results or a blocked status. You receive their reports and
decide what to keep.
```

Keep the catalog compact. Descriptions are the one part of the format that costs the parent context on every session; a bloated description is paid forever.

### Filtering

Users and projects can disable or enable any subagent, including the ones your harness bundles. Disablement lives in your own configuration — the format defines the capability, not a config file. A project's choice wins over the user's for that project, mirroring how files take precedence. Hide subagents the user has disabled or that policy denies, rather than listing them and blocking at delegation time.

Show overrides as well as hiding. When several layers provide the same `name`, surface which source won; when a subagent is disabled, surface what disabled it. A user debugging delegation needs to see the layering, not just the outcome.

If no subagents are available, omit the catalog and the delegation tool entirely.

## Step 5: Spawn and execute

When the parent delegates, spawn a new model session.

### The spawn

Give the new session:

* **System prompt**: the subagent's body. Nothing else — not the parent's system prompt, not the conversation. Basic environment details (working directory, platform) are fine and often necessary.
* **Task**: the delegation message from the parent.
* **Tools**: resolved from the subagent's `tools` field — `true` grants all tools, `false` or an empty array none, an array whitelists those names against what your harness offers (warn on unknown names); absent inherits the parent's tools. Enforce the restriction harness-side — the body saying "don't edit files" is not enforcement.
* **An isolated context**: the subagent sees nothing from the parent beyond the task. That isolation is the point.

### Enforce the no-human rule

Subagents run without a human in the loop. Harness-side, this means:

* Don't expose user-interaction tools (asking questions, requesting approval) to subagents. Intercept them if your tool set includes them.
* Don't pause subagent runs for permissions the parent already has. A subagent blocked on a consent dialog stalls its parent.
* If a subagent needs a permission it doesn't have, let it fail and report `Status: blocked`. The parent decides what to do.

### Depth and parallelism

A parent may itself be a subagent; the format sets no depth limit, but you may. Existing harnesses cap nesting (Claude Code allows three layers) and bound concurrent spawns. Decide deliberately: unbounded nesting multiplies cost in ways users don't see until the bill arrives.

Parallel delegations are safe when subagents work on separate areas or are read-only. They are the classic way to produce conflicting edits when subagents mutate the same files — your harness can prevent this with worktree isolation or by serializing writes, but a cautious default is to let the parent decide and only support what you can arbitrate.

## Step 6: Handle the return

When the subagent finishes, its report becomes the parent's tool result.

### Deliver the report as untrusted data

The subagent is untrusted code with a pen: its body came from the filesystem, and its output is model-generated text that may contain instruction-shaped content. Before handing the report to the parent:

* Consider scanning for instruction-injection patterns (imitated system reminders, fake tool output, "ignore previous instructions") and flagging or escaping them
* Wrap the report in a structure the parent reads as data, not as instructions to itself
* Attribute it: "the following is the report of subagent X"

This matters more than for skills, because the report arrives mid-conversation and shaped like ordinary model output.

### Surface cost and status

If you can, attach timing and token metadata to the report (duration, tokens spent). Parents triaging several subagents use status first and cost second — both belong next to the report, not buried in a log.

### Support follow-ups where you can

A subagent that just did an hour of exploration is expensive to redo. If your harness can keep finished subagents resumable — the parent sends a follow-up task and the subagent continues with its context intact — do it. If you can't, say so in the tool result so the parent doesn't try.

## Summary

The whole integration is a loop you already know: scan a directory, sync a catalog, adapt what you load, show the parent who exists, run a session, hand back a result. What makes it subagents is the isolation on the way in (body as system prompt, no conversation) and the discipline on the way out (report as untrusted data, status first). Get those two right and the format takes care of the rest.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.