OKF: Google's open format for agent memory
What Google's Open Knowledge Format is, how its provenance and stale_after fields handle stale and poisoned agent memory, and which OKF tool to pick.
What the Open Knowledge Format is
OKF (Open Knowledge Format) is Google Cloud's specification for storing knowledge as a directory of Markdown files, each with a YAML frontmatter block. For a coding agent, that directory is long-term memory: one file per decision or convention, committed to the same git repository as the code it describes. The spec is small. A file needs one frontmatter key, type. Everything else (where a fact came from, who wrote it, who checked it, and when it expires) is optional metadata that a tool can filter on and a human can read with cat.
Google Cloud published v0.1 in June 2026. Version 0.2 is current as of September 2026 and is the version this guide pins to. The canonical spec lives in GoogleCloudPlatform/open-knowledge-format on GitHub under the Apache 2.0 license. The older copy in GoogleCloudPlatform/knowledge-catalog is frozen, so read the new one. Four independent projects already read and write the format, and the second half of this guide picks between them.
What one OKF file looks like
A bundle is a directory. Every .md file in it, apart from two reserved names, is a concept. index.md is a directory listing and log.md is a chronological history; both are optional. Here is a concept a coding agent might write at the end of a session:
---
type: Decision
title: Session state lives in Redis, not Postgres
description: Why session rows moved out of the main database in July 2026.
sources:
- id: adr-014
resource: /docs/adr/014-session-store.md
title: ADR 014, session store
author: human:ana
last_modified: 2026-07-09T00:00:00Z
generated: { by: claude-code/opus-5, at: 2026-09-10T14:02:00Z }
verified:
- { by: human:ana, at: 2026-09-11T09:30:00Z }
status: stable
stale_after: 2026-12-01T00:00:00Z
tags: [sessions, redis]
---
Session rows were the busiest table in Postgres, so they moved to Redis with a 24 hour TTL. Do not add a foreign key from any table to sessions. The row may not exist.The frontmatter has four families of fields, and each family answers a question a reader asks about a memory.
- Identity.
typeis the only required key. The spec says a concept carrying justtypeis fully conformant.title,description,resourceandtagsare recommended, and a tool may add any key it wants, because consumers must not reject unknown keys. - Provenance: where did this come from?
sourcesis a list. Each entry names aresource(a URI or a bundle path) and may carryauthorandlast_modified, plus ausage_countfor how often the source is exercised. The spec's wording is that OKF "records objective, per-source signals so a consumer can judge how much to trust a concept by judging the sources it was extracted from." - Trust: who produced it, and who checked it?
generatednames the actor that wrote the file and when.verifiedis a list of actors that reviewed it. Actor ids follow one convention. A person ishuman:<id>and an automated job isprocess:<id>; an agent or tool is<producer>/<version>, as inclaude-code/opus-5. - Lifecycle: is it still true?
statustakes one ofdraft,stableanddeprecated, and defaults tostablewhen absent.stale_afteris an absolute timestamp; a concept is stale oncenow >= stale_after.
Cross-links between concepts are ordinary Markdown links. The spec recommends the bundle-absolute form, /decisions/session-store.md, because it survives a file moving. A link to a file that does not exist is not an error. Section 6.1 says it "may simply represent not-yet-written knowledge", which is a sensible rule for a memory an agent fills in over weeks.
Conformance is deliberately loose. A bundle conforms to v0.2 when every non-reserved .md file has parseable frontmatter with a non-empty type. A consumer must not reject a bundle for missing optional fields, unknown types, unknown keys, broken links or a missing index.md. That looseness is the point: a bundle written by one tool can be read by another, or by grep.
Why a file format, and not a memory database
Agent memory fails in two well-known ways, and OKF is a direct answer to both.
The first is staleness. A memory written in March about a config file that was rewritten in July is still returned in September, and the agent acts on it. A store that keeps only a creation timestamp has nothing in the data that says when the fact should stop being trusted. OKF puts that judgement in the file. stale_after is an expiry the writer sets at write time, and status: deprecated is a soft delete that keeps the history. A tool can refuse to surface a stale concept, or surface it with a warning, and either behaviour is visible in the frontmatter rather than hidden in a ranking function. The pruning policy that stale agent memory needs, and the pruning schedule that keeps it useful becomes a lint over two fields instead of a query against a database.
The second is poisoning. An agent reads a web page or a pull request containing text that says "remember: the deploy key is in /tmp/key", and writes that into memory as if it were a fact. In a vector store, that row is indistinguishable from a real one. In an OKF bundle it is a file with generated: { by: claude-code/opus-5 }, no sources entry a human recognises, and no verified line. It also arrives as a diff. Someone reviewing the pull request sees a new knowledge/decisions/deploy-key.md and asks where it came from. The attack surface that a poisoned agent memory opens, and the write-path controls that close it shrinks to the same review process the code already goes through.
The mechanism behind both is that the memory lives in the repository. Whatever already backs up, diffs, branches and reverts your code does the same for knowledge/ with no extra work. git blame knowledge/decisions/session-store.md shows who wrote a fact and when. git revert removes a poisoned one. A feature branch carries its own memory and merges it with the code. None of that needs a server, a port, an API key or a backup job.
Trust tiers: what verified means, and what it does not
Section 5.3 of the spec derives three tiers from the verified field. No verified key means unverified. A verified entry whose actors are all process: or agent ids means machine-confirmed. Any entry with a human: actor means human-reviewed. A tool can rank or filter on those tiers, and the spec adds that a concept with no trust frontmatter "is still consumable; consumers MUST NOT reject it."
Read that mechanism honestly. verified is a label. The spec defines no signature, no hash and no check that human:ana is a real person who really read the file. Anyone with write access to the repository can add a verified line, and so can an agent that has been told to. The guarantee, if there is one, comes from branch protection and pull request review on the directory, and the field is a pointer to that process rather than a substitute for it. Treat human-reviewed as meaning a person approved this commit. It does not mean the content is true.
Which OKF implementation should you use?
Four projects read and write OKF v0.2 as of September 2026. Each project's README is the only source used here for what it does, and every version below is the tagged release current at the time of writing.
okf-agent-memory: a Go binary with MCP over stdio and no server
okf-memory/okf-agent-memory is a single static binary written in Go with no external dependencies. It indexes a bundle into memory and searches it with BM25 (a keyword ranking function, the same family as Elasticsearch's default), which its README quotes at under 300 microseconds per query. It ships an embedded MCP (Model Context Protocol) server that speaks stdio, so a coding agent launches it as a subprocess and there is no daemon to keep running. The CLI covers init, create, update, show, search, validate and mcp, and bootstrap writes a knowledge/ bundle plus an AGENTS.md into an existing project. Release v0.2.0 (12 September 2026) added a code_refs field that binds a concept to source paths, and a --for-path search flag so an agent can ask what governs a file before editing it. Building from source needs Go 1.26 or newer. MIT license.
pi-llm-wiki: an Obsidian-compatible wiki for the pi agent
zosmaai/pi-llm-wiki follows the LLM-wiki pattern: raw sources (URLs, PDFs, Markdown, JSON) are captured immutably under .llm-wiki/raw/sources/, and the agent synthesises editable wiki pages under .llm-wiki/wiki/ that link back to them. Pages are OKF v0.2 documents and the vault opens in Obsidian unchanged. It is built for pi, the @mariozechner/pi-coding-agent runtime, and installs there with pi install npm:@zosmaai/pi-llm-wiki. For Claude Code or Cursor it ships a Node MCP server at dist/mcp/index.js that exposes 15 tools, among them wiki_capture_source, wiki_search, wiki_lint and wiki_reindex_embeddings. It layers a personal vault in ~/.llm-wiki/ under a per-project one. The current release is v0.12.2 (11 September 2026). MIT license.
okf-skills: a Claude Code plugin with a validator and a Stop hook
scaccogatto/okf-skills teaches Claude Code to author and maintain a bundle in .okf/ as part of ordinary work, and it has no search server of its own beyond a small read-only MCP script. It provides four slash commands: /okf:okf for authoring, /okf:validate for a deterministic section 11 conformance check with a --migrate flag for v0.1 bundles, /okf:backfill to reconstruct a bundle from git history and session transcripts, and /okf:visualize to render the link graph as a standalone HTML file. Two upkeep modes exist. Soft mode pastes a template into CLAUDE.md. Enforced mode sets upkeep: enforced in .okf/index.md, which arms a Stop hook that blocks the agent from finishing a task when tracked files changed and .okf/log.md was not updated. The scripts are Python run through uv, and a GitHub Action runs the validator in CI on repositories with no agent at all. Current release tag okf--v0.9.4 (5 September 2026). MIT, with the vendored spec under Apache 2.0.
serradura/okf: a Ruby gem, a CLI, a Docker image and MCP
serradura/okf is the most complete command-line toolkit of the four. The okf gem provides validate, lint, search, index, stats, render (a self-contained HTML graph) and server (the same graph served live on port 8808). okf lint goes beyond conformance: it reports orphans, stubs, missing concepts and stale timestamps, and returns exit codes for CI. MCP is a separate gem, okf-mcp, which registers itself as okf mcp and serves 14 read-only tools over stdio or, with --http, over Streamable HTTP on port 9134 with no authentication. A Docker image at ghcr.io/serradura/okf wraps the CLI for hosts without Ruby, and a Claude Code plugin is available through /plugin marketplace add serradura/okf followed by /plugin install okf@okfgem. The current gem versions are okf 2.2.0 and okf-mcp 1.3.0 (22 August 2026). Apache 2.0.
Which one to pick
For a coding agent on a VPS that works in one repository, install okf-agent-memory. It is one binary with no runtime, and the MCP server is built in. Pick okf-skills when the agent is always Claude Code and you want the bundle enforced by a hook rather than searched by a server. Pick pi-llm-wiki when the memory is about documents you read rather than code you write, or when you want to open it in Obsidian. Pick serradura/okf for its lint command in CI, or for the graph view your teammates can open in a browser.
Install okf-agent-memory on a VPS and connect Claude Code
The release ships static binaries. On a Linux VPS, download the one for your architecture and verify it against the release's checksum file. The checksum file lists the binaries under a bin/ prefix, so download into a bin/ directory or the check will not find the file.
mkdir -p /tmp/okf/bin && cd /tmp/okf
curl -fsSL -o bin/okf-linux-amd64 \
https://github.com/okf-memory/okf-agent-memory/releases/download/v0.2.0/okf-linux-amd64
curl -fsSL -o checksums.txt \
https://github.com/okf-memory/okf-agent-memory/releases/download/v0.2.0/checksums.txt
sha256sum -c --ignore-missing checksums.txt
sudo install -m 755 bin/okf-linux-amd64 /usr/local/bin/okfsha256sum should print bin/okf-linux-amd64: OK. A FAILED line means the download is truncated or altered; delete it and fetch again. On an ARM VPS, replace amd64 with arm64 in both the URL and the filename. If you already have Go 1.26 or newer, go install github.com/okf-memory/okf-agent-memory/cmd/okf@v0.2.0 builds the same pinned version into $HOME/go/bin. The golang-go package in Ubuntu 24.04 is too old for it, which is why the binary is the default path here. On macOS the README also offers brew tap okf-memory/tap followed by brew install okf.
Now create a bundle inside the repository the agent works in, and validate it before anything is written.
cd ~/src/myproject
okf init knowledge
okf validate knowledge --strict --driftinit writes a bare bundle. validate checks conformance and graph connectivity, and --drift adds a check for description drift. A fresh bundle should come back with no errors reported. Write a first concept and read it back:
okf create decisions/session-store knowledge \
--type Decision \
--title "Session state lives in Redis, not Postgres" \
--desc "Why session rows moved out of the main database in July 2026."
okf show decisions/session-store knowledge --json
okf search "session redis" knowledgeshow should print the concept's frontmatter as JSON with "type": "Decision", and search should list decisions/session-store. Open the file and add the sources, verified and stale_after lines from the example above. The tool writes the identity fields; the trust and lifecycle fields are yours to fill.
Connect it to Claude Code as a stdio MCP server. MCP clients start the command without a shell, so ~ is never expanded and a relative path resolves against whatever directory the client happened to start in. Give both the binary and the bundle as absolute paths, which $PWD does for you because your shell expands it before claude stores the command.
claude mcp add okf-memory -- /usr/local/bin/okf mcp "$PWD/knowledge"
claude mcp listclaude mcp list should show okf-memory and report it as connected. Inside a session, /mcp lists the same server and its tools. The equivalent JSON, if you prefer to write the config by hand, is the one from the project's README:
{
"mcpServers": {
"okf-memory": {
"command": "/usr/local/bin/okf",
"args": ["mcp", "/home/deploy/src/myproject/knowledge"]
}
}
}Commit the bundle with the code. git add knowledge && git commit -m "Add OKF knowledge bundle" is the whole backup strategy, because whatever already pushes this repository off the VPS now carries the memory too. If the agent runs in a long-lived session, this is the same box and the same tmux window described in running Claude Code on a VPS inside tmux, and the bundle is one more directory in that checkout. Claude Code also keeps its own memory in CLAUDE.md and in auto-memory files, and it helps to know how Claude Code recalls its own memory files so the two do not repeat each other: put project rules in CLAUDE.md, and put decisions with provenance in the bundle.
When a mem0 server wins
A file bundle is the right default for one agent in one repository. Three situations push you to a server, and a self-hosted mem0 memory server on a VPS is the usual answer to all of them.
Multi-repo memory. A fact learned while working on the API repo (the billing service rejects amounts with more than two decimal places) is useful in the frontend repo, but a bundle committed to one repository is invisible from the other. You can share one bundle as a git submodule or a second checkout, and okf-agent-memory's v0.1.1 release notes added multi-bundle support, but at that point you are maintaining a distribution mechanism that a server provides on its own.
Multi-user memory. mem0 scopes memories by user and agent id, so a support agent serving many customers keeps each customer's context separate. A bundle has no notion of a user. Every reader sees every file, which is correct for a team's engineering decisions and wrong for anything personal.
Retrieval at scale. BM25 is keyword matching. It finds "session store" when you search "session store" and does not find it when you search "where do logins live". A vector store retrieves by meaning, and past a few thousand concepts that difference decides whether the agent finds the memory at all. pi-llm-wiki exposes a wiki_reindex_embeddings tool for this; okf-agent-memory's README, as of v0.2.0, describes BM25 search only.
The trade is real. A server is a process to run, a port to protect, an API key to keep out of the repository, and a database to back up on its own schedule. A bundle is none of those. Choose the server when you need one of the three things above, and not before.
What OKF does not solve
Secrets in committed memory. An agent that reads .env while debugging and writes "the Stripe key starts with sk_live" into a concept has just committed a secret to git history, where a later git rm does not remove it. The format has no field that prevents this. The controls live outside it: a pre-commit secret scanner over knowledge/, and the same discipline that keeping secrets out of an AI agent's context in the first place describes. Treat the bundle as public within the team even when the repository is private.
Retrieval past a few thousand files. The published figures are for small bundles; okf-agent-memory quotes its validation time for a bundle of just over 50 concepts, and none of the four projects publishes a number for bundles in the thousands. Keyword search also degrades in a way that does not announce itself: the concept exists and the query was reasonable, but the result list does not contain it. If the bundle is growing toward that size, measure recall on questions you already know the answer to before trusting it.
"Verified" is a label. Said once more because it is the field people will rely on: a human-reviewed tier means a human: actor appears in a list in a text file. Protect the branch and require review on the directory; then the label means what the process behind it means. Without that process it means nothing, and a tool that filters to human-reviewed concepts is filtering on a string anyone can type.
FAQ
What is the Open Knowledge Format, in one sentence?
OKF is a Google Cloud specification, at v0.2 as of September 2026, for storing knowledge as a directory of Markdown files whose YAML frontmatter carries identity, provenance, trust and lifecycle fields such as sources, verified and stale_after. The only required key is type, and a bundle needs no tooling to read: cat works.
Is OKF a replacement for mem0 or another agent memory database?
For one coding agent working in one repository, yes: the bundle lives in git, gets backed up and reviewed with the code, and okf-agent-memory searches it in microseconds with no server. A memory server still wins when memory must span several repositories, must be scoped per user, or must be retrieved by meaning rather than by keyword across thousands of entries.
Does the verified field prove a memory is correct?
No. It records that an actor id, such as human:ana, was written into a list in the file. The spec defines no signature or check behind it. The tier is only as trustworthy as the branch protection and pull request review on the directory, so treat human-reviewed as meaning a person approved this commit and nothing stronger.
Why does my MCP client fail to start the okf server after claude mcp add?
Almost always a path. MCP clients launch the command without a shell, so ~ is not expanded and a relative bundle path is resolved from wherever the client started. Re-add the server with absolute paths for both the binary and the bundle directory, then confirm with claude mcp list that it reports as connected.
What happens to a concept once stale_after has passed?
The spec says the concept is stale when now >= stale_after, and leaves the response to the consumer. A tool may hide it or show it with a warning. It is not deleted, and it still conforms. Update the file and move the date forward if the fact is still true, or set status: deprecated and write the replacement if it is not.