---
title: MCP
icon: custom/MCP
description: Tools the OpenKnowledge MCP server exposes to AI agents.
---

The MCP server gives AI agents structured access to your knowledge base. Two reads are server-free: `exec` (shell-style reads, fs-direct against the disk) and `preview_url` (reads `ui.lock` directly) both work even when the editor is down. Every other read tool (`search`, `links`, `history`, etc.) and all write tools route through the Hocuspocus server, which OpenKnowledge starts for you on the first write.

The surface is **17 tools**. Three of the four write verbs — `write`, `edit`, `delete` — are native CRUD operations polymorphic over a target (`document`, `folder`, `template`, `asset`): per-target fields nest inside the address key (`write({ document: { path, content } })`), and you pass exactly one target per call. `move` is the fourth write verb but takes flat `from`/`to` paths and auto-detects whether the path is a document, folder, or asset (no `template` target).

## Tools

| Tool | Purpose |
| --- | --- |
| `exec` | Read-only shell (`cat`, `ls`, `grep`, `find`, `head`, `tail`, `wc`, `sort`, `uniq`, `cut`); reads return frontmatter, backlinks, and recent history. Fs-direct; works without the server. |
| `search` | Ranked workspace search (title boost + body BM25 + recency; same engine the cmd-K palette uses). When [semantic search](/docs/reference/configuration#semantic-search) is enabled, an embeddings signal is additionally fused into `full_text` ranking (opt-in, content egress) — pass `semantic: false` to force pure-lexical. |
| `links` | Wiki-link graph. `kind` selects: `backlinks`, `forward`, `dead`, `orphans`, `hubs`, or `suggest`. Accepts an array (e.g. `["dead", "orphans", "hubs"]`) to fetch several views in one call; each view nests under its own key in the response |
| `history` | Version timeline for a doc. Each entry carries a `version` (commit SHA) you pass to `restore_version` |
| `config` | Read the effective merged config (`config({ key: "appearance.theme" })` for a sub-tree; omit `key` for the whole config) |
| `palette` | Markdown-native authoring forms, themed `html preview` embed starters, and theme tokens. Pass `components` for the canonical components' full JSX prop schemas |
| `preview_url` | Resolve the browser-reachable preview URL. Per-response `previewUrl` fields elsewhere are route-only (`/#/<doc>`); call this when you need the full openable URL |
| `share_link` | Build a GitHub-substrate share URL for a doc to send to a teammate (read-only against `.git/`; never publishes) |
| `write` | Create or overwrite a `document`, `folder`, `template`, or `asset`. For a document: `{ path, content }`, or `{ path, template }` to instantiate from a folder template. `position` selects `replace` (full rewrite; the only mode that touches frontmatter), `append`, or `prepend` |
| `edit` | Modify a `document` (body find/replace **or** a frontmatter merge-patch), a `folder` (frontmatter merge-patch), or a `template` |
| `delete` | Delete a `document` (one path or an array), `folder`, `template`, or `asset` |
| `move` | Move or rename a `document`, `folder`, or `asset` and rewrite every affected link |
| `checkpoint` | Save a project-wide version snapshot — a single restore point. Returns its `version` |
| `restore_version` | Restore one document to a historical `version` (the SHA from `history` or `checkpoint`) |
| `conflicts` | Read GitHub-sync merge conflicts. `kind: "list"` enumerates tracked conflicts; `kind: "content"` returns one file's base / ours / theirs stages |
| `resolve_conflict` | Write a chosen resolution (`mine` / `theirs` / `content` / `delete`) and commit |
| `workflow` | Procedural guides. `kind` selects: `ingest` (capture a source), `research` (gather + write provisional findings), `consolidate` (promote research to a canonical article), or `discover` (onboard an existing repo) |

## Output shape mirrors the input

The write verbs nest their result under the same target key you wrote, mirroring the input: `write({ folder })` returns `{ folder: { ok, path } }`, `edit({ document })` returns `{ document: { … } }` (with any `contentDivergence`), and a batch returns `{ documents: [ … ] }`. The uniform preview envelope (`previewUrl`, `previewUrlSource`, `warning`) always stays at the top level — every tool surfaces it the same way. `conflicts` and `links` nest the same way under their `kind`.

## Instantiating from a template

`write` accepts a `template` field on the `document` target — `write({ document: { path, template } })` — that resolves against the cascade of templates available for the target document's parent folder, using the same folder-up walk the [Folders and templates](/docs/advanced/folders-and-templates#templates) page describes. The template body becomes the new document's content; the template's own info block (its name and description) is stripped, so it doesn't bleed onto the document.

`content` and `template` are mutually exclusive. With `template`, `position` is forced to `replace` (initial create semantics).

## Editing frontmatter

Use `edit({ document: { path, frontmatter } })` for frontmatter edits: it applies a JSON Merge Patch (set or create a key with a value, delete a key by passing `null`). A document body find/replace (`edit({ document: { path, find, replace } })`) is body-only and refuses patterns that touch frontmatter; `write` with `position: "replace"` is the only write mode that includes the `---\n…\n---` block (other positions ignore any frontmatter in the payload). Folders and templates take frontmatter the same way: `edit({ folder: { path, frontmatter } })`.

## Edit summaries

The write tools (`write`, `edit`, `move`, `checkpoint`) accept an optional `summary` describing the intent of the edit, e.g. `"Fixed token-refresh race"`. Summaries appear on the document's timeline so readers can scan recent agent activity.

Cap is 80 characters. Avoid secrets and PII; summaries persist to git history.

## Conflict-aware writes

Every mutating tool (`write`, `edit`, `delete`, `move`, `restore_version`, and agent undo) refuses to mutate a doc whose GitHub-sync state is `conflict`.

To recover, call `conflicts({ kind: "content", file })` to inspect the merge stages, then `resolve_conflict` with one of:

- `mine`: resolve to your committed version (stage 2 — runs `git checkout --ours <file>` then `git add`).
- `theirs`: resolve to their committed version (stage 3 — runs `git checkout --theirs <file>` then `git add`).
- `content`: write the exact bytes you supply (for example, a merged result you composed by reading both stages).
- `delete`: `git rm` the file (for delete-vs-modify shapes where one stage is missing).

To detect conflict state proactively without waiting for a 409, call `conflicts({ kind: "list" })`; it enumerates every conflicted doc with its `lifecycle: { status, reason }`. `exec("cat …")` also returns that `lifecycle` field for any doc.

## Preview links

Read and write tools return a `previewUrl` for any doc they touched, but **those are route-only** (`/#/<doc>` with no host:port), meant to identify the doc, not to be opened as-is. Hosts that want to open the editor (Claude Code Desktop's `preview_start`, terminal `open <url>`) call `preview_url` to resolve the full URL once per session.

`preview_url` always carries an `autoOpen` boolean (top-level on its response) reflecting the user's [`appearance.preview.autoOpen`](/docs/reference/configuration) preference. The write tools (`write`, `edit`) carry the same boolean on the `warning` object, which fires only when no browser is attached to the preview. In the common case (a browser is attached), the write response has no `warning` and no `autoOpen` field. Agents honor `autoOpen` before navigating: `true` (default) follows the host-capability routing in the bundled skill; `false` means the user is managing their own preview window, so the agent surfaces the URL on request but does not open or refresh anything. The value is resolved fresh on every tool call, so a mid-session toggle propagates within 0–1 calls, with no client restart.
