OKF Wiki

approvedunreviewed

by Yoschanin Sasiwat

Serve your notes to AI agents over MCP as Open Knowledge Format bundles, with provenance, trust and freshness.

Updated todayApache-2.0

Contributors Forks Stargazers Issues Apache-2.0 License


OKF Wiki

Serve your Obsidian notes to AI agents over MCP as Open Knowledge Format bundles, with provenance, trust and freshness.
Read the usage guide »

Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. Support
  7. License
  8. Acknowledgments

About The Project

OKF Wiki serves folders of your vault to AI agents over MCP as Open Knowledge Format (OKF) v0.2 bundles: plain Markdown with YAML frontmatter that records where knowledge came from, who checked it and when it goes stale. Agents read, search and write through OKF-aware tools; you stay in charge of what counts as reviewed.

Here's why:

  • Agents that remember things in your notes should say where each fact came from
  • You should decide which knowledge counts as reviewed, not the agent
  • Your notes stay plain Markdown that you can read and edit without the plugin

Desktop only. Status: 0.6.2, early.

(back to top)

Features

  • MCP tools for OKF: browse, search, read, graph, history and lint, plus writes for agents you allow
  • Drafts first: everything an agent writes starts as a draft that you approve or reject in Obsidian
  • Provenance: who wrote each note and why, kept in log.md and an audit log
  • Checkable trust: notes whose status or verified changed outside the plugin are reported as not attested
  • Safe writes: rate limits, no writes while you type in a note, snapshots and one-click revert
  • Language policy: curated notes in English, original sources kept as raw files in any language
  • Extension API: other plugins can read the wiki and follow every change
  • okf CLI: lint any OKF bundle in CI

(back to top)

Network use and data

  • The plugin runs a local MCP server on 127.0.0.1 (port 27150 by default, changeable in the settings). It listens on the loopback interface only, so other machines cannot reach it. It starts only once you create an access token.
  • Every request needs a token you create in the settings. Tokens are stored as SHA-256 hashes, are shown once, and can be limited to scopes, bundles and folders.
  • The plugin contacts no remote service and has no telemetry. Whatever an agent reads goes to the agent you connected, which may send it to its own model provider; that is between you and that agent.
  • It reads and writes only inside your vault: the bundle folders you enable, and its own state (snapshots, audit log, trust snapshot) in its plugin folder. Files reached through symlinks that lead outside the vault are not served.

(back to top)

Built With

  • TypeScript
  • Obsidian
  • MCP
  • Zod
  • esbuild
  • Vitest

(back to top)

Getting Started

Prerequisites

  • Obsidian desktop 1.13.1 or later (the plugin does not run on mobile)
  • An MCP client that speaks streamable HTTP, such as Claude Code

Installation

  1. In Obsidian, open Settings → Community plugins, search for OKF Wiki, install and enable it.
  2. To install by hand instead, download main.js, manifest.json and styles.css from the latest release into <vault>/.obsidian/plugins/okf-wiki/, then enable the plugin.
  3. To build from source (Node.js 22 or later):
    git clone https://github.com/ysasiwat/obsidian-okf-wiki.git
    cd obsidian-okf-wiki
    npm ci
    npm run build
    node scripts/install-plugin.mjs <path-to-vault>
    

(back to top)

Usage

Connect an agent

  1. In the plugin settings under Bundles, add a folder to serve. Any folder works; it becomes an OKF bundle (an index.md, a log.md and optionally a .okf.yaml policy). Folders that already look like OKF bundles are offered for you to enable.

  2. Under Access tokens, create a token. New tokens can read; tick Write to let agents write drafts. Publish, Replace raw sources and Edit computations are for trusted automation only.

  3. Copy the command shown for Claude Code (or the .mcp.json snippet for other clients), for example:

    claude mcp add --transport http okf-wiki http://127.0.0.1:27150/mcp/ --header "Authorization: Bearer okf_…"
    
  4. Ask your agent something about the notes in the bundle.

