nextv2.0.0
Customize and automate

Share chains with add-ons

Publish chains, library components, skills and agent profiles as a Kraft add-on in a collection, then install, use and update it on another instance.

Publish your chains as a Kraft add-on in a collection, and install it on every instance that should run them. Each instance pins the add-on to a commit and changes it only through an update you review.

This guide builds a collection acme with one add-on, release, then installs it. To write an add-on, start at Publish a collection. To install someone else's, check Before you start first, then go to Install an add-on.

ToRun
Check an add-on you wrotekraft admin addon validate PATH
Add a collectionkraft admin addon collection add SOURCE
Install an add-on from itkraft admin addon install ADDON@COLLECTION
See what is installedkraft admin addon list
Take a new versionkraft admin addon update
Remove an add-onkraft admin addon uninstall ADDON@COLLECTION

Before you start

  • A running Kraft server, and git.
  • A git repository to publish the collection from, if other machines will install it.
  • The instance defines every harness and agent profile the add-on requires. The example needs the shipped claude harness and strong profile.

Publish a collection

1. Lay out the collection

A collection is a directory with .kraft/collection.json at its root and one directory per add-on:

acme-kraft/
  .kraft/collection.json
  addons/
    release/
      .kraft/addon.json
      library.yaml
      chains/ship.yaml
      skills/release-notes/SKILL.md

collection.json names the collection and lists its add-ons:

acme-kraft/.kraft/collection.json
{
  "$schema": "https://kraft-sdlc.dev/schemas/collection.schema.json",
  "name": "acme",
  "description": "ACME's Kraft chains and review methods",
  "owner": { "name": "ACME Platform", "email": "platform@acme.dev" },
  "addons": [
    { "name": "release", "source": "./addons/release", "description": "Release chains" }
  ]
}

addon.json names the add-on, its version, and what it needs from an instance. "kraft": "2" means any Kraft 2.x:

acme-kraft/addons/release/.kraft/addon.json
{
  "$schema": "https://kraft-sdlc.dev/schemas/addon.schema.json",
  "name": "release",
  "version": "1.0.0",
  "description": "Release chains",
  "requires": { "kraft": "2", "harnesses": ["claude"], "profiles": ["strong"] }
}

2. Write the add-on's files

The files have the same shape as the ones in your own config/. Inside an add-on, a bare extends:, steering: or skill: names the add-on's own declaration. A bare harness: or profile: names the instance's.

An add-on holds only the files it uses. One chain, or one skill, is a valid add-on. An add-on with none of library.yaml, chains/, skills/ and profiles.yaml is refused.

A chain is named by its id, or by its file name when it has none, so the chain below is release:ship once installed. A file name is a lowercase letter, then lowercase letters, digits, _ or -. Kraft ignores chains/Ship.yaml, and validate warns about it.

acme-kraft/addons/release/library.yaml
tasks:
  implementer:
    kind: agent
    harness: claude
    profile: strong
    prompt: Implement the approved plan, then write the release notes.
    skill: release-notes
    policy:
      time_cap_minutes: 90

  test_changed_scopes:
    kind: builtin
    ref: kraft.verify_changed_test_scopes
    scope: each_repository
acme-kraft/addons/release/chains/ship.yaml
id: ship
description: Implement, write release notes, run the tests for what changed.

nodes:
  - id: implementation
    kind: exec
    tasks:
      - id: implement
        extends: implementer

  - id: verify
    kind: exec
    tasks:
      - id: test_changed_scopes
        extends: test_changed_scopes
acme-kraft/addons/release/skills/release-notes/SKILL.md
---
name: release-notes
description: Write release notes for the change in this worktree.
---

Add one line to `RELEASES.md` for each user-visible change, newest first.

An add-on cannot use a component of your local library or of another add-on: it carries everything its chains extend. It also cannot carry a subprocess task or a permission. What an add-on may set has the list.

3. Validate it

kraft admin addon validate ./acme-kraft
release 1.0.0  sha256:f915f6266d319e9c0bc2bb2483683d74f307839138258901919e7d071fd37da4

validate runs the checks an install runs and installs nothing. It prints one line per add-on, then:

  • each problem as error: <file>: <message>. Any problem makes it exit 1.
  • each file or manifest key Kraft ignores as warning: <message>. A warning does not change the exit code.
  • when the config directory has no library.yaml, as in CI, a skipped: line that names the checks it left out.

