Kyle keeps a coral-monitoring project and a literature-tracking project alive at the same time. Each project has its own cairn. The agent reaches the right one without being told.
Kyle is a marine biologist with two active projects: coral-bleach (a multi-year monitoring study of three transect sites in the Coral Triangle) and lit-monitor (an arXiv- and journal-feed watcher for relevant new papers). They live in two separate project repos. Each has its own cairn for project memory — decisions, findings, open questions, collaborators.
Both cairns are registered against the same user-level cairn mcp server. One server, two cairns, one researcher juggling both contexts during the same week.
The pairing happens once, when each project repo is first set up: cd ~/projects/coral-bleach && cairn link --name coral-bleach. That writes a small cairn.toml at the project root. From then on, any Claude Code session opened in that project repo reaches coral-bleach's cairn automatically — the agent doesn't have to ask, and Kyle doesn't have to pick.
Kyle finishes the morning's transect analysis. T3's 2024 cover dropped to ~30% from a multi-year mean near 50%. He opens Claude Code in ~/projects/coral-bleach/ and says:
The agent calls the MCP add_finding tool with cairn defaulting to coral-bleach (because cairn.toml at cwd says so), author=kyle, the title and body Kyle supplied. The server writes knowledge/findings/2026-05-23-coral-cover-at-transect-t3-dropped-to-30-in-2024.md into coral-bleach's repo, attributed via git authorship, and commits it. The whole transaction is invisible to Kyle except for a one-line confirmation in the chat.
The T3 trend pushes Kyle toward a methodology change he's been mulling for months. He decides to switch from line-intercept transects to belt transects starting with the 2025 season. The change connects to an open question raised last November about whether to base the bleaching-extent baseline on pre- or post-bleach surveys.
Agent calls add_decision with related=["Q-001"]. Server allocates D-002 (D-001 was the prior PIT-tag decision), validates that Q-001 exists in the cairn-wide id index, writes it to state/decisions.yaml, commits. Kyle's confirmation in the chat names D-002 and the file path so he can read it back later if he wants.
After lunch Kyle skims arXiv listings and notices a methodology comparison paper (2403.04567) on belt vs. line-intercept sampling. He opens a second Claude Code session — same machine, different window — in ~/projects/lit-monitor/.
This session's cairn.toml says name = "lit-monitor", so the agent's add_finding call routes there — not to coral-bleach. The finding lands in ~/cairns/lit-monitor/knowledge/findings/2026-05-23-methods-comparison-paper-arxiv-2403-04567-is-worth-a-closer.md. The cross-project link is captured in the body text rather than a structured related field — references across cairns aren't first-class entities the way references within one cairn are.
The same agent, the same person, the same afternoon, two cairns. The agent never asked "which one?"; the repo Kyle was in was the answer.
Every project repo that pairs with a cairn carries a small cairn.toml at its root:
[cairn]
name = "coral-bleach"
When the CLI or MCP server resolves a write, it walks up from cwd looking for this pointer. The name field looks the cairn up in the user-level registry; the registry points at the actual filesystem path. (Two other modes — a direct path = ... and a remote-MCP endpoint = ... + name = ... — exist for other deployments, but the registry-by-name form is the everyday case.)
The same routing applies to read commands. cairn status in ~/projects/coral-bleach/ returns coral-bleach's status; cairn status in ~/projects/lit-monitor/ returns lit-monitor's. The agent doesn't track a "current cairn" — there's no mode to forget to switch out of. Cwd is the state.
If, while sitting in coral-bleach, Kyle decides he also wants to log something to lit-monitor without switching shells, he can pass an explicit cairn override to the MCP tool: add_finding(cairn="lit-monitor", ...). The agent surfaces this naturally when Kyle says "log this to the other project". The everyday case stays implicit; the occasional cross-write is one word away.
If Kyle opens Claude Code in a directory that doesn't have a cairn.toml, the agent gets a clear error naming the cwd that was searched. If a cairn.toml names a cairn that isn't registered — say Kyle copied the project repo from a colleague but never ran cairn register — the error names the missing cairn and suggests the fix:
error: cairn 'coral-bleach' is not registered. Add it with
`cairn register coral-bleach <path>`. See `cairn registered`.
The error message does the work of telling Kyle what to do, without him having to think about which discovery surface he tripped over.
A natural temptation would be one MCP server per cairn — a process forest, one per project. It's tidy in isolation but doesn't scale to a researcher with four projects: four servers to register with Claude Code, four to restart when something changes. The user-level registry collapses that to one server and a tiny config file.
Another natural shape would be Claude Code "session-level cairn selection" — pick one cairn when the session starts, remember it. That breaks the moment Kyle wants to log a quick cross-project note without alt-tabbing to a different window. The cwd-as-discriminator approach lets the obvious place to do work — the project repo — also be the obvious place to capture about it.
The cost of this design is that Kyle's project repos all need cairn.toml at their roots. That's one file, written once via cairn link, checked into git so the rest of the team picks it up automatically. The benefit is that everywhere Kyle naturally is — the project he's working on — is also where the agent already knows to write.