# Core Concepts (https://openknowledge.ai/docs/reference/core-concepts)

How OpenKnowledge works: the three-layer model, the file system as the database, links and backlinks, the well-connected knowledge base, and attribution.

This page is the precise reference for the ideas the rest of the docs build on. If you want the persuasive tour instead, start with the [Overview](https://openknowledge.ai/docs/get-started/overview); if you want to start using it, see the [Quickstart](https://openknowledge.ai/docs/get-started/quickstart).

## Three layers

OpenKnowledge has three layers working together:

- a surface you edit
- an engine that keeps it consistent
- the files underneath

```html preview
<div style="padding:18px">
  <div class="tl-surfaces" id="surf"></div>
  <div class="tl-arrows">↓&nbsp;&nbsp;&nbsp;↓&nbsp;&nbsp;&nbsp;↓</div>
  <div class="tl-files" id="files">
    <div class="tl-files-t">your-project/ &middot; *.md</div>
    <div class="tl-files-s">plain markdown, versioned by git</div>
  </div>
  <div class="cap">All three operate on the same files. Nothing locks you out.</div>
</div>
<style>
#surf{display:flex;flex-wrap:wrap;gap:8px}
#surf .s{flex:1;min-width:132px;border:1px solid var(--border);border-radius:12px;padding:11px 13px;background:var(--card);transition:border-color .3s,box-shadow .3s;cursor:pointer}
#surf .s .t{font-weight:600;font-size:13px}
#surf .s .d{color:var(--muted-foreground);font-size:11.5px;margin-top:2px}
#surf .s.on{border-color:var(--primary);box-shadow:0 0 0 3px var(--accent-soft)}
#surf .s.on .t{color:var(--accent-ink)}
.tl-arrows{text-align:center;color:var(--muted-foreground);font-size:15px;margin:9px 0}
.tl-files{border:1px dashed var(--border);border-radius:12px;padding:12px 14px;background:var(--card);text-align:center;transition:border-color .3s,box-shadow .3s}
.tl-files.on{border-color:var(--primary);border-style:solid;box-shadow:0 0 0 3px var(--accent-soft)}
.tl-files-t{font:600 13px ui-monospace,monospace}
.tl-files-s{color:var(--muted-foreground);font-size:11.5px;margin-top:2px}
.cap{margin-top:12px;color:var(--muted-foreground);font-size:12.5px}
@media (prefers-reduced-motion:reduce){#surf .s,.tl-files{transition:none}}
</style>
<script>
var data=[["The editor","WYSIWYG markdown, in the app"],["The knowledge engine","any AI agent, over MCP"],["Any text editor","by hand, whenever"]];
var surf=document.getElementById("surf"),files=document.getElementById("files"),nodes=[];
data.forEach(function(s,i){
  var d=document.createElement("div");d.className="s";
  var t=document.createElement("div");t.className="t";t.textContent=s[0];
  var sub=document.createElement("div");sub.className="d";sub.textContent=s[1];
  d.appendChild(t);d.appendChild(sub);
  d.onclick=function(){pinned=true;set(i);};
  surf.appendChild(d);nodes.push(d);
});
var cur=0,pinned=false;
function set(i){cur=i;nodes.forEach(function(n,j){n.classList.toggle("on",j===i);});files.classList.add("on");setTimeout(function(){files.classList.remove("on");},650);}
set(0);
if(!matchMedia("(prefers-reduced-motion:reduce)").matches){setInterval(function(){if(!pinned)set((cur+1)%nodes.length);},1600);}
</script>
```

- [The editor](https://openknowledge.ai/docs/features/editor): The application you see: a beautiful, themeable markdown editor that renders rich extensions (Mermaid, LaTeX, video and asset embeds, callouts, collapsible sections, interactive HTML) and lets you read and write your knowledge base directly.
- [The knowledge engine](https://openknowledge.ai/docs/reference/mcp): The framework underneath: an MCP server that lets any AI agent read and write your knowledge base while keeping front matter consistent, references intact, and the link graph healthy.
- [The content](https://openknowledge.ai/docs/reference/core-concepts#the-file-system-is-the-database): The files underneath: plain markdown in your own project directory, version-controlled by git. This is the durable layer the other two operate on, described in detail below.

All three layers operate on the **same files**. You can edit through the editor, an agent can edit through the knowledge engine's MCP tools, and you can always drop down to any text editor and change the markdown by hand. Nothing locks you out.

Because the knowledge engine is exposed over [MCP](https://modelcontextprotocol.io), it is **agent-agnostic**. Bring Claude Code, Cursor, Codex, OpenCode, OpenClaw, or any MCP-capable client, and any model you have access to.

## The file system is the database

The third layer is the content itself. OpenKnowledge has **no database dependency**. Your knowledge base is plain markdown files in your own project directory, and the only persistence layer is the file system, version-controlled by git.

This means:

- **No lock-in.** Your knowledge is portable markdown you can read, grep, diff, and commit with ordinary tools.
- **Almost nothing to install.** The recommended path is the desktop app (macOS 13 or later, Windows, or Linux); there is no separate database or service to run.
- **The engine is a management layer, not a gatekeeper.** It maintains consistency when you go through it, but editing the raw files yourself is always allowed.

The set of files the engine treats as your knowledge base is the configured content directory. See [Configuration](https://openknowledge.ai/docs/reference/configuration) for where that and other settings live.

## Links and backlinks

Internal cross-references are written with **standard markdown links**. The recommended form is **relative** — `[text](./sibling.md)`, `[text](../folder/doc.md)` — which stays portable across GitHub, Obsidian, VS Code, and published sites. A **root-absolute** form (`[text](/folder/doc.md)`, where the leading slash means the content root) is equally valid and convenient for cross-folder links. The two never mix: never glue `./` onto a content-root path, since `./folder/doc.md` written from a doc already inside `folder/` resolves to the doubled, broken `folder/folder/doc.md` — `write`/`edit` flag exactly this in their `brokenLinks` response. Whenever document A links to document B, OpenKnowledge automatically records the inverse on B: a **backlink** from B back to A.

### Review links after upgrading

A wiki link such as `[[notes/beta.md]]` first checks for a document whose path is exactly `notes/beta.md`. If none exists, OpenKnowledge removes **one** terminal `.md` or `.mdx` (case-insensitive) and resolves `notes/beta`. It does not repeatedly remove suffixes: `[[notes/beta.md.md]]` can fall back to `notes/beta.md`, but not `notes/beta`. If the suffix-free name finds no document, resolution tries the original spelling.

After the original exact-path check, OpenKnowledge fully resolves the suffix-stripped spelling: exact path, case- and punctuation-insensitive slug, folder `index` page (or its same-named page), then matching basename when the link has no slash. Only if that finds nothing does it try the original spelling's fuzzy, folder-index, and basename fallbacks. Without a Markdown suffix, those checks run once on the original spelling. If multiple paths have the same fuzzy slug or basename, the path smallest in UTF-16 code-unit order wins. For example, with `reports/index.md` and `reports-md.md`, `[[reports.md]]` opens `reports/index` before trying the fuzzy match for `reports-md`. An exact, case-matching path avoids a fuzzy tie.

Every exact-path check, in every link form except wiki asset links and embeds (see below), compares names with one identity rule. Document and folder names match case-sensitively. File names (images, PDFs, and other non-markdown files) match case-insensitively. Names that differ only in Unicode normalization are the same name for every kind: `é` stored as one character (NFC) or as `e` plus a combining accent (NFD) matches either spelling, so a link typed on Linux opens a file whose name macOS stored decomposed. Characters that only compatibility normalization would merge, such as the `ﬁ` ligature and `fi`, stay distinct. When two stored names are equivalent, an exact spelling wins; otherwise the name smallest in UTF-16 code-unit order wins.

Markdown and wiki asset links treat folder case differently. A Markdown asset link such as `![cat](./Images/cat.png)` matches each parent folder case-sensitively and only the file name case-insensitively, so it no longer finds `images/cat.png`. A wiki embed such as `![[Images/cat.png]]` still matches its whole path case-insensitively. On macOS and Windows, whose file systems ignore case, a Markdown asset link whose folder case differs from the folder on disk can show as broken after upgrading; correct the folder spelling in the link.

After upgrading, review existing wiki links and shorthand targets that omit a folder, differ only by case or punctuation, or end in `.md` or `.mdx`. Open each link or use the MCP `links` tool with `kind: "forward"` to inspect its resolved destination. If a valid link now opens a different document, replace its target with the intended document's exact path. Use `audit` to find broken links, but do not rely on it to detect a link that still resolves to the wrong document. For new cross-document links, prefer the explicit relative or root-absolute Markdown paths above.

You never write backlinks by hand. They are computed from the links you already write, and together they form the **link graph**: the network of relationships across your knowledge base.

```html preview
<div style="padding:18px">
  <div id="lb"></div>
  <div class="cap">Write the link once; OpenKnowledge records the backlink on the target for you.</div>
</div>
<style>
#lb{display:flex;flex-wrap:wrap;gap:10px;align-items:stretch}
#lb .card{flex:1;min-width:150px;border:1px solid var(--border);border-radius:12px;padding:12px 13px;background:var(--card)}
#lb .card .t{font:600 12.5px ui-monospace,monospace}
#lb .row{font-size:12px;margin-top:8px;color:var(--muted-foreground);opacity:0;transform:translateY(3px);transition:opacity .4s,transform .4s}
#lb .row.on{opacity:1;transform:none}
#lb .row .k{color:var(--accent-ink);font-weight:600}
#lb .mid{align-self:center;color:var(--muted-foreground);font-size:12px;text-align:center;min-width:104px}
#lb .mid .b{margin-top:6px;opacity:0;transform:translateY(3px);transition:opacity .4s,transform .4s}
#lb .mid .b.on{opacity:1;transform:none;color:var(--primary);font-weight:600}
.cap{margin-top:12px;color:var(--muted-foreground);font-size:12.5px}
@media (prefers-reduced-motion:reduce){#lb .row,#lb .mid .b{transition:none}}
</style>
<script>
document.getElementById("lb").innerHTML=
  '<div class="card"><div class="t">login.md</div><div class="row on"><span class="k">link &rarr;</span> [Sessions](./sessions.md)</div></div>'
 +'<div class="mid"><div>you write<br>one link</div><div class="b" id="b">&#x21A9; inverse recorded</div></div>'
 +'<div class="card"><div class="t">sessions.md</div><div class="row" id="bkrow"><span class="k">backlink &larr;</span> login.md</div></div>';
var b=document.getElementById("b"),bk=document.getElementById("bkrow");
function cycle(){b.classList.remove("on");bk.classList.remove("on");setTimeout(function(){b.classList.add("on");},500);setTimeout(function(){bk.classList.add("on");},900);}
cycle();
if(!matchMedia("(prefers-reduced-motion:reduce)").matches)setInterval(cycle,3200);
</script>
```

> **Info**
>
> Backlinks are the payoff of ordinary linking. Every internal link you write earns a backlink on the target for free, so the graph grows as a side effect of normal writing.

## The well-connected knowledge base

"Well-connected" is not a vibe; it has concrete substance:

> **A well-connected knowledge base = backlinks + the link-graph tools (dead / orphans / hubs / suggest) + closed-loop grounding.**

An agent puts all three to work when it retrieves: it searches, greps, and follows backlinks in a loop over your live files, with no vector database. That mechanism is [Agentic search](https://openknowledge.ai/docs/reference/agentic-search).

### Backlinks

The automatic inverse relationships described above. They turn a pile of files into a navigable graph.

### The link-graph tools

The knowledge engine exposes a [`links`](https://openknowledge.ai/docs/reference/mcp) tool whose `kind` selects a view of the graph. Four of these views are how you keep the graph healthy:

| View      | What it surfaces                                                                    |
| --------- | ----------------------------------------------------------------------------------- |
| `dead`    | Links that point at documents that don't exist: broken references to fix or remove. |
| `orphans` | Documents nothing links to: knowledge that's effectively unreachable.               |
| `hubs`    | The most-linked-to documents: the natural centers of gravity in your KB.            |
| `suggest` | Likely-missing links between related documents: connections worth adding.           |

Agents use these to repair and densify the graph as they work, instead of letting it rot.

```html preview
<div style="padding:18px">
  <div id="gt-tabs" class="gt-tabs"></div>
  <div id="gt-nodes" class="gt-nodes"></div>
  <div id="gt-cap" class="cap"></div>
</div>
<style>
.gt-tabs{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
.gt-tabs .tab{font:600 11.5px ui-monospace,monospace;border:1px solid var(--border);border-radius:999px;padding:4px 11px;background:var(--card);color:var(--muted-foreground);cursor:pointer;transition:border-color .3s,background .3s,color .3s}
.gt-tabs .tab.on{border-color:var(--primary);background:var(--accent-soft);color:var(--accent-ink)}
.gt-nodes{display:flex;flex-wrap:wrap;gap:8px}
.gt-nodes .n{border:1px solid var(--border);border-radius:10px;padding:8px 11px;background:var(--card);font:12.5px ui-monospace,monospace;color:var(--muted-foreground);transition:border-color .3s,box-shadow .3s,color .3s}
.gt-nodes .n.hot{border-color:var(--primary);box-shadow:0 0 0 3px var(--accent-soft);color:var(--accent-ink)}
.gt-nodes .n .tag{display:block;font:11px system-ui;margin-top:2px;color:var(--primary)}
.cap{margin-top:12px;color:var(--muted-foreground);font-size:12.5px;min-height:1.2em}
@media (prefers-reduced-motion:reduce){.gt-tabs .tab,.gt-nodes .n{transition:none}}
</style>
<script>
var nodes=["README.md","auth.md","tokens.md","draft.md","old-notes.md"];
var views=[
 {k:"dead",hot:{1:"&rarr; missing.md &#x2717;"},cap:"dead: links pointing at documents that don't exist."},
 {k:"orphans",hot:{3:"nothing links here"},cap:"orphans: documents nothing links to."},
 {k:"hubs",hot:{0:"most linked-to"},cap:"hubs: the natural centers of gravity."},
 {k:"suggest",hot:{1:"relates &rarr; tokens.md",2:"relates &rarr; auth.md"},cap:"suggest: likely-missing links worth adding."}
];
var tabsEl=document.getElementById("gt-tabs"),nodesEl=document.getElementById("gt-nodes"),capEl=document.getElementById("gt-cap"),tabs=[];
views.forEach(function(v,i){var t=document.createElement("div");t.className="tab";t.textContent=v.k;t.onclick=function(){pinned=true;set(i);};tabsEl.appendChild(t);tabs.push(t);});
function set(i){var v=views[i];tabs.forEach(function(t,j){t.classList.toggle("on",j===i);});nodesEl.innerHTML=nodes.map(function(n,j){var tag=v.hot[j]?'<span class="tag">'+v.hot[j]+'</span>':'';return '<div class="n'+(v.hot[j]?' hot':'')+'">'+n+tag+'</div>';}).join("");capEl.innerHTML=v.cap;}
var cur=0,pinned=false;set(0);
if(!matchMedia("(prefers-reduced-motion:reduce)").matches)setInterval(function(){if(!pinned){cur=(cur+1)%views.length;set(cur);}},2400);
</script>
```

### Closed-loop grounding

Every factual claim should trace back to a source **inside** the knowledge base. External material is pulled in and cited locally rather than linked off to the open web, so the knowledge base stays self-contained and auditable. This is the backbone of the source-grounded workflows: see the [LLM wiki workflow](https://openknowledge.ai/docs/workflows/karpathy-llm-wiki) and the [Entity vault (GBrain-compatible) workflow](https://openknowledge.ai/docs/workflows/entity-vault).

> **Info**
>
> OpenKnowledge is unopinionated about which workflow you adopt; these are supported patterns, not requirements. Grounding, backlinks, and the graph tools work the same regardless of how you choose to organize.

## Attribution and collaboration

Every change made through OpenKnowledge is tracked, with **attribution** to whoever made it: a human author or a specific AI agent. The change history is persisted in the file system with no dependency beyond git.

```html preview
<div style="padding:18px">
  <div id="attr"></div>
  <div class="cap">Every edit is attributed — a human or a specific agent — and revertible, with nothing beyond git.</div>
</div>
<style>
#attr{display:flex;flex-direction:column;gap:6px}
#attr .e{display:flex;align-items:center;gap:10px;border:1px solid var(--border);border-radius:10px;padding:9px 12px;background:var(--card);transition:border-color .3s,box-shadow .3s}
#attr .e.on{border-color:var(--primary);box-shadow:0 0 0 3px var(--accent-soft)}
#attr .who{font:600 11px ui-monospace,monospace;border-radius:999px;padding:2px 9px;white-space:nowrap}
#attr .who.h{background:var(--accent-soft);color:var(--accent-ink)}
#attr .who.a{border:1px solid var(--border);color:var(--muted-foreground)}
#attr .sha{font:11.5px ui-monospace,monospace;color:var(--muted-foreground)}
#attr .msg{font-size:12.5px}
.cap{margin-top:12px;color:var(--muted-foreground);font-size:12.5px}
@media (prefers-reduced-motion:reduce){#attr .e{transition:none}}
</style>
<script>
var log=[
 ["a","agent:claude","9f8e7d6","Drafted the overview"],
 ["h","you","a1b2c3d","Fixed the token-refresh race"],
 ["a","agent:cursor","4d5e6f7","Linked auth.md &rarr; tokens.md"],
 ["h","you","b7c8d9e","Promoted to canonical"]
];
document.getElementById("attr").innerHTML=log.map(function(r){return '<div class="e"><span class="who '+r[0]+'">'+r[1]+'</span><span class="sha">'+r[2]+'</span><span class="msg">'+r[3]+'</span></div>';}).join("");
var rows=document.getElementById("attr").querySelectorAll(".e"),cur=0;
function tick(){rows.forEach(function(x,j){x.classList.toggle("on",j===cur);});cur=(cur+1)%rows.length;}
tick();
if(!matchMedia("(prefers-reduced-motion:reduce)").matches)setInterval(tick,1600);
</script>
```

That gives you:

- **A changelog** of every edit across the knowledge base.
- **Point-in-time history.** Revert to any earlier state.
- **Per-author views.** See exactly what one human or one agent changed.

Browse this history and restore earlier versions from the editor's [timeline](https://openknowledge.ai/docs/features/timeline-and-recovery).

Because humans and agents edit the same files through the same tracked layer, collaboration is a first-class property of the system rather than something bolted on.