When the config directory has a library.yaml, validate also checks the add-on against that instance: its requires, its namespace, and your own chains.

Add-on problems lists each message and its fix.

4. Try it from the directory

Add the directory itself as a collection, and install from it:

kraft admin addon collection add ./acme-kraft
kraft admin addon install release@acme

An add-on from a directory collection has an update whenever its files change, whatever its version. Edit a file, then run kraft admin addon update and accept the review. Before you add the published collection (Install an add-on), remove this one: kraft admin addon uninstall release@acme, then kraft admin addon collection remove acme.

A directory collection exists on one machine only, and never auto-updates.

5. Publish it

Commit the collection and push it to a git host. To release a change later, raise version in addon.json and push. An installed instance sees an update only when the version changes, so a push without a new version changes nothing for the people who installed it.

Tell people the collection's address and the add-on's id. They add and install it with the commands under Install an add-on.

A private repository works when git on the machine that runs the Kraft server can clone it without a prompt: an SSH key, or a credential helper, that a server run as a service can reach. Put no credentials in the URL; Kraft refuses one that has them.

Run validate in CI

Run validate on every push to the collection. validate needs no server and no config directory, so CI only installs Kraft and runs it. The job fails when validate exits 1. For GitHub Actions:

.github/workflows/validate.yml
name: validate
on: [push, pull_request]
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pipx run --spec kraft-sdlc kraft admin addon validate .

Or share from the repository itself

A collection suits chains many repositories share. For one repository's own chains, commit them in the repository and skip the collection: a repo library is read from the repository's .kraft/ folder on its default branch, with no manifest and no install.

  1. Put library.yaml, profiles.yaml, chains/<name>.yaml or skills/<name>/SKILL.md directly in .kraft/, commit them, and merge to the default branch.
  2. A teammate runs kraft repo connect in a terminal. Connect prints a review of the library and asks whether to take it.
  3. Items filed in that repo run .kraft/chains/default.yaml with no further setup, and --chain my-repo:hotfix selects another. A later change waits until someone runs kraft repo library and takes it. The first accept asks whether later text changes may be taken automatically; see Automatic updates.

The repository's id in repos.yaml is the namespace, and an instance checks every change against the same rules as an add-on. Repo libraries has the facts.

Install an add-on

Bound what an add-on's agents may do

An add-on's prompts, steering and skills are instructions an agent follows with whatever tools your instance allows it. An add-on cannot widen what a run may do, but with nothing set on the instance an agent may already run any command. Before you install an add-on from people you do not fully trust, set these on the instance:

Security explains why an add-on carries limits and never permissions.

1. Add the collection

Kraft ships no collection and has no directory of them, so ask whoever published the add-on for its address. Then add it:

kraft admin addon collection add acme/kraft-addons
added collection acme

owner/repo is a GitHub repository. An https URL, an ssh:// URL, a user@host:path address or a file:/// URL works too, and --ref picks a branch, tag or commit. This installs nothing. kraft admin addon collection list shows what the collection publishes.

2. Install the add-on

kraft admin addon install release@acme

Kraft fetches the add-on, checks it against your instance, and prints a review. Reach lists what decides how far a run goes: gates, merge steps, harnesses, models and limits. Content lists the rest, with every prompt and skill in full. On a first install everything is new:

release@acme new, 1.0.0
Reach:
  - release:ship.nodes[implementation].tasks[implement]: harness set to 'claude'
  - release:ship.nodes[implementation].tasks[implement].policy: limit time_cap_minutes set, set to 90
  ...
Content:
  - release:ship.nodes[implementation].tasks[implement]: prompt new:
Implement the approved plan, then write the release notes.
  ...
Apply release@acme? [y/N]

Read it, then answer y. Nothing is installed until you do. -y accepts without asking. A running server loads the add-on at once. Add-on problems covers a refused or declined install.

If another add-on or a repository already uses the name release, install it under another namespace with --as:

kraft admin addon install release@acme --as acme-release

3. Check it worked

kraft admin addon list
release@acme  release  1.0.0  f4a11422cc83

The columns are the add-on id, its namespace, its version and the commit it is pinned to. Then read a chain it ships:

kraft admin templates show release:ship

