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 fixes | Which means |
|---|---|
| Model | which engine does the thinking; change it per kapsule without touching the rest |
| Persona + skills | how it works: the system prompt plus the instruction packs it loads |
| Tools | what it may touch — an allowlist, still approval-gated; a CLI model keeps its own native tools alongside Kaptain's |
| Permissions | how far it may go unattended (ask / sandbox / auto / full) and which targets are pre-trusted |
| Memory | whether a run sees the previous runs, plus the private memory database |
| Schedule + task | when it works on its own and what the standing job is |
| Threads + Jobs | where 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 Agent | KDDA — Kapsule Defined Dynamic Agent | |
|---|---|---|
| What it is | an agent you declare in kapsule.json — the persona, model, tools and schedule you wrote | a worker the kapsule mints for one role while a job runs |
| Lifetime | persistent: it exists whether or not work is running | born for a task; kept only if its job completed with evidence |
| Name | yours, chosen by you; callable by name from chat, schedule, CLI and other agents | role-shaped; earns an identity by succeeding, then appears under Jobs as a proven worker |
| Memory | across runs, when you turn it on | the job's board: structured notes the workers share |
| Permissions | the kapsule's approval mode and tool allowlist | never 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
- Open the Kapsules tab ▸ New kapsule.
- Name it; write a one-line Purpose — the Generate persona button drafts the system prompt from it, and you edit the result.
- 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.
- Pick a Schedule (or On demand) and a time — the timezone your browser detected is shown with it.
- Write the Standing task — what a scheduled run should do. A schedule without a task is refused.
- Create kapsule. It is immediately listable, chattable, and scheduled.
The settings that matter
- Permissions (approval mode): a scheduled run has nobody to answer prompts. Ask stops at the first risky step; Full access is the only mode that runs a CLI-harness kapsule start to finish unattended. Set per kapsule (it travels with the file) or inherit the model's setting.
- Remember previous runs: off by default — a scheduled job starts fresh from its task, the way you'd brief a person. Turn it on only when a job genuinely builds on its own last answer; Reset run memory is right below it for when a bad run poisons the thread.
- Trusted scopes: pre-approve targets, never tools — e.g. a path with
rw, one MCP server, one web host. The approval mode still sets the ceiling. - Can bring in workers: the harness switch described above. Off: the kapsule does each job itself. On: it may split a job across workers it creates; a worker is kept only when its job completed with evidence.
- Delegation: whether the kapsule may call other kapsules and its workers. Default is on when workers are on or an agent tool is granted; Off keeps granted agent tools unusable until you change it.
Schedules
| Write | Meaning |
|---|---|
daily@10:00 | every day at 10:00, in the kapsule's timezone |
every 6h@08:00 | every 6 hours, anchored to 08:00 — deterministic wall-clock slots |
30m, 1h, 24h | plain 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.