okf
Integrates with the note corpus's local git repository, optionally committing every write and pushing changes to preserve version history.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Open Knowledge Fabric (OKF)
A personal knowledge base that an AI assistant reads and writes through one MCP server. The notes are plain markdown files with YAML frontmatter, in a git repo you own. Between the assistant and those files sits the Librarian: ordinary, deterministic Python with no LLM in it. It assigns ids, files notes, validates every write against a schema, enforces each note's lifecycle, and searches.
The assistant does the judgment: what to write, what a new note makes false,
how to rerank what search returns. The Librarian does the bookkeeping and refuses
bad writes. Search runs on your machine: word scoring plus a small local
embedding model (bge-small), so your text never leaves the box.
Built by Sumit for his own notes, and run daily against several hundred of them. This repo has the code and a fictional example corpus; no real notes are included.
The note design: three layers
Every note (a node) has three layers, read in this order:
Metadata. Title, type, project, tags, and
asks: up to eight questions a stranger would type when this note is the answer. Search indexesaskslike the summary, so a note can be found by someone who has forgotten its words.Summary: the current state. Up to eight
-bullets. Bullet 1 says what the note is. Each other bullet states one point the note currently makes and ends with→ § <heading>, the section of the body that holds the detail. When a point changes, its bullet says so:(changed 2026-09-02: was 2pm). The summary is rewritten whenever the note changes.Body: the long form. It is never overwritten. Corrections are appended as dated blocks, and a body replacement that would drop existing text is refused unless the caller passes an explicit flag. The body is the history; the summary is the answer of record.
---
id: okf_20260902_064500_d002
type: decision
title: Wholesale orders close at noon the day before
summary: |-
- The current wholesale cut-off: cafés order by noon for the next morning's delivery.
- Noon gives the evening shift the full mix before it starts → § Why
- Replaces the 2pm cut-off (changed 2026-09-02: was 2pm) → § Why
status: active
maturity: established
canonical: true
project: bakery
asks:
- what time do cafés have to order by
- can a café order after lunch
supersedes: okf_20260714_070000_d001
---
# Wholesale orders close at noon the day before
## Why
…Replacing a note does not delete it. The new note supersedes the old one; the
Librarian marks the old note superseded and links both ways. Search then leaves
superseded notes out and tells you history exists.
Related MCP server: Cortex
Quickstart (5 minutes, over stdio)
You need Python 3.11+ and git.
git clone https://github.com/sumit-anfy/open-knowledge-fabric.git
cd open-knowledge-fabric
python3.11 -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m librarian.validate examples/corpus # OK — 0 error(s)The server runs against the bundled example corpus by default: 37 notes from a fictional baker, Rowan, covering every note type. To keep the repo clean while you experiment, work on a copy:
cp -r examples/corpus ~/okf-demoClaude Code:
claude mcp add --transport stdio --env OKF_ROOT=$HOME/okf-demo okf -- "$PWD/.venv/bin/python" "$PWD/server.py"Claude Desktop: add this to claude_desktop_config.json (Settings →
Developer → Edit Config), with absolute paths, then restart Claude Desktop:
{
"mcpServers": {
"okf": {
"command": "/absolute/path/to/open-knowledge-fabric/.venv/bin/python",
"args": ["/absolute/path/to/open-knowledge-fabric/server.py"],
"env": { "OKF_ROOT": "/Users/you/okf-demo" }
}
}
}Then ask Claude things like:
"Brief me: what time do the cafés have to order by, and why did it change?"
"Who owns the bakery?"
"Create a note in garden: the beans failed because they went in too early."
"Run the corpus audit."
The first search downloads the embedding model (about 64 MB) into a local cache.
Until it is ready, and wherever fastembed is not installed, search falls back
to words only and says so (semantic: false).
To start your own corpus, copy examples/corpus/schemas/ into an empty folder,
edit PROJECT_REGISTRY in schemas/type-registry.md to list your own homes,
git init it, and point OKF_ROOT at it. Set OKF_GIT_COMMIT=1 to have every
write committed. All settings are in .env.example.
Run the tests (about 30 seconds). The write tests run on throwaway copies of the example corpus:
.venv/bin/pip install -r requirements-dev.txt
.venv/bin/python -m pytestThe tools
Tool | What it does |
| Search. Returns the best-matching notes with bodies, their neighbours, and what was left out as stale |
| Read one note by id; list by type and status |
| The write path: validated, filed, state machine enforced |
| Check every note against the schema |
| Weekly triage: orphans, stale links, near-duplicates, suggested links |
| Accept or dismiss a suggested link |
| Delete only retired, unlinked notes; hand anything else to a human |
A session note must end with a close-out (Keep / Conflicts / Your call / Tasks), and every ruling it lists must cite the note it is filed in. The server refuses a session note that skips either.
Architecture
Claude (Desktop, Code, claude.ai)
│ MCP: stdio, or HTTP behind TLS with a bearer token or GitHub OAuth
server.py thin FastMCP wrapper: ten tools, auth, no logic
│
librarian/ the deterministic core (no LLM, no network)
validate.py schema + registry, read live from the corpus's own schema notes
store.py the write path: lock, validate as a set, atomic replace,
state machine, supersession, body guard, git commit/push
context.py brief(): hybrid ranking, intent-aware type priors, aliases
embed.py local bge-small embeddings (fastembed, ONNX), cached in ~/.okf
sections.py long notes searched section by section
summary.py the bullet-summary format and its checks
cluster.py after a write: "which neighbours does this make false?"
redundancy.py after a rule is written: "does a canonical note already say this?"
completeness.py session rulings must cite the note they are filed in
audit.py weekly triage, link suggestions, purge candidates
findability.py weekly run of held-out stranger questions, logged as a note
│
your corpus markdown + YAML frontmatter, its own git repo
schemas/ node.schema.md and type-registry.md are themselves notes
okf_web/ Starlette graph explorer and markdown editor, password login
deploy/ systemd units, Caddy, a pull-and-test auto-deploy timerSome design choices:
The vocabulary lives in the corpus. Note types, folders and project homes are YAML blocks inside
schemas/type-registry.md. The validator reads them live; changing your homes is an edit to a note, not to the code.Fail closed. No registry means no writes. HTTP without auth refuses to start. A check that cannot run reports a failure, not a pass.
Search only adds. The embedding layer and the aliases can reorder results or add matches, but never remove a word match. Every score is broken down in the output (
score_lexical,score_semantic,prior), so you can see why a note ranked where it did.Live data stays in its own app. Tasks, spreadsheets and calendars are
resourcenotes that point at them, never copies that go stale.
Retrieval numbers (example corpus only)
python tests/retrieval_report.py prints these. They are measured on the
37-note example corpus with the benchmark in tests/retrieval_benchmark.yaml
(48 questions) and the held-out bank in tests/findability_seed.yaml (20 notes,
two questions each, written without reusing the note's own words).
Words + embeddings | Words only | |
Benchmark top-1 | 46/48 | 44/48 |
Benchmark top-5 | 47/48 | 48/48 |
Held-out questions, top-1 | 15/20 | 5/20 |
Held-out questions, in the default pack of 8 | 20/20 | 14/20 |
Held-out short phrases, in the default pack of 8 | 20/20 | 16/20 |
Read these as a smoke test, not a quality claim: the same person wrote the corpus and the questions, and 37 notes is an easy haystack. The useful signal is the gap between the two columns on held-out wording. That gap is what the embedding layer is for.
What is not built
No LLM inside. The server never calls a model. Summaries,
asks, and the "what does this make false?" review are written by the assistant that calls the tools.No importers. Nothing reads Notion, Obsidian or Apple Notes.
Single owner. One corpus, one owner. Auth decides who gets in, with no per-note permissions, no sharing, and no multi-user editing.
No packaging. Run from a checkout; there is no
pip install okfand no Docker image.No encryption at rest. Notes are plain files. Protect the disk and the repo.
Edges are only links.
relates_tolinks are plain lists. The typed-edge vocabulary in the schema (supports, contradicts, …) is not used yet.Tested on macOS and Linux only. It has not been run on Windows.
Scheduled work is external. The weekly audit is meant to be run by a scheduled assistant task calling
audit_corpus; this repo ships no scheduler beyond the findability run inside the HTTP service.
Licence
MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
Self-hosted AI workspace: semantic RAG document search, long-term memory, and AI chat via MCP.
Personal knowledge graph as an AI memory layer over MCP - read, save, and link your memories.
Persistent memory, knowledge graph, task management and more for AI agents via MCP.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to read and write a local-first knowledge base of plain markdown files in git, with governance gates for safe, hash-anchored edits.1Apache 2.0
- AlicenseNot gradedqualityBmaintenanceA dynamic, governed memory layer for Markdown notes that serves knowledge to AI clients and humans through a secure MCP server, with scoped access, git-audited changes, and optional LLM-powered semantic search.Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables interaction with a local knowledge repository via MCP, providing tools for capturing, indexing, and searching Markdown notes with Git version control and optional semantic search.3 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to persist, search, and evolve knowledge through a Markdown vault with a typed knowledge graph and MCP interface.13 PyPI15Apache 2.0