Content
<p align="center">
<a href="https://okfgem.com">
<picture>
<source media="(prefers-color-scheme: dark)" srcset=".github/hero-dark.png">
<img src=".github/hero-light.png" width="100%" alt="okf: somewhere for your project's reasoning to live between agent sessions. Everything OKF, in one ecosystem: author, curate, and consume your project's knowledge, with your agent. 100% local. Start at https://okfgem.com/#try. The pieces, top to bottom: the Agent Skill (the brain) authors, curates and consumes, and writes the bundle (the memory) — Markdown + YAML, in your repo. The bundle is read by, and by nothing else, the library (the spine): require okf, the only thing that touches disk. Five surfaces sit over it — the CLI (the muscle) for validate, lint and search; the Graph (the vision), live or static; MCP (the nerve), any host, 14 tools; the TUI (the hands), six views over any bundle; and Pro (the guard), three doors, all of them closed. Available from RubyGems, as a Docker image, and as a Claude Code plugin, speaking OKF v0.2.">
</picture>
</a>
</p>
<p align="center">
<a href="https://rubygems.org/gems/okf"><img src="https://img.shields.io/gem/v/okf" alt="Gem version"></a>
<a href="https://rubygems.org/gems/okf"><img src="https://img.shields.io/gem/dt/okf" alt="Downloads"></a>
<a href="https://github.com/serradura/okf/pkgs/container/okf"><img src="https://img.shields.io/badge/ghcr.io-okf-2496ED?logo=docker&logoColor=white" alt="Docker image"></a>
<a href="https://github.com/serradura/okf/actions/workflows/main.yml"><img src="https://github.com/serradura/okf/actions/workflows/main.yml/badge.svg" alt="CI"></a>
<a href="LICENSE.txt"><img src="https://img.shields.io/badge/license-Apache--2.0-blue" alt="License: Apache-2.0"></a>
<a href="gems/okf/lib/okf/skill/reference/SPEC.md"><img src="https://img.shields.io/badge/OKF-v0.2-6E56CF" alt="OKF v0.2"></a>
<a href="#claude-code-plugin"><img src="https://img.shields.io/badge/Claude%20Code-plugin-D97757" alt="Claude Code plugin"></a>
</p>
<p align="center">
<b><a href="https://okfgem.com">Site</a></b> ·
<b><a href="https://okfgem.com/docs/">Docs</a></b> ·
<b><a href="https://demo.okfgem.com">Live demo</a></b> ·
<b><a href="https://claude.okfgem.com">Claude plugin</a></b> ·
<b><a href="https://docker.okfgem.com">Docker image</a></b>
</p>
Your coding agent works out how your system fits together — why the service
exists, what the metric actually measures, which line of the schema is
load-bearing — and then the session ends and all of it is gone. Next session it
works the same things out again, from the same code, and reaches slightly
different conclusions.
**okf gives that reasoning somewhere to live.** Plain Markdown files in your
repo, next to the code they explain, written and kept current by the agent
itself rather than by you.
It adds nothing to your stack. No database, no service, no new place to keep
knowledge — just files, reviewed in the same pull request as the code. If you
stop using okf tomorrow, everything it wrote is still Markdown your team can
read.
### See it in sixty seconds
This repository documents itself in OKF, so you can walk a real bundle before
installing anything:
```bash
gem install okf
git clone https://github.com/serradura/okf && cd okf
okf server .okf # the whole ecosystem as an interactive graph
```
No Ruby on the machine? The published image runs the same commands —
[docker.okfgem.com](https://docker.okfgem.com). Or skip the clone entirely and
open [demo.okfgem.com](https://demo.okfgem.com).
### Why it doesn't rot
Notes decay because keeping them current is a separate act from doing the work.
Here it isn't:
- **The agent writes it, not you.** An Agent Skill ships with the gem, so
curation happens inside the work rather than after it.
- **Drift is a failing build.** `okf validate` and `okf lint` return exit codes,
so a stale or malformed bundle breaks CI the same way a broken test does.
- **The agent reads only what it needs.** `okf index` reads the map and
`okf search` pulls the handful of files a task touches, so the knowledge
outgrows the context window instead of filling it.
### How it compares
Knowledge already has several homes near an agent, and each holds something
different. None of the others is built for curated, durable team knowledge:
| | OKF bundle (this) | `CLAUDE.md` / `AGENTS.md` | Agent auto-memory | Wiki / Notion |
| ------------------------------ | ----------------------------------------------------- | -------------------------- | ------------------------ | ---------------- |
| Holds | curated team knowledge | standing instructions | what one agent picked up | human docs |
| Versioned with the code | ✅ | ✅ | ❌ | ❌ |
| Portable across agents | ✅ plain Markdown + YAML | ⚠️ per-harness conventions | ❌ per-agent store | ⚠️ export needed |
| Typed and queryable | ✅ frontmatter + graph | ❌ prose | ❌ | ⚠️ partially |
| Reviewed in PRs | ✅ | ✅ | ❌ implicit | ⚠️ rarely |
| Scales past one context window | ✅ progressive disclosure<br>(`okf index` + `search`) | ❌ loaded whole | ⚠️ partially | n/a |
| Checked by tooling | ✅ exit codes for CI<br>(`okf validate` + `lint`) | ❌ | ❌ | ❌ |
The last two rows are this gem's job.
[OKF][okf] is an open, vendor-neutral format (Google Cloud, 2026). This
repository is a complete implementation of it, distributed as four gems, a
Docker image, and a Claude Code plugin.
[okf]: https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing
## What a bundle looks like
A bundle is just a directory; each concept is one Markdown file whose path is its
id. This repo documents _itself_ in OKF, so the tree below is real:
```
.okf/
├── index.md # progressive-disclosure map (root carries okf_version)
├── log.md # ISO-dated change history, newest first
├── overview.md
├── gems/okf-mcp.md # one concept = one file
├── decisions/monorepo-layout.md
└── format/frontmatter.md
```
The only hard requirement is YAML frontmatter with a non-empty `type`; everything
else is optional and tolerated when missing. A concept reads as below — this is
the real `capabilities/graph-server.md` from the baseline gem's own bundle,
`gems/okf/.okf/`, with its body trimmed:
```markdown
---
type: Capability
title: Interactive graph server (server)
description: A self-contained HTML knowledge graph — served over HTTP as a mountable Rack app, one bundle or many behind a hub, or written to a single static file.
resource: gems/okf/lib/okf/server/app.rb
tags: [server, graph, rack, diagram]
generated:
by: human:maintainer
at: 2026-08-13T12:00:00Z
---
# Overview
`okf server` boots an interactive view of the [graph](../model/graph.md) …
```
The `.okf/` above is the **ecosystem's** map — a concept per gem, per plugin
item, per skill — and each gem carries its own bundle beside its code. Clone the
repo and run `okf server .okf` to browse the map as an interactive graph, or
`okf server gems/okf/.okf` for the baseline gem's.
### Trust, provenance, and lifecycle — OKF v0.2
Knowledge written continuously by agents raises questions a static corpus never
had to answer: who wrote this, who checked it, is it still current? OKF v0.2
makes them frontmatter — `generated` (who produced the content, and when),
`verified` (who confirmed it, deriving the trust tier every surface shows:
unverified · machine-confirmed · human-reviewed), `sources` with per-claim
footnote attribution, `status`, and `stale_after` — and this gem reads all of
it: as [catalog columns and `--status`/`--trust` filters](https://okfgem.com/docs/),
as the [graph page](#the-graph)'s third visual channel, and as
[lint](https://okfgem.com/docs/cli/lint/)'s provenance, attestation and
migration findings. Every family is optional, and a v0.1 bundle keeps reading
forever — two `lint` findings tell you exactly what a migration would change,
and never fail you for not having done it.
## The whole ecosystem
Knowledge an agent writes dies in four places, and a tool that fixes one of them
only gets to watch it die in the next. **It never gets written**, because writing
it up is a separate act from doing the work. **It rots**, and nothing says so
until someone acts on a claim that stopped being true. **It cannot be found**,
because the corpus outgrew the person who would have to read it all. And **it is
stuck** in whichever tool wrote it, so the next tool starts over.
The pieces below are one answer per failure. They are separate gems because they
*install* separately, not because they are separate products: every one of them
reads the same folder of Markdown, none of them is required by any other, and
what you would lose by dropping all of them is tooling, never the knowledge.
One install — `gem install okf` — carries three pieces:
- an **Agent Skill**, so the knowledge gets written at all: your agent curates
inside the work rather than promising to write it up afterwards, and you stay
the editor;
- a **CLI and Ruby library**, so you can ask the corpus a question instead of
reading it — what is in here, which types and which tags, what links to what,
what nothing links to, where the term you half-remember appears — and so drift
is a failing build rather than a feeling: `validate` and `lint` answer with
exit codes CI already knows how to fail on;
- a **Graph**, so the shape of what the team knows is a thing you can look at —
live on your machine, or one self-contained HTML file you can host anywhere or
hand to someone who will never install this.
Three sibling gems extend that same command rather than adding another one:
- **`okf mcp`** ([okf-mcp](gems/okf-mcp/README.md)), so the knowledge is not stuck in whichever terminal wrote it: any MCP host reads it with no shell and nothing pasted into context — fourteen read tools, over stdio or Streamable HTTP;
- **`okf tui`** ([okf-tui](gems/okf-tui/README.md)), so looking around costs a keystroke instead of four commands: six views over one bundle or every registered one, and you can read one while searching all of them;
- **`okf pro`** ([okf-pro](gems/okf-pro/README.md)), so the practice holds on the days nobody is watching: it writes an agent's knowledge repository and then refuses to let it rot, at three doors that each fail closed.
`gem install okf-pro` and you type `okf pro`. Packaging multiplies; the
interface does not, and a sibling ships no second binary to learn.
### The second bundle costs nothing
Nobody stops at one. The service you documented last month, the team handbook,
the gem you maintain on the side — each is its own bundle in its own repository,
and that is the right answer rather than a filing problem to clean up later.
So a bundle gets a **name**. `okf registry set ./handbook` makes it `@handbook`,
and anywhere a directory goes a `@slug` goes: `okf lint @handbook`, `okf render
@handbook -o graph.html`. Groups collect the ones you think about together, and
`@all` reaches every one you have registered — so the same four commands hold
your whole corpus at once instead of one bundle of it:
```bash
okf search @all "rate limit" # every bundle, ranked together in one list
okf server # all of them behind one hub, in the browser
okf tui # all of them in one terminal UI
okf mcp # all of them, to any MCP host
```
A project-local `.okf.json` replaces the machine-wide registry while you stand
inside that repository. That is how this monorepo addresses its own five bundles
as `@okf-eco`, `@okf`, `@okf-mcp`, `@okf-tui` and `@okf-pro` without anyone's
`~/.okf` ever hearing about them.
## How the pieces fit together
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset=".github/overview-dark.png">
<img src=".github/overview-light.png" width="760" alt="The pieces, end to end: the Agent Skill (your coding agent authors and curates, you stay the editor) writes and maintains the bundle, a folder of Markdown + YAML in your repo where one concept is one file, links between files are the knowledge graph, and frontmatter says who wrote it, who checked it and when it goes stale. The bundle is read by — and by nothing else — the library (require okf), which reads, validates and indexes it and is the only thing that touches disk. Two surfaces come in the same install, gem install okf. The CLI, to ask the corpus and gate the merge: validate (legal OKF per section 11), lint (curated and fresh), search (find it, ranked), index / stats / types / tags (what is in here), registry (bundles addressed as @slug). The Graph, the shape of what the team knows: okf server (live), okf render (static HTML you can host anywhere), OKF::Server::App (the Rack app for one bundle), OKF::Server::Hub (the Rack app for every bundle), and untrusted bodies sanitized. Three more arrive through the plugin seam, each its own gem and no second binary. The MCP server (okf mcp, the okf-mcp gem): 14 read tools for any MCP host, reads and never writes, stdio or http with no CLI in the loop, every answer bounded for a context window. The Terminal UI (okf tui, the okf-tui gem): six views switched with number keys — bundles, browse, search, graph, health — read one while you search all of them, and the registry edited in place. OKF Pro (okf pro, the okf-pro gem): writes a whole knowledge repository, a board and a journal and a roadmap, held at three doors — agent, commit, CI — every one of which fails closed. The CLI runs the checks and retrieves the data the Agent Skill acts on. 100% local, Ruby 2.4 or newer, only rack, webrick and minifts as dependencies, Apache-2.0.">
</picture>
</p>
_Everything above the first divider is what one `gem install okf` gives you.
Everything below it arrives through the same plugin seam, one gem at a time, and
every door is listed in
[What is in this repository](#what-is-in-this-repository)._
> [!TIP]
> **Browse this repository as knowledge, not just docs.** This README is the
> front door; the depth lives in the five OKF bundles it carries. Start at the
> [ecosystem map](.okf) — the [gems](.okf/gems/), the [plugin](.okf/plugin/),
> the [skills](.okf/skills/), the [decisions](.okf/decisions/) and the
> [format itself](.okf/format/) — then open a gem's own bundle for its code:
> [`gems/okf/.okf/`](gems/okf/.okf). Run `okf server .okf` to walk the map as an
> interactive graph, or `okf search @all <term>` to reach every bundle at once.
**It installs on the Ruby your OS already ships** — every Ruby since 2.4, three
small dependencies, no native extension and no build step — so there is nothing
to provision and nothing to keep up to date. The
[design constraints](gems/okf/.okf/design/) that hold that line are enforced by
tests on every supported Ruby.
## What is in this repository
Every top-level name is a boundary, and the whole menu is one row each. A
directory under `gems/` is a gem, named for the gem it ships; everything else at
the root is named for what it is.
| Door | What lives there |
| ---- | ---------------- |
| [`gems/okf/`](gems/okf/README.md) | the `okf` gem — the agent skill, the CLI and library, ranked search, the graph. Everything above describes this one |
| [`gems/okf-mcp/`](gems/okf-mcp/README.md) | `okf mcp` — the MCP server over the same kernel: 14 read tools, any MCP host |
| [`gems/okf-tui/`](gems/okf-tui/README.md) | `okf tui` — the full-screen terminal UI, over one bundle or every registered one |
| [`gems/okf-pro/`](gems/okf-pro/README.md) | `okf pro` — writes an agent's knowledge repository, then enforces it at three doors |
| [`plugin/`](#claude-code-plugin) | the Claude Code plugin: that skill, `/okf:gem`, and a post-edit curation hook |
| [`.claude-plugin/`](.claude-plugin) | the marketplace manifest — this repository is its own marketplace |
| [`skills/`](#the-skill-without-the-gem) | the skills a generic installer reads: `okf`, and `okf-principles` |
| [`resources/`](resources/ci/github/README.md) | copy-paste recipes — today, CI that validates and lints your bundles on every push |
| [`.okf/`](.okf) | the ecosystem map: a concept per gem, per plugin item, per skill — plus the decisions and the format |
| [`.okf.json`](.okf.json) | every bundle in this tree, addressable as `@slug` from anywhere in it |
| [`Dockerfile`](Dockerfile) | builds the published image from `gems/okf/`, from a root build context |
| [`.github/`](.github/workflows) | the CI workflows, and the images this page renders |
| [`.claude/`](.claude/CLAUDE.md) | one line, pointing Claude Code at [`AGENTS.md`](AGENTS.md) |
## The graph
<picture>
<source media="(prefers-color-scheme: dark)" srcset=".github/server-dark.png">
<img src=".github/server-light.png" alt="The okf graph server: a force-directed knowledge graph with a concept selected, its neighbors highlighted and the rest of the bundle dimmed, and the inspector panel showing the concept's type, description, tags, and every concept it links to and from, each labelled with its type.">
</picture>
_The graph server on this repo's own [`.okf`](.okf) bundle, with the `overview`
concept selected. Try it live at
**[demo.okfgem.com](https://demo.okfgem.com)**._
What the page does, and how `okf render` bakes the same thing into one static
file: [`gems/okf/README.md`](gems/okf/README.md#the-graph).
## Claude Code plugin
This repository doubles as a Claude Code plugin marketplace, so the whole
toolchain installs with two commands inside Claude Code:
```
/plugin marketplace add serradura/okf
/plugin install okf@okfgem
```
The plugin carries three pieces: the [`okf` skill](gems/okf/README.md#the-agent-skill);
**`/okf:gem`**, a front door that hands its arguments to the skill unchanged (no
arguments: it orients on your bundle and recommends the next move, never
auto-runs); and a **curation hook** that runs `okf validate` + `okf lint` after
every edit inside a bundle and returns the findings as context. The checks are
the CLI's own, so the feedback is deterministic.
The hook stays silent outside bundles, and it is config-free to switch off:
`OKF_CURATE_DISABLED=1` turns it off, `OKF_CURATE_QUIET=1` keeps the findings
without the install suggestion, and an `<!-- okf-disable -->` comment skips one
file.
Prefer no plugin? `gem install okf && okf skill .claude` installs the skill
alone, and the skill itself instructs the agent to run the same checks after
editing a bundle.
## The skill, without the gem
**Without the gem**, any agent that reads `SKILL.md` installs it straight from
this repository:
```bash
npx skills add serradura/okf # choose from the list
npx skills add serradura/okf --skill okf -a codex # or name skill and agent
```
That path installs a generated copy — `rake skill:sync` writes it from the same
canonical tree the gem ships, and the build fails on any drift — so it tracks
this repository rather than the `okf` on your machine. `okf-principles` sits
beside it: the five structural principles the format implies, written to be
pointed at any instruction artifact rather than at a bundle.
## Extending okf, and running it safely
Publish a gem named `okf-*` carrying an `okf/plugin.rb` and installing it is the
whole installation: your verb answers to `okf` and behaves like a built-in.
Nothing an addon registers can displace one, and a broken addon is skipped rather
than taking the CLI down. The three siblings above arrive exactly this way —
`okf-mcp`, `okf-tui` and `okf-pro` each ship an `okf/plugin.rb` and no
executable of their own — and none of them needs a line of the baseline to know
it exists. Yours would be the fourth, on the same terms.
Contract and threat model:
[extension points](.okf/design/extension-points.md).
The graph page treats a bundle as untrusted content: inlined data is escaped, and
every concept body is sanitized before it reaches the DOM, so a script hidden in
Markdown is stripped rather than run. It still loads libraries from a CDN, so
treat an unfamiliar bundle the way you would treat any document from a source you
do not know. Full write-up:
[server trust boundary](gems/okf/.okf/design/server-trust-boundary.md).
## Development
From the repo root — plain `rake`, there is no root Gemfile:
```bash
rake # every gem's default task (tests + RuboCop), then the repo-level lint
rake test # every gem's test suite
rake okf # validate + lint every registered .okf bundle
rake serve # browse this project's own bundle as a graph
```
From any gem's directory, for work on that gem — `cd gems/okf-mcp`, `cd
gems/okf-tui` or `cd gems/okf-pro` follows the same three commands, and each has
its own README and CI job. From `gems/okf`, for work on the baseline itself:
```bash
cd gems/okf
bin/setup # install dependencies
bundle exec rake # tests + RuboCop (what CI runs)
bundle exec rake test # just the test suite
ruby -Ilib exe/okf validate <dir> # run the CLI from a checkout
```
The suite runs on every supported Ruby; to check the 2.4 floor locally, from the
repo root:
```bash
docker run --rm -v "$PWD":/src:ro ruby:2.4 bash -c \
"cp -a /src /build && cd /build/gems/okf && rm -f Gemfile.lock && bundle install --quiet && bundle exec rake test"
```
The graph page has its own suite in a real browser (`bundle exec rake
browser:setup`, then `rake test:browser`, both from `gems/okf/`). See
[AGENTS.md](AGENTS.md) for the maintainer guide.
## Contributing
Bug reports and pull requests are welcome on GitHub at
<https://github.com/serradura/okf>. This project is intended to be a safe,
welcoming space for collaboration, and contributors are expected to adhere to
the [code of conduct](CODE_OF_CONDUCT.md).
## License
The gem is available as open source under the terms of the
[Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) (see
`LICENSE.txt`). The Open Knowledge Format specification bundled with the skill
is authored by Google Cloud Platform and included under its own Apache-2.0
license, Copyright (c) Google LLC. See `NOTICE` and
`okf/lib/okf/skill/reference/APACHE-2.0.txt`.
[okf-skills](https://github.com/scaccogatto/okf-skills) by Marco Boffo, a Python
OKF toolkit for Claude Code with a feature-rich interactive graph view, was an
early inspiration for this gem's Claude Code plugin and for the knowledge-as-code
comparison in [How it compares](#how-it-compares). okf takes a different shape: a Ruby-native
gem built around the `okf` CLI and an embeddable library.
Connection Info
You Might Also Like
No recommendations available