How agents and people share the wiki

  • Tools. Reading: okf_bundles, okf_browse, okf_read, okf_read_file (non-markdown text such as attester code), okf_search, okf_graph, okf_history, okf_lint. Writing (Write scope): okf_create, okf_update, okf_move, okf_deprecate, okf_describe_directory, okf_ingest_raw, okf_request_review. Prompts: okf_author_concept and okf_distill_raw.
  • Agents write drafts. Everything an agent creates starts as draft. Only you, in Obsidian, can approve a note (Approve this note, or the Review queue); no token can mark knowledge as reviewed by a person. In the review queue you can tick several notes, or Select all without errors, and Approve selected in one go.
  • Auto approve (optional, off by default). Under Auto approve, list the tokens (and optionally bundles) you trust. A note such a token writes that cites its sources in footnotes and has no lint warnings or review request is approved at once as process:auto-approve: it becomes stable and machine-confirmed, not reviewed by a person. Notes you approved yourself always come back to you after an agent edits them.
  • Reject. Reject in the review queue, or Reject the agent's latest change to this note…, undoes the agent's latest change to that note (a new draft goes to the trash) and writes your reason to log.md, where agents read it.
  • Provenance is recorded for you. The server stamps who wrote each note, keeps index.md and log.md up to date, and, once you set Your ID, records your own edits when you leave a note (turn this off with Record your edits). Approving needs Your ID too.
  • Trust you can check. If someone edits status or verified outside the plugin (another device, a script), the note is reported as not attested instead of trusted.
  • Original sources stay original. Curated notes are English. Material in other languages is stored as a write-once raw source under references/raw/ and cited with footnotes.

Staying in control

  • Pause or resume agent writes stops every agent write at once.
  • Revert an agent change… undoes any recent agent write from its snapshot.
  • Writes are rate limited per token (settings under Agent writes), refused while you are typing in that note, and checked so they cannot drop sources, citations or large parts of a note by accident.

Other commands: Open review queue, Accept edits to this raw source, Convert links in this bundle to OKF form, Reload OKF bundles, Copy MCP endpoint URL, Restart MCP server.

Bundle policy

A bundle may carry a .okf.yaml file:

okf_version: "0.2"
content_language: en
raw_dirs: [references/raw]
non_english_threshold: 0.05
auto_index: true
auto_log: true
agent_initial_status: draft

The okf CLI

Checks any OKF bundle directory, in or out of Obsidian, for example in CI:

npm install
npm run build:cli
node dist/okf.cjs lint path/to/bundle            # conformance and policy; exit 1 on errors
node dist/okf.cjs lint path/to/bundle --strict   # also fail on warnings
node dist/okf.cjs index path/to/bundle           # exit 1 if index.md files are out of date
node dist/okf.cjs index path/to/bundle --write   # regenerate them

For plugin developers

Other plugins can read the wiki and follow its changes, but not write to it:

const api = (this.app as any).plugins.plugins["okf-wiki"]?.api;
if (api?.apiVersion === 1) {
  const off = api.onCommit((e) => {
    // e: { commitId, at, bundle, actor, tool, conceptId, reason?, reverts?,
    //      changes: [{ path, change: "created" | "modified" | "deleted" }] }
  });
  this.register(off);
  const hits = api.search({ bundle: "Knowledge", query: "remote sensing" }).hits;
  const note = api.read({ bundle: "Knowledge", concept_id: hits[0].concept_id });
}
  • bundles(), search(args) and read(args) take the same arguments as the okf_bundles, okf_search and okf_read tools and return copies.
  • onCommit is called after every commit is on disk: agent writes, your own approvals and edits, and reverts (a revert lists the files it restored). Listeners run after the write and cannot slow or break it.
  • When OKF Wiki is disabled or reloaded, listeners are dropped and the old api object throws; get it again once OKF Wiki is enabled. The types are in src/api.ts.

(back to top)

Roadmap

  • Read-only MCP server with OKF lint and the okf CLI
  • Agent writes with drafts, snapshots, revert and rate limits
  • Review queue, batch approve, auto approve and reject
  • Extension API for other plugins
  • Publish the extension API types as an npm package
  • HTTPS and signed URLs for attachments, once a client needs them

See the open issues for a full list of proposed features (and known issues).

(back to top)

Contributing

Contributions are welcome. Read CONTRIBUTING.md for the project's rules, then:

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Run npm run typecheck, npm run lint and npm test
  4. Commit your Changes (git commit -m 'Add some AmazingFeature')
  5. Push to the Branch (git push origin feature/AmazingFeature)
  6. Open a Pull Request

Development commands:

npm test              # vitest
npm run typecheck
npm run lint          # eslint-plugin-obsidianmd
npm run build         # main.js
npm run bench         # UI-thread cost on large synthetic bundles

Top contributors:

contrib.rocks image

(back to top)

Support

Like this project? A coffee keeps it going — every cup funds issues, fixes, and new features.

Buy Me A Coffee

(back to top)

License

Distributed under the Apache-2.0 License. See LICENSE for more information. Includes material from Open Knowledge Format (Apache-2.0); the design of the server follows obsidian-local-rest-api (MIT) without using its code. See NOTICE.

(back to top)

Acknowledgments

(back to top)

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.