Overview
A multi-tenant store for Open Knowledge Format bundles, built so an agent spends as few tokens and as few round trips as possible reading them.
OKF is a good authoring format. A directory of Markdown with YAML frontmatter, no SDK, no runtime, readable in Obsidian and diffable in git. It is an expensive reading format. The agent pays for full frontmatter on every read, the prose is written for people, and the reference consumption pattern walks the graph one file at a time, spending an inference turn per hop.
langonrock keeps your Markdown as the source of truth and compiles it into a dense read model. A
manifest the agent keeps in its cached prompt prefix, and section-addressable concepts it fetches
in batches. Your bundles stay conformant, so okflint, the visualizer and Obsidian keep working on
the same folder.
What it costs to read
Measured against the OKF reference consumption pattern over the same corpus and the same twenty questions:
| OKF navigator | langonrock | |
|---|---|---|
| Tokens billed for a 20-question session | 116,357 | 64,355 |
| Tool calls | 30 | 17 |
| Tokens for one concept read | 594 | 213 |
| Retrieval, hit rate in the top 8 | 70% | 75% |
The saving comes from the manifest carrying the link graph. The agent knows every id it needs before it fetches anything, so one batched call covers them all, and it can ask for a single section instead of the whole concept. The manifest itself is not smaller than the Markdown it replaces, and retrieval gives nothing back: the store matches the raw files on ranking and passes them on hit rate. Full numbers, including where the store still loses.
Where to start
Installation
Install the binary or run from source with Bun.
Quickstart
Compile a folder of bundles and read it back in four commands.
Use it from an agent
Register the MCP server with Claude Code or Cursor.
Why it is built this way
Where the tokens and the round trips actually go.
What it does
Compiles any Markdown, keeps OKF as the bar. Every file compiles, frontmatter or not, with its
id, summary, title and links derived from the text; --strict is the OKF conformance gate. Your
directory stays the source of truth.
A manifest that fits in the prompt. One dense TSV row per concept: id, bundle, kind, status, grain, summary, outgoing links.
Byte-deterministic output. Identical input compiles to identical bytes, so the manifest stays in the prompt cache across rebuilds.
Section addressing. get(id, { section: "schema" }) returns one slice instead of the whole
document, using the concept's own Markdown headings.
Sliced reads on any document. offset and limit page a long concept, and find returns a
window around a literal phrase plus the offset of every occurrence — sub-document addressing that
works on prose with no headings at all. Over MCP a read is capped at 15,000 characters per concept
by default.
Batched reads. Pass every id you need in one call. N concepts cost one round trip.
Deterministic retrieval. BM25 plus a capped one-hop expansion over the link graph, with no model call anywhere in the path.
Search that points inside the document. Every direct hit carries pos, the offset of the
passage densest in the query's words, so the next get can be a 2,000-character window instead of
the document — no quote required.
Knowledge that expires visibly. A concept past its stale_after date shows stale in the
manifest's status cell, computed at read time so the snapshot bytes never depend on the clock.
Immutable, content-addressed snapshots. A backup is a file copy, a restore is a file copy back, and a rollback is a side effect of naming files by their own hash.
Multi-tenant. A tenant is a directory boundary with its own snapshots and its own index.
Three connection modes, one interface. Embedded, local daemon, or HTTP server, selected by a connection string.
Refuses to leak its own credentials. TCP needs a token, and any address past loopback needs TLS, or the server declines to start.
MCP server. Six verbs for Claude Code, Cursor, or anything else that speaks MCP — four to read and two to write, with tool descriptions that carry the tenant's own numbers: the server measures the manifest at startup and advises manifest-first or search-first.
A model can persist knowledge, safely. write and delete change a concept and recompile
before answering, and a tenant that does not exist yet is created by the first write. Both still
name the version they replace, and the refusal hands back the hash to retry with, so a model
satisfies the precondition without a lost update.
Editable over the network. Create, change and delete concepts through the API, with a mandatory precondition so two editors cannot silently overwrite each other.
No database. Two runtime dependencies, both for MCP.
The shape of a session
An agent reads the manifest once, usually from the cached prompt prefix. It picks ids from the rows it already holds. It fetches them in one call, and only the section it needs.
langonrock manifest --data ./data --tenant acme# tenant: acme
# bundles: ops sales
id bundle kind status grain summary links
deploy ops runbook - - How to ship the orders service. -
customers sales bigquery_table deprecated customer_id Registered customers, including churned. -
orders sales bigquery_table - order_id One row per completed customer order. customersEverything needed to plan the reads is in those rows. A status cell other than - is the concept
telling you it is not current.
langonrock get orders --section schema --data ./data --tenant acmeTwo runtime dependencies
@modelcontextprotocol/sdk and zod, both for the MCP server. Everything else, including YAML
parsing, directory walking, hashing and zstd, comes from Bun.
The editor
langoneditor is the human-facing half: a desktop app for macOS, Windows and Linux that browses the bundle tree, edits concepts as Markdown with a form for the frontmatter the compiler keeps, draws the link graph, searches through the server's BM25 index, and imports or exports bundles as archives or spreadsheets.
It ships the langonrock binary inside it, so nothing else is required to run it. See editing over the network for the API it is built on, and the library for the client it uses.