Install cairn
On this page
cairn ships as an extension for kli, the runtime it was built for, and kli serves it to any client that speaks the Model Context Protocol. In this tutorial you install cairn one of two ways, point an agent at it, and confirm the tool surface is live. By the end you have a working cairn that an agent can plan in and resume into. You do not have to adopt kli as your main agent to use cairn; any MCP client works.
You need kli built and a project directory to work in. The directory you launch from selects the project whose task graph cairn opens, so run these steps inside the repository you want the graph to track.
Install with kli
There are two ways to install. Bake cairn into the kli image declaratively, or install it at runtime from a running session. Pick one.
Declaratively
Take cairn as a flake input and name it in your kli configuration. kli's Home Manager and NixOS modules compile the listed extensions into the image. cairn needs SQLite on its library path, because its observation store is built on SQLite FTS5.
{ inputs.cairn.url = "github:kleisli-io/cairn"; }
programs.kli = {
enable = true;
extensions = [ inputs.cairn.packages.${system}.default ];
blessedNativeLibs = [ pkgs.sqlite ];
};
Rebuild, and cairn is in the image. Anything baked in this way stays put until you edit your configuration and rebuild again.
At runtime
Each cairn release page carries the exact install command for that version: the url of the published bundle and the git tree hash it is pinned to. For v0.1.1:
kli install https://github.com/kleisli-io/cairn/releases/download/v0.1.1/cairn.bundle 1b92b2928de8de87711c299d7353f1e0b602068e
kli fetches the bundle, recomputes the tree hash over its contents, and refuses to install on a mismatch, so what loads is exactly the bytes the release names. It shows what it is about to add and asks first; pass --yes in scripts and other non-interactive runs. The install is durable: the next kli or kli mcp-serve launch finds cairn without installing again.
The same install runs from inside a kli session as /install <url> <git-tree-sha1>, loading cairn live with no rebuild. The companion commands manage what you have installed: /extensions lists them, /enable and /disable toggle one, and /uninstall removes a runtime-installed extension.
cairn releases are also signed. To require the signature rather than the pin alone, add the Kleisli.IO release key to trustRoots; the key is published on each release page and committed at release/trust/cairn-release.pub. Sharing extensions walks the full trust flow.
To load a local build for a single run instead of installing it, start kli with --extension:
kli --extension <path>
That extension lives only for the life of that run.
Serve to any MCP client
The same kli, built with cairn, serves the extension to any other client over stdio. One command does it:
kli mcp-serve cairn
Wire a client to that command. Claude Code, Claude Desktop, and Cursor all read the same mcpServers block, so a single server entry connects any of them:
{
"mcpServers": {
"cairn": {
"command": "kli",
"args": ["mcp-serve", "cairn"]
}
}
}
The client launches kli in your project directory, and that working directory picks the project whose task graph cairn opens. Once connected, the client lists all fourteen of cairn's tools, with the bundled workflow prompts and the cairn-method skill exposed as MCP prompts and resources.
The slash commands, the per-turn context injection, and the compaction folding stay behind, because kli provides those as the host rather than over the tool protocol. That is why kli is the fuller home for cairn. See the mcp-serve reference for the full client matrix, exactly what travels, and the exposed surface in full.
Confirm it is live
Connect your agent and have it call one read-only tool to confirm cairn answers. task_bootstrap orients on the current task in a single call; in a fresh project with no current task set, it answers with a clear message instead of crashing:
No task to bootstrap; pass task_id or select a task first.
That message comes back as a tool result, not a protocol error, and it means the tool surface is wired and the graph is empty, which is exactly the state a first session starts from.
From here, run your first cairn session to create a task, record an observation, write a handoff, and bootstrap back into the work.