The output starts with # release:ship (release@acme 1.0.0). kraft admin doctor shows 1 add-on(s) load on its add-ons row.

Use what an add-on ships

Everything an add-on declares is named <namespace>:<name> from outside it.

  • Run its chain. Name it when you file an item, or make it a repo's default_chain in repos.yaml:
    kraft item create "Cut the 4.2 release" --chain release:ship
    
  • Extend a component. A chain or library component of your own takes an add-on's with extends: and changes what it needs. An update to the add-on reaches your chain too, and its review shows the change:
    config/chains/mine.yaml
    id: mine
    nodes:
      - id: implementation
        kind: exec
        tasks:
          - id: implement
            extends: release:implementer
            policy:
              time_cap_minutes: 60
    
  • Select its skill, steering profile or agent profile. Set skill: release:release-notes, steering: [release:house-style] or profile: release:careful on a task in your own chain or library. The add-on must ship the one you name. The example add-on ships only the skill. An add-on declares a steering profile in the steering: section of its library.yaml, and an agent profile in its profiles.yaml. Names lists every qualified reference.
  • Copy it. An add-on's chains and components are read-only. In the web UI, open the chain under Templates › Chains, or the component under Templates › Library, and click Copy to my library. Kraft asks for a name and opens a draft that is yours to edit. A copy no longer follows the add-on's updates. The phone layout has no copy button.

Keep it current

Update by hand

kraft admin addon update --check
release@acme 1.0.0 -> 1.1.0
Reach:
  - release:ship.nodes[implementation].tasks[implement].policy: limit time_cap_minutes raised, 90 -> 120
Content:
  - component tasks.implementer changed
release@acme: update waiting

--check prints each review and changes nothing. It exits 0 when every add-on is current, 1 when an update is waiting, 2 when one would be refused and 3 when a collection could not be checked, so a scheduled job can watch for one. kraft admin addon update shows the same reviews and asks about each add-on in turn.

An item that is already running keeps the add-on version it started with.

Let an add-on update itself

kraft admin addon auto-update release@acme on

After each server start, and once a day while the server runs, Kraft checks the add-on and applies an update whose review has no Reach line: a new version that changes only content, such as a prompt or a skill. It holds every other update for you and keeps the installed version running. kraft admin doctor shows a held or failed update on its add-on updates row.

kraft admin addon collection auto-update acme on does the same for every add-on installed from the collection. Auto-update lists what is held.

Put the same add-ons on another machine

Copy addons.yaml and addons.lock from config/ to the other machine's config/, then start Kraft or run kraft admin reload. Kraft fetches each add-on at its locked commit in the background, so both machines run the same files. The other machine needs git access to the collection's URL.

Remove an add-on

kraft admin addon uninstall release@acme

Kraft refuses while one of your own files still names the add-on's namespace, and lists each reference. Change those first. kraft admin addon disable release@acme keeps the add-on installed and stops loading it, under the same rule. Items that are running finish on the version they started with.

Serve Claude Code from the same directory

An add-on directory can also be a Claude Code plugin. Kraft reads .kraft/, library.yaml, profiles.yaml, chains/ and skills/, and nothing else in the directory:

addons/release/
  .kraft/addon.json
  .claude-plugin/plugin.json
  library.yaml
  chains/ship.yaml
  skills/release-notes/SKILL.md
  hooks/hooks.json
  .mcp.json
  • skills/ has the layout Claude Code uses, so both tools read the same SKILL.md. The skill is release:release-notes in both.
  • .claude-plugin/, hooks/ and .mcp.json never reach Kraft. It does not install the Claude Code half: do that in Claude Code.
  • An alias changes the name on Kraft's side only. An add-on installed with --as acme-release has acme-release:release-notes in Kraft and release:release-notes in Claude Code.
  • A chain of yours that already says skill: release:<name> hands that skill to the agent. Once an add-on holds the namespace release, Kraft reads the skill from the add-on, and the install review lists each such reference.

Next steps

  • Add-ons and collections: every manifest field, addons.yaml, the lock, and when an add-on loads.
  • Admin verbs: every kraft admin addon verb and flag.
  • Security: what an add-on can and cannot change.
  • Add-on problems: the message validate or a kraft admin addon command printed when you add a collection, install, update or remove an add-on, and its fix.
  • Write your own chain: the chain and library keys an add-on's files use.
Copyright © 2026