# Serving over MCP


`kli mcp-serve cairn` runs a kli built with the cairn extension as a Model Context Protocol server over stdio. The process exposes one extension's surface to a single client: cairn's fourteen tools, seven prompts, and seven readable resources. A client connected this way plans, observes, queries, and resumes against the same durable task graph it would reach inside kli, without adopting kli as its agent.

This page documents the command, its client configuration, and the exact surface it carries. For the install paths behind the `kli` binary, see [Install cairn](/cairn/get-started/install-cairn).

## The command

```text
kli mcp-serve cairn
```

The invocation is `kli mcp-serve <extension>`, where `<extension>` is the name of an extension built into the kli image — here, `cairn`. The process speaks MCP over stdio, reading requests on stdin and writing responses on stdout — the transport every MCP client uses to launch a server. On launch it prints no banner to stdout; stdout carries JSON-RPC only, every diagnostic goes to stderr, and the process blocks waiting for the first request — a clean start goes quiet rather than printing anything. It serves until the client closes the connection.

| Element | Value | Notes |
| --- | --- | --- |
| Binary | `kli` | The same `kli` you install the extension into. See [Install cairn](/cairn/get-started/install-cairn). |
| Subcommand | `mcp-serve` | Runs the named extensions as an MCP server. |
| Argument | `cairn` | The extension to expose. One process serves only the extensions you name. |
| Transport | stdio | Requests on stdin, responses on stdout; diagnostics on stderr. |
| Scope | one client | One `mcp-serve` process serves a single client. |

The working directory the client launches `kli` in selects the project whose task graph cairn opens. There is no separate database flag; the project is the directory.

## Client configuration

Claude Code, Claude Desktop, and Cursor read the same `mcpServers` block. The canonical entry is:

```json
{
  "mcpServers": {
    "cairn": {
      "command": "kli",
      "args": ["mcp-serve", "cairn"]
    }
  }
}
```

| Field | Value | Meaning |
| --- | --- | --- |
| `command` | `kli` | The binary the client spawns. |
| `args` | `["mcp-serve", "cairn"]` | The subcommand and the extension to expose. |

The client spawns this process, lists its tools, and routes tool calls to it, picking up a newly added entry on its next restart.

## Exposed surface

`mcp-serve` exposes one extension's surface and nothing else. Naming `cairn` gives the client cairn's surface alone; no other extension's tools, prompts, or resources travel on the same process. The surface is the same regardless of which client connects.

### Tools

The fourteen cairn tools appear as MCP tools, each gated by the capability it declares. The full per-tool reference — parameters, return text, and semantics — is in [Tools](/cairn/reference/tools).

| Capability | Tools |
| --- | --- |
| `:cairn/observe` | `observe` |
| `:cairn/write` | `task_create`, `task_fork`, `task_link`, `task_sever`, `task_set_metadata`, `task_update_status`, `handoff`, `task_query_write` |
| `:cairn/read` | `task_search`, `task_get`, `timeline`, `task_query`, `task_bootstrap` |

The serve subject holds exactly the capabilities its exposed tools declare, so the `:cairn/read` / `:cairn/write` / `:cairn/observe` split applies over MCP just as it does in kli. The capability each tool declares is the gate; the tool name is not. A read-only client never reaches `task_query_write` or any other write tool. See [Reads, writes, and capabilities](/cairn/concepts/reads-writes-and-capabilities).

### Prompts

Seven MCP prompts travel on the process: the six cairn-method workflow prompts plus the `cairn-method` skill, which the serve loop lists as a prompt as well as a resource. They carry the documentarian-and-TDD discipline of the cairn-method into the client's prompt picker.

| Prompt | Stage of the loop |
| --- | --- |
| `research` | Read the ground before changing it. |
| `plan` | Structure the work as a graph of phases. |
| `implement` | Do one phase with the discipline it asks for. |
| `validate` | Check the phase against its acceptance. |
| `handoff` | Write the resumable summary. |
| `resume` | Read the stones and pick the work back up. |
| `cairn-method` | The whole method, expanded as a prompt. |

The six workflow prompts are the named loop; see [The cairn-method](/cairn/concepts/the-cairn-method) for how they compose. The seventh, `cairn-method`, is the bundled skill surfaced in the prompt list.

### Resources

Every prompt and the skill are also served as readable MCP resources — seven in all, each a markdown body the model reads straight off the prebuilt prompt or skill. The workflow prompts are advertised at `cairn://prompts/<name>` (for example `cairn://prompts/research`), and the skill at `cairn://skills/cairn-method`; the scheme is the extension name. A client that reads the skill resource gets the method in full — the bootstrap-observe-handoff heartbeat and the discipline wrapped around it — as text the model can consult mid-task.

## What stays kli-only

Three things kli provides do not travel over the tool protocol, because kli supplies them as the host rather than as MCP surface. A plain MCP client does not get them.

- **Slash commands.** `/observe`, `/handoff`, `/task`, `/tasks`, `/workon`, and `/where` are registered under a kli command provider, not as MCP tools, so an MCP client cannot invoke them. See [Slash commands](/cairn/cli/slash-commands).
- **Per-turn context injection.** Inside kli, the current task's live state — its status and its open handoffs — is folded into the model's view on every turn. Over MCP the client calls `task_bootstrap` itself to stay oriented.
- **Compaction folding.** When kli compacts a long conversation, the observations and handoffs from the dropped span are folded into the summary so the durable markers survive the cut. An MCP client manages its own context window, and its compaction does not know about those markers.

The data surface is identical either way: writes append events and fold into the same queryable projection no matter which client made them, so a graph built over MCP reads back exactly as one built inside kli.

## What a connected server reports

A connected server advertises the fourteen tools listed above, among them `task_bootstrap`, `task_create`, `observe`, `task_query`, and `task_search`.

`task_bootstrap` reads the live graph. In a fresh project with no current task set, it reports that there is nothing to orient on rather than failing:

```text
No task to bootstrap; pass task_id or select a task first.
```

That message means the tool surface is wired and the project's graph is empty — the state a first session starts from. In a project that already has tasks, `task_bootstrap` returns state, neighbors, open handoffs, and recent observations. Either result means the server is connected and reading the right project.

## Related

- [Install cairn](/cairn/get-started/install-cairn) — the declarative and runtime install ledgers behind the `kli` binary.
- [Tools](/cairn/reference/tools) — the full per-tool reference for the fourteen exposed tools.
- [Reads, writes, and capabilities](/cairn/concepts/reads-writes-and-capabilities) — the capability boundary that carries over MCP.
- [Slash commands](/cairn/cli/slash-commands) — the kli-host steering surface that does not travel over the protocol.
