Cairn is an append-only store of typed facts. An agent asserts a fact in one session and recalls it, with a freshness verdict, at the start of the next.
Facts persist in SQLite. The desk is optional. The work happens on JSON and MCP.
The npm package is @quarkos/cairn. Always use the scoped package name; the unscoped cairn name is an unrelated 2017 React Native styling package.
From any empty project folder (Node 20+):
npx --yes @quarkos/cairn --help
npx --yes @quarkos/cairn init --project
npx --yes @quarkos/cairn devThe first command warms the npx cache. init --project creates .cairn/cairn.db (empty), wires Cursor (.cursor/mcp.json), and wires Pi + Claude Code (.mcp.json). The shared .mcp.json stores an absolute CAIRN_HOME. It does not use Cursor-only ${workspaceFolder}. --demo seeds only an empty store and refuses to overwrite existing facts.
On an ephemeral VM, run the scoped help command once before starting an agent so the MCP process does not pay the package download during client startup. Run project init again for each new workspace, then reload the client's MCP configuration. Claude Code may ask for the expected project-server approval; Pi must be installed in the VM.
Global install without a project file:
npx --yes @quarkos/cairn init| Command | Purpose |
|---|---|
cairn init --project |
Empty database + Cursor + Pi/Claude MCP config in the current repo |
cairn init --project --demo |
Seed sample beliefs only when the project store is empty |
cairn dev |
Desk and API on port 4721, using this project's .cairn |
cairn start |
Production server after npm run build |
cairn mcp |
Stdio MCP server for agents |
cairn recall |
Print live beliefs as JSON |
Invoke via npx --yes @quarkos/cairn …, npx --yes github:QuarkOS/Cairn …, or node bin/cairn.mjs from a clone. init writes MCP npx args from that install source (@quarkos/cairn, github:QuarkOS/Cairn, or the local checkout path). Override with CAIRN_NPX_SPEC when MCP should use a different package.
Send JSON to POST /api/cairn or use the typed MCP tools:
| MCP tool | Purpose |
|---|---|
cairn_recall |
Recall live beliefs with freshness and assurance |
cairn_assert |
Append a typed fact with explicit conflict behavior |
cairn_retract |
Retract a live fact without deleting its history |
The write tools expose the complete input schema and take request fields directly. cairn_request remains available for clients using the original nested JSON-contract tool.
Every write carries an idempotencyKey. Replay the same key and body after a crash and Cairn returns the original result without writing twice.
Recall returns freshness and assurance on each belief. Branch on response.kind. Rejections include error.remedy.kind.
curl -s http://127.0.0.1:4721/api/cairn \
-H 'content-type: application/json' \
-d '{
"kind": "assert",
"idempotencyKey": "s-021-deploy",
"onConflict": "supersede",
"draft": {
"entity": "repo:acme/checkout",
"attribute": "deploy.command",
"value": { "kind": "text", "text": "bin/ship --env staging" },
"provenance": {
"kind": "observed",
"command": "cat Makefile && bin/ship --help",
"session": "s-021"
},
"validity": { "kind": "until-superseded" }
}
}'After init --project, .cursor/mcp.json includes a cairn server. Cursor may use ${workspaceFolder} here:
{
"mcpServers": {
"cairn": {
"command": "npx",
"args": ["-y", "@quarkos/cairn", "mcp"],
"env": {
"CAIRN_HOME": "${workspaceFolder}/.cairn"
}
}
}
}Reload MCP in Cursor (or restart) so the tools appear. After npx --yes github:QuarkOS/Cairn init --project, the args entry is github:QuarkOS/Cairn instead of @quarkos/cairn.
The same init writes project-scoped .mcp.json. Claude Code reads that file at session start and prompts once to approve project servers. On this checkout, see CLAUDE.md for the agent rule and DEMO.md for a two-session walkthrough. Init is still the local first step. .mcp.json is gitignored because it stores an absolute CAIRN_HOME.
{
"mcpServers": {
"cairn": {
"command": "npx",
"args": ["-y", "@quarkos/cairn", "mcp"],
"env": {
"CAIRN_HOME": "/absolute/path/to/your/project/.cairn"
}
}
}
}CAIRN_HOME is an absolute path written at init time. Claude Code does not understand Cursor's ${workspaceFolder}. The args package matches whatever install source ran init.
You can also add the server with:
claude mcp add --scope project cairn -- npx -y @quarkos/cairn mcpThen set CAIRN_HOME in the generated entry to your project's .cairn directory.
Pi also reads .mcp.json. Init writes the same portable file used for Claude Code: absolute CAIRN_HOME, no ${workspaceFolder}.
Start Pi from the project root (or any client that loads .mcp.json) and open /mcp to confirm the cairn server is listed.
This repository is an Agent Plugin (plugin.json + mcp.json + skills/) with a Cursor overlay at .cursor-plugin/plugin.json only so marketplace Configure can collect optional CAIRN_HOME. It does not add rules, hooks, agents, or commands.
The npm package is always @quarkos/cairn. Never install or invoke the unscoped cairn package (an unrelated 2017 React Native styling library).
-
In the project that should hold beliefs, run:
npx -y @quarkos/cairn init --project
That creates
.cairn/(the SQLite store) on your machine. -
Install this plugin in Cursor (Customize, or a local copy under
~/.cursor/plugins/local). Reload the window so thecairnMCP server and thecairn-recall/cairn-assertskills appear. -
Optionally open Plugins → Configure and set
CAIRN_HOMEto the absolute path of that project's.cairndirectory (for example/Users/you/work/checkout/.cairn). Leave it unset if you already exportedCAIRN_HOME, or if you want native resolution. -
Call
cairn_recallat session start. Callcairn_assertafter a decision, deploy, URL, or command actually lands. Callcairn_retractwhen a live fact is no longer true. Do not invent facts.
| Item | Value |
|---|---|
| MCP command | npx -y @quarkos/cairn mcp |
| Store | CAIRN_HOME on the installer's machine |
| Optional plugin variable | CAIRN_HOME — absolute path to the project's .cairn after init --project. Not required. Not a secret. |
| Native resolution if unset | CAIRN_HOME if set, else ./.cairn if that directory exists in the MCP process cwd, else ~/.cairn |
| Skills | cairn-recall, cairn-assert |
mcp.json does not set cwd (and does not use ${PLUGIN_ROOT}). Spec-compliant Agent Plugins clients still default the subprocess cwd to the plugin root, so do not rely on ./.cairn inside the plugin install directory. Point CAIRN_HOME at your project store.
If Configure leaves CAIRN_HOME blank, hosts may pass an empty string or the literal ${CAIRN_HOME}. Cairn treats both as unset and continues native resolution. Never pin a coordinator or cloud-agent path such as /home/box/cairn-loop/.cairn.
This plugin helps Cursor IDE users on the installer's machine. It does not inject facts into Cursor cloud agent VMs. Those remotes cannot see the installer's SQLite.
Marketplace listing is a separate step. This repo is plugin source only; submitting at cursor.com/marketplace/publish is out of scope until someone does that on purpose.
Open Desk (/) for the beliefs table and Agent API console. Open Canvas (/canvas) to see each agent or session as a draggable container with the facts they contributed.
Agents group by provenance.by for told facts and by provenance.session for observed or inferred facts. Drag pods to arrange the board; layout persists in .cairn/canvas.json.
npm publish --access publicThe published tarball ships the desk, canvas, API, CLI, and MCP server. Package and MCP server versions are both 0.4.6.
CAIRN_HOME is the one directory that holds cairn.db and canvas.json.
Resolution, in order:
CAIRN_HOMEif you set it./.cairnin the directory you ran the command from, if that folder exists~/.cairn
cairn dev and cairn start run Next.js from the installed package, not from your project. They still pin CAIRN_HOME using the rule above, so a throwaway project that ran init --project talks to that project's database without exporting anything. Set CAIRN_HOME only when you want a different store.
CAIRN_DB_PATH overrides just the SQLite file.
npm install
npm test
npm run devDatabase path resolves as described in Where the database lives. npm run dev from a clone uses the same rule with the repo as cwd.
A ~30s product trailer for X lives in cairn-trailer/. Preview with npm run dev inside that folder, or render:
cd cairn-trailer
npx remotion render CairnTrailer out/cairn-v0.4-trailer.mp4Free-form JSON values. Semantic search. Editing facts in place. Waiting on a human mid-request.