How-To · 20 min

Kapsules: harnesses and agents

A Kapsule is not a plain agent. It is a harness: a model of your choice — local, API, or a coding CLI — wrapped with its own persona, tool allowlist, skills, permission policy, memory, schedule, chat threads and jobs, in one folder you can review and ship. The agents inside it come in two kinds: the ones you declare and keep, and the workers it creates for a job. You can build one entirely in the UI.

What a Kapsule is

A folder at <data>/kapsules/<name>/ holding one kapsule.json. It can carry any mix of three things: agents (persona + model + tools + schedule — one, or several in the composite form), skills (instruction packs its agents load), and an mcp section (its own tool server — see Krew tools). Drop the folder in and it mounts live — no restart. Each kapsule also gets its own private memory database, a read-only home, a read-write <name>_workspace/ its agents maintain, its own chat threads, its own schedule table and its own Jobs view.

A harness, not just an agent

Every model Kaptain can run — an Ollama or GGUF model on your machine, a cloud API model, or a coding CLI you already use — is a bare engine. A kapsule is what turns that engine into a dependable unit of work by fixing everything around it:

The harness fixesWhich means
Modelwhich engine does the thinking; change it per kapsule without touching the rest
Persona + skillshow it works: the system prompt plus the instruction packs it loads
Toolswhat it may touch — an allowlist, still approval-gated; a CLI model keeps its own native tools alongside Kaptain's
Permissionshow far it may go unattended (ask / sandbox / auto / full) and which targets are pre-trusted
Memorywhether a run sees the previous runs, plus the private memory database
Schedule + taskwhen it works on its own and what the standing job is
Threads + Jobswhere its conversations, scheduled results and workers are recorded

With Can bring in workers off (the default) a kapsule is one persona, one toolset, one job — and a single agent doing its job well is the normal case. Switch it on and the same kapsule may split a job across workers it creates for the parts of that job. Each worker gets only the tools its part needs, workers receive each other's output, and a worker that provably completes its job is kept under the kapsule's own name and reused. There is one Kapsules tab, one file format and one permission model either way: being a harness is a capability you switch on, not a different kind of thing you have to choose up front.

The two kinds of agents

KDKA — Kaptain Defined Kapsule AgentKDDA — Kapsule Defined Dynamic Agent
What it isan agent you declare in kapsule.json — the persona, model, tools and schedule you wrotea worker the kapsule mints for one role while a job runs
Lifetimepersistent: it exists whether or not work is runningborn for a task; kept only if its job completed with evidence
Nameyours, chosen by you; callable by name from chat, schedule, CLI and other agentsrole-shaped; earns an identity by succeeding, then appears under Jobs as a proven worker
Memoryacross runs, when you turn it onthe job's board: structured notes the workers share
Permissionsthe kapsule's approval mode and tool allowlistnever wider than whatever minted it — a worker cannot hold a tool its parent lacks

The two are alike in capability; the real difference is lifetime and ownership. A KDKA is something you keep. A KDDA is something the work creates. Both sit under the same never-widen ceiling, so turning workers on never grants a kapsule anything it did not already have. In the product you will see them as your kapsules and the workers they created; the two formal names exist so the design can be discussed precisely.

Create one in the UI

  1. Open the Kapsules tab ▸ New kapsule.
  2. Name it; write a one-line Purpose — the Generate persona button drafts the system prompt from it, and you edit the result.
  3. Pick a Model (default: engine default) and, optionally, a Tools allowlist — leave it empty and the agent may use the whole enabled catalog, still approval-gated.
  4. Pick a Schedule (or On demand) and a time — the timezone your browser detected is shown with it.
  5. Write the Standing task — what a scheduled run should do. A schedule without a task is refused.
  6. Create kapsule. It is immediately listable, chattable, and scheduled.

The settings that matter

Schedules

WriteMeaning
daily@10:00every day at 10:00, in the kapsule's timezone
every 6h@08:00every 6 hours, anchored to 08:00 — deterministic wall-clock slots
30m, 1h, 24hplain interval
(empty)on demand only

Schedules carry an IANA timezone (schedule_tz, e.g. America/Toronto) so "10am" means 10am where you are; each occurrence runs at most once, ever, and results are persisted — not just broadcast into a void.

The kapsule.json file

Everything the UI does lands in this file, so a kapsule is reviewable and shippable (git-friendly). The core agent fields:

{
  "name": "digest",
  "enabled": true,
  "agent": {
    "name": "digest",
    "system": "You are…",            // persona; or drop a digest.md next to it
    "model": "",                      // empty = engine default
    "tools": ["web_search","file_read"], // empty = full enabled catalog
    "approval_mode": "auto",          // ask | sandbox | auto | full | "" = inherit
    "schedule": "daily@08:30",
    "schedule_tz": "America/Toronto",
    "task": "Summarise overnight mentions of…",
    "memory": false,                  // replay previous runs; default off
    "skills": ["report-style"],       // skill docs injected into the persona
    "trusted_scopes": ["path:/home/me/reports rw"],
    "swarm": false,                   // "Can bring in workers"
    "delegation": { "mode": "off", "allow_agents": [] }
  }
}

A kapsule that carries several agents uses "agents": [ … ] instead of "agent"; "use_kapsule_tools": true lets an agent reach the tools of its sibling mcp section; "skills" at the top level adds the kapsule's own skill folders. Existing single-agent files stay valid forever — a harness with one agent is a valid harness.

Run, chat, invoke

kaptain agent list
kaptain agent run <name> "<task>"     # one turn
kaptain agent chat <name> "<msg>"     # persistent direct chat
kaptain agent history <name>
kaptain agent enable|disable <name>
kaptain agent set-model <name> <model>

In the UI, each kapsule has direct chat and its sessions; scheduled results persist and are reviewable.

Jobs and proven workers

Each kapsule's Jobs section lists the jobs it split across workers and the workers that earned a place. The Kapsules overview shows the same in one line per kapsule: last run and its result, the review verdict, how many memories it holds, and whether workers are on. When a run finishes, the result lands under Jobs and in the notification bell; a local model can take a few minutes. Every worker turn is traceable in BlackBox like any other turn.

Agents calling agents

Off by default. A kapsule opts in with a delegation block (mode + an allow_agents list); agent CLIs connected over MCP also get agent_list / invoke_agent tools, which route to the running Kaptain. Every sub-agent is also callable as a tool named agent_<name> where granted.

Agent-readable version: index.md · Every claim on this page was exercised on a real install before being written. Something missing that cost you time? That is a documentation bug — tell us.