Most answers to "give my AI agent long-term memory" hand you an opaque vector store: embeddings in a database you can't read, can't diff, and can't easily redact. I wanted the opposite : memory I can open in an editor, review in a pull request, and 'git blame' line by line. That itch is what pushed OKF4net from a single library into a small toolkit over the last few months. It just reached v0.5, and this post is about what's new — starting with the part I'm most excited about.
If you haven't seen it before: OKF4net (docs & project site) is an independent, zero-dependency .NET implementation of Google's Open Knowledge Format (OKF). OKF represents knowledge as a directory of markdown files with YAML frontmatter, cross-linked like a wiki, versioned in git. No database, no proprietary format: if you can 'cat' a file you can read it, if you can 'git clone' a repo you can ship it.
The headline: agent memory as plain markdown
'OKF4net.Agents' turns a bundle into tools and context for the Microsoft Agent Framework. 'OkfBundleTools' exposes read, browse, graph, search, write, append-log, validate and more as function tools an agent can call directly. Layer 'OkfContextProvider' onto the same instance and the agent automatically gets relevant bundle context injected into each turn — and, when you opt in, its exchanges captured back into the bundle as long-term memory:
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OKF4net.Agents;
var tools = new OkfBundleTools("./my_bundle");
// Memory capture is opt-in (Disabled by default) — turn it on explicitly.
var provider = new OkfContextProvider(
tools,
new OkfContextProviderOptions { MemoryCapture = MemoryCaptureMode.Enabled });
AIAgent agent = chatClient.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new ChatOptions { Tools = tools.GetTools() },
AIContextProviders = [provider],
});
var response = await agent.RunAsync("What do we know about orders?");
Here's what makes it different. Capture is deterministic (no extra LLM call): after each turn, the last user message and the agent's final response are appended to a single memory concept for the day ('memory/'), with a matching 'log.md' change-history entry. Those writes go through the exact same validated, lock-protected, path-safe write path any other caller uses, and the captured text is blockquote-neutralized so a payload smuggled into a message can't fake document structure.
The payoff is that memory is just files in your bundle. You can:
- 'git blame' a remembered fact to see exactly when and in which exchange it entered the memory,
- diff memory across commits and redact a line with a normal edit,
- point a second agent at the same directory with no export step,
- and review the whole thing in a PR like any other change.
I'll be honest about where v1 stands: this captured memory is bundle-global, unscoped, and opt-in : it carries no session/user/tenant key, so it's meant for a shared, non-sensitive knowledge base, which is exactly why it ships disabled by default. If you need per-caller isolation, that lives one layer up in the catalog (below). I'd rather ship an honest, inspectable v1 than a magic box (maybe next version ?).
The rest of what's new (v0.2 → v0.5)
The memory story is the headline, but the project grew in every direction since the first release. OKF4net now ships as five NuGet packages plus a couple of standalone tools:
- A local MCP server, 'OKF4net.Mcp'. The 'okf-mcp' 'dotnet tool' exposes a bundle to Claude Desktop or Claude Code over the Model Context Protocol now with bundle auto-discovery, so it finds your knowledge base instead of making you wire a path. Recipes for other MCP-capable editors (VS Code, Cursor, Rider…) are on the issue tracker as good-first contributions.
- A multi-bundle catalog, 'OKF4net.Catalog'. A 'catalog.json' manifest, a source resolver, and full-text search across many bundles with read-only knowledge sources and writable memory tiers ('session' / 'user' / 'tenant') for exactly the per-caller scoping the agent provider's v1 memory doesn't do.
- Machine-readable CLI output. The Native AOT 'okf' CLI ('validate'/'info'/'index'/'graph'/'parse'/'fmt') gained a '--json' flag on 'validate' and 'info', so a CI step can parse structured diagnostics instead of scraping text.
- A producer that turns a repo into a bundle. 'producers/OkfProducer' generates a validated OKF bundle straight from an existing repository (npm/NuGet/README detection so far). It's an early walking skeleton, but it closes the loop: you don't have to hand-author a bundle to try the ecosystem.
Through all of it, the core constraint held: 'OKF4net' and its CLI have zero third-party runtime dependencies — base class library only, hand-written YAML-subset parser and link scanner included. That's what lets the CLI ship as a single self-contained Native AOT binary with no runtime to install, and it keeps the barrier to contributing low: there's no framework to learn before you can read the code. Much of OKF4net is built with AI assistance (Claude Code), with the OKF spec and an extensive test suite — including byte-exact golden CLI captures — as the ground truth every change has to satisfy.
Come contribute
OKF4net is open source under LGPL-3.0-or-later and deliberately welcoming to first contributions, no prior OKF knowledge needed. The 'good first issue' label names the files to touch and the test that should go green, 'ROADMAP.md' shows where it's headed, and Discussions is the place to ask before you write any code. If you'd rather start by reading, the project site and docs are the friendlier way in. Your first PR is three commands away: 'dotnet build', 'dotnet test', 'dotnet format'.
If "agents that remember things in files you can read" sounds useful, I'd love the help and the feedback.
OKF4net is built and maintained by Coderise.
Top comments (0)