nextv2.0.0
Agents and harnesses

Add or override a harness

Add an agent CLI to Kraft with a YAML file, and override a shipped one.

Add a new agent CLI to Kraft, or change how a shipped one is launched, by dropping a YAML file into a directory. No Python change and no Kraft release are involved. At the end, a chain task runs on your harness.

Before you start

  • The CLI is installed, on the PATH of the shell that starts Kraft, and you can run it headless by hand.
  • You know its flags for a prompt, and for each option you want Kraft to set (a model, an effort, a permission mode).
  • You know how it reports tokens: in a log one of Kraft's readers parses, or in a file the agent writes.

Add a harness

  1. Create $KRAFT_HOME/config/harnesses/mytool.yaml (~/.kraft/config/harnesses/ by default). Make the directory if it does not exist. The file name without .yaml must equal the id.
  2. Start with the three required capabilities:
    config/harnesses/mytool.yaml
    id: mytool          # must match the file name without .yaml
    kind: cli           # the only kind implemented
    command: [mytool]   # the command and its fixed arguments
    capabilities:
      prompt:  { cli: ["-p", "{value}"] }
      context: { channel: prompt }       # or: { channel: system_prompt, cli: [...] }
      usage:   { source: result_file }   # or: { source: envelope, reader: <parser name> }
    

    Capabilities defines each one and the channel, source and reader keys.
  3. Add each optional capability the CLI supports, with the cli: fragment that sets it. Leave out what the CLI cannot do. A task that asks for a capability you left out is rejected at load, pointing at this file. For a CLI with --model and --effort flags, add these two lines under capabilities::
    config/harnesses/mytool.yaml
      model:   { cli: ["--model", "{value}"] }
      effort:  { cli: ["--effort", "{value}"], values: [low, high] }
    
  4. Add a harness profile for the harness in ~/.kraft/config/harnesses.yaml. The profile's provider is your harness id. See harnesses.yaml for every profile field.
    config/harnesses.yaml
    harnesses:
      mytool:
        provider: mytool
        enabled: true
        executable: mytool
    
  5. In library.yaml, set harness: mytool on a task that should run on it.
  6. Reload so a running server rereads library.yaml:
    kraft admin reload
    

    Kraft reads harnesses.yaml and the harness file again at every agent launch, so those two need no reload.

Override a shipped harness

Use the same steps, with a file named after a shipped harness: claude.yaml, codex.yaml, cursor.yaml, opencode.yaml, gemini.yaml, antigravity.yaml, or amp.yaml.

Your file replaces the shipped one entirely. Copy the shipped definition from src/kraft/harnesses/ (one file per harness) and change only what you need. For example, edit claude.yaml to change which effort values it allows.

Check it worked

kraft admin doctor

Once a chain selects your harness profile, the output has an agent: mytool row that gives the path where Kraft found the executable. Kraft pads the name column to the widest check name:

ok    agent: mytool  /usr/local/bin/mytool
  • A failing harness: mytool row means your file did not load. Its detail names the file and the field to fix.
  • kraft admin harnesses lists the library tasks that select each harness profile.
  • File a small work item on a chain that selects the harness profile, and confirm the task runs on it.
  • If the task cannot log in, give the CLI credentials a worker can use. Give a worker its login has each harness's login, and how to check a worker can log in.

Next steps

Copyright © 2026