---
title: "The build kit"
description: "Skills that teach your coding agent to build Orchestrator Zero plugins the way verified plugins are built, installed with oz0 setup for Claude Code, Codex, Gemini CLI, Cursor, GitHub Copilot, OpenCode and goose."
canonical_url: "https://docs.oz0.ai/build/plugins/claude-code"
---
# The build kit

> Skills that teach your coding agent to build Orchestrator Zero plugins the way verified plugins are built, installed with oz0 setup for Claude Code, Codex, Gemini CLI, Cursor, GitHub Copilot, OpenCode and goose.

For: plugin authors.

Give your coding agent the build kit when it writes an Orchestrator Zero plugin. The kit provides eight [Agent Skills](https://agentskills.io/specification), the commands to run, and a path from a request such as wrapping a ticket system's MCP server to a plugin that passes `oz0 plugin lint --verified` and its tests.

The skills cite rule IDs from [plugin structure](https://docs.oz0.ai/build/plugins/structure). They do not duplicate the rules: a test fails if a skill names a rule lint lacks, or if a lint rule appears in no skill.

## The skills

<table>
<thead>
  <tr>
    <th>
      Skill
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        oz0-choose-the-kind
      </code>
    </td>
    
    <td>
      Chooses the plugin kind and agent boundaries. See <a href="#how-the-kit-chooses-a-structure">
        structure decisions
      </a>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-new-plugin
      </code>
    </td>
    
    <td>
      Picks a template and a name, runs <code>
        plugin new
      </code>
      
      , and turns the template into what was asked for
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-connector
      </code>
    </td>
    
    <td>
      Builds a connector: wrap the vendor's own MCP server or build on its API, pin it, connect it with the customer's own OAuth app, writes behind approval, exact egress, output schemas, contract tests with a fake, recorded evals and a README that documents it and its limits
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-check
      </code>
    </td>
    
    <td>
      Installs the dependencies, runs the plugin's tests and <code>
        plugin lint
      </code>
      
       (with <code>
        --verified
      </code>
      
       for the house rules as errors), and fixes what they report, reading each finding's rule section
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-contracts-and-evals
      </code>
    </td>
    
    <td>
      JSON Schema <a href="https://docs.oz0.ai/build/parts/contracts-and-limits">
        contracts
      </a>
      
      , <a href="https://docs.oz0.ai/improve/evals">
        eval
      </a>
      
       cases with recorded answers, <a href="https://docs.oz0.ai/improve/outcome-checks">
        outcome checks
      </a>
      
       with the default deliverable rubric, a connector's contract tests, and how to judge merging or splitting an agent: by the whole-job cases that flipped, three runs each, not by the pass rate alone
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-writing
      </code>
    </td>
    
    <td>
      Every description, prompt, message and error, written plainly and exactly, with no padding, and the README as the plugin's documentation within <a href="https://docs.oz0.ai/build/plugins/limits">
        its limits
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-publish
      </code>
    </td>
    
    <td>
      Checks, then packs a bundle into <code>
        dist/
      </code>
      
       with <code>
        plugin pack
      </code>
      
      , and says how to install it; it never publishes
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        oz0-where-a-fix-belongs
      </code>
    </td>
    
    <td>
      When an agent failed a job, an eval or a review: keeps the failure as an eval case, puts the fix in the cheapest part that holds it (<a href="https://docs.oz0.ai/improve/where-a-fix-belongs">
        Where a fix belongs
      </a>
      
      ), and says when to split the agent (<a href="https://docs.oz0.ai/build/parts/when-to-split-an-agent">
        When to split an agent
      </a>
      
      )
    </td>
  </tr>
</tbody>
</table>

### How the kit chooses a structure

The kit decides how the work is cut: connector, capability or policy, when to split it, its name, and the exact functions a capability's `uses:` grants. A request for an application is treated as an application; it is never a plugin.

For the agent's shape, it starts with one agent per job. Roles become skills, steps with no judgement become tools, a fixed order becomes a flow tool, and a reviewer becomes an outcome check. It adds a second agent only for the reasons on [When to split an agent](https://docs.oz0.ai/build/parts/when-to-split-an-agent).

The skills run `scripts/oz0kit.py` in their own folder, a Python script with no dependencies that calls the `oz0` command (or the one `OZ0_BIN` names) and prints JSON for the model to read. It never calls a model API, never records evals (that costs money: the skills ask first), never installs on a cluster and never pushes or publishes anywhere.

## Install it

`oz0 setup <tool>` writes the kit into the project, or into your own configuration with `--global`, beside the [operators' MCP server](https://docs.oz0.ai/fleet/mcp-client#in-one-command-oz0-setup):

```bash [Terminal]
oz0 setup claude-code      # .agents/skills and .claude/skills, .mcp.json
oz0 setup codex            # .agents/skills, .codex/config.toml, a section of AGENTS.md
oz0 setup gemini           # .agents/skills, .gemini/settings.json, a section of GEMINI.md
oz0 setup cursor           # .agents/skills, .cursor/mcp.json
oz0 setup copilot          # .agents/skills, .mcp.json (GitHub Copilot's CLI, coding agent and VS Code)
oz0 setup opencode         # .agents/skills, opencode.json
oz0 setup goose --global   # ~/.agents/skills, ~/.config/goose/config.yaml (goose reads MCP servers only there)
```

<table>
<thead>
  <tr>
    <th>
      Tool
    </th>
    
    <th>
      Skills, in the project (<code>
        --global
      </code>
      
      )
    </th>
    
    <th>
      MCP server, in the project (<code>
        --global
      </code>
      
      )
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        claude-code
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       and <code>
        .claude/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      , <code>
        ~/.claude/skills
      </code>
      
      )
    </td>
    
    <td>
      <code>
        .mcp.json
      </code>
      
       (<code>
        ~/.claude.json
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        codex
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      )
    </td>
    
    <td>
      <code>
        .codex/config.toml
      </code>
      
       (<code>
        $CODEX_HOME/config.toml
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gemini
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      )
    </td>
    
    <td>
      <code>
        .gemini/settings.json
      </code>
      
       (<code>
        ~/.gemini/settings.json
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cursor
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      )
    </td>
    
    <td>
      <code>
        .cursor/mcp.json
      </code>
      
       (<code>
        ~/.cursor/mcp.json
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        copilot
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      )
    </td>
    
    <td>
      <code>
        .mcp.json
      </code>
      
       (<code>
        $COPILOT_HOME/mcp-config.json
      </code>
      
      , <code>
        ~/.copilot
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        opencode
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      )
    </td>
    
    <td>
      <code>
        opencode.json
      </code>
      
       (<code>
        ~/.config/opencode/opencode.json
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        goose
      </code>
    </td>
    
    <td>
      <code>
        .agents/skills
      </code>
      
       (<code>
        ~/.agents/skills
      </code>
      
      )
    </td>
    
    <td>
      none (<code>
        ~/.config/goose/config.yaml
      </code>
      
      , under <code>
        extensions
      </code>
      
      )
    </td>
  </tr>
</tbody>
</table>

`.agents/skills` is the folder Agent Skills tools share; every tool above but Claude Code reads it, so setup writes the kit there for every tool, and to `.claude/skills` too for Claude Code. The copies are the same files, so a tool that reads both folders sees the same skill twice, not two skills. Kiro is not in the list: its folder could not be checked against Kiro itself.

- A second run changes nothing, and `--dry-run` prints the changes as a diff and writes nothing.

### `--update`

`--update` replaces the skills an earlier `oz0 setup` wrote from another version of the kit, and says what changed (`the skill oz0-check, kit 1.4.0 -> 1.5.0`). Each skill carries the kit's version, which is Orchestrator Zero's release, and a digest of its files in its `SKILL.md`; setup replaces only a skill whose files still have that digest. It also writes a skill of the same kit again when the folder became a Git repository's root since setup wrote it, or stopped being one, so the skill names its script the way that folder needs (a plain run says so).

A skill you changed stays as it is, and so does one of a newer kit. Claude Code skills an older `oz0 setup` wrote (a `SKILL.md` with `oz0kit.py` beside it, no kit version) count as setup's while nobody changed them: `--update` replaces them and `--remove` takes them out.

- `--remove` takes out what setup wrote and keeps a skill you changed. The skills in `.agents/skills` are shared by every tool set up in the project: removing them for one tool removes them for all, except while Claude Code is set up there, since its copies in `.claude/skills` run the script from `.agents/skills`. In a project, Claude Code and GitHub Copilot read the same `.mcp.json` entry: removing Copilot keeps it while Claude Code is set up, and removing Claude Code takes it out for both.
- The script's path. The skills run their script by a path a shell finds from any folder: `"$HOME/.agents/skills/..."` with `--global`, `"$(git rev-parse --show-toplevel)/.agents/skills/..."` in a Git repository's root, and `.agents/skills/...` from the project's folder otherwise.
- Setup never runs the tool, installs, downloads or signs in to anything. In a project it refuses to write through a symbolic link.

## Without oz0

The repository's `plugins/claude-code-oz0` folder is the kit's one source and a Claude Code plugin with a marketplace of its own, so Claude Code adds it from a checkout:

```text [Claude Code]
/plugin marketplace add ./plugins/claude-code-oz0
/plugin install oz0@orchestrator-zero
```

It adds the commands `/oz0:new`, `/oz0:check`, `/oz0:evals` and `/oz0:publish` beside the skills. The kit will also be published as a repository of its own, with a Claude Code marketplace, a Cursor plugin and the Agent Skills layout, generated from the same source.

## In every new plugin

Every template writes two files for coding agents:

- `AGENTS.md`, which Codex, Cursor, Copilot, Claude Code and others read: how the plugin is built, the manifest's rules, a table of the house rules by ID and where each bites, and the commands to set up, lint, test, run in dev and pack, for that template.
- `.claude/skills/oz0-plugin/SKILL.md`, a skill with the same rules and the loop: change, `plugin lint --json`, read the section of each finding's rule, run the tests, try it in `dev`, and never record evals against a paid API without asking.

Both point at the kit's skills. They are plain files: edit them as the plugin grows, and keep them in its repository.

## A connector from a vendor's MCP server

`oz0 plugin new <folder> --template mcp-connector --name <system>` writes the `oz0-connector` skill's starting point for wrapping a vendor's own remote MCP server; [Tools](https://docs.oz0.ai/build/parts/tools#wrap-a-vendors-remote-server) says what is in it.

## Kit evals

`make kit-evals` in a checkout runs build tasks through a coding agent with the kit installed: wrap a vendor's MCP server, a capability that triages tickets through a ticket connector's exact functions, and a connector by OpenAPI import. Each result must pass `plugin lint --verified` and its own tests. Name the agent's command, which calls a model with your own account:

```bash [Terminal]
make kit-evals KIT_TOOL=claude-code KIT_AGENT='claude -p --permission-mode acceptEdits "$(cat {prompt_file})"'
make kit-evals KIT_TOOL=codex KIT_AGENT='codex exec --full-auto "$(cat {prompt_file})"' KIT_TASK=wrap-atlassian
```

The tests run the same tasks with a fake coding agent that replays recorded transcripts, and call no model.

## Orchestrator Zero reads it too

Orchestrator Zero reads Claude Code plugins ([Claude Code and Agent Plugins](https://docs.oz0.ai/build/plugins/claude-code-and-agent-plugins)): `oz0 plugin lint plugins/claude-code-oz0` reads this one as `0 tools, 0 agents, 10 skills`: its eight skills, and the commands `evals` and `new`, which a Claude Code plugin's import counts as skills too. The commands `check` and `publish` have their skills' names, and a skill wins over a command of its name, as in Claude Code.


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
