OKF Wiki
by ysasiwat
README.md
<a id="readme-top"></a>
<!-- PROJECT SHIELDS -->
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![Apache-2.0 License][license-shield]][license-url]
<!-- PROJECT HEADER -->
<br />
<div align="center">
<h3 align="center">OKF Wiki</h3>
<p align="center">
Serve your Obsidian notes to AI agents over MCP as Open Knowledge Format bundles, with provenance, trust and freshness.
<br />
<a href="#usage"><strong>Read the usage guide »</strong></a>
<br />
<br />
<a href="https://github.com/ysasiwat/obsidian-okf-wiki/issues/new?labels=bug&template=bug-report.md">Report Bug</a>
·
<a href="https://github.com/ysasiwat/obsidian-okf-wiki/issues/new?labels=enhancement&template=feature-request.md">Request Feature</a>
</p>
</div>
<!-- TABLE OF CONTENTS -->
<details>
<summary>Table of Contents</summary>
<ol>
<li>
<a href="#about-the-project">About The Project</a>
<ul>
<li><a href="#features">Features</a></li>
<li><a href="#network-use-and-data">Network use and data</a></li>
<li><a href="#built-with">Built With</a></li>
</ul>
</li>
<li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li>
<li>
<a href="#usage">Usage</a>
<ul>
<li><a href="#connect-an-agent">Connect an agent</a></li>
<li><a href="#organizing-bundles">Organizing bundles</a></li>
<li><a href="#how-agents-and-people-share-the-wiki">How agents and people share the wiki</a></li>
<li><a href="#staying-in-control">Staying in control</a></li>
<li><a href="#bundle-policy">Bundle policy</a></li>
<li><a href="#the-okf-cli">The okf CLI</a></li>
<li><a href="#for-plugin-developers">For plugin developers</a></li>
</ul>
</li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#support">Support</a></li>
<li><a href="#license">License</a></li>
<li><a href="#acknowledgments">Acknowledgments</a></li>
</ol>
</details>
<!-- ABOUT THE PROJECT -->
## About The Project
OKF Wiki serves folders of your vault to AI agents over [MCP](https://modelcontextprotocol.io) as
[Open Knowledge Format (OKF) v0.2](https://github.com/google/open-knowledge-format) 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.3, early.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
### 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
<p align="right">(<a href="#readme-top">back to top</a>)</p>
### 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.
- It imports Node's `fs` module for one thing only: resolving a file's real path (`realpath`), so
that a symlink inside a bundle cannot expose files outside the vault or in its configuration
folder. It reads and writes notes only through Obsidian's vault API.
<p align="right">(<a href="#readme-top">back to top</a>)</p>
### Built With
* [![TypeScript][TypeScript-shield]][TypeScript-url]
* [![Obsidian][Obsidian-shield]][Obsidian-url]
* [![MCP][MCP-shield]][MCP-url]
* [![Zod][Zod-shield]][Zod-url]
* [![esbuild][esbuild-shield]][esbuild-url]
* [![Vitest][Vitest-shield]][Vitest-url]
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- GETTING STARTED -->
## 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](https://github.com/ysasiwat/obsidian-okf-wiki/releases) into
`<vault>/.obsidian/plugins/okf-wiki/`, then enable the plugin.
3. To build from source (Node.js 22 or later):
```sh
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>
```
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- USAGE EXAMPLES -->
## 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:
```sh
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.
### Organizing bundles
- **One bundle per body of knowledge whose notes link to each other.** Links, `sources` and
footnote citations cannot point outside their bundle, and the graph and backlinks stop at its
edge, so splitting related notes across bundles breaks them apart.
- **Add another bundle only for a real boundary:** a different set of agents that may read or
write it (tokens can be limited to bundles), a different auto approve choice, a different
`.okf.yaml` policy, or a folder you share or sync on its own. Bundles cannot be nested.
- **Inside a bundle, use folders for the kind of note and tags for the topic**, for example
`concepts/`, `playbooks/` and `decisions/`, with originals in `references/raw/`. A note has one
folder but many tags, and `okf_search` filters by both. Keep folders shallow.
- **Notes outside every bundle are not served**, so personal notes and drafts can stay in the
same vault.
### 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:
```yaml
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:
```sh
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:
```ts
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](src/api.ts).
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- ROADMAP -->
## Roadmap
- [x] Read-only MCP server with OKF lint and the `okf` CLI
- [x] Agent writes with drafts, snapshots, revert and rate limits
- [x] Review queue, batch approve, auto approve and reject
- [x] 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](https://github.com/ysasiwat/obsidian-okf-wiki/issues) for a full
list of proposed features (and known issues).
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- CONTRIBUTING -->
## Contributing
Contributions are welcome. Read [CONTRIBUTING.md](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:
```sh
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:
<a href="https://github.com/ysasiwat/obsidian-okf-wiki/graphs/contributors">
<img src="https://contrib.rocks/image?repo=ysasiwat/obsidian-okf-wiki" alt="contrib.rocks image" />
</a>
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- SUPPORT -->
## Support
Like this project? A coffee keeps it going — every cup funds issues, fixes, and
new features.
<div align="center">
<a href="https://buymeacoffee.com/ysasiwat" target="_blank">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" width="217" height="60">
</a>
</div>
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- LICENSE -->
## License
Distributed under the Apache-2.0 License. See [LICENSE](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](NOTICE).
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- ACKNOWLEDGMENTS -->
## Acknowledgments
* [Open Knowledge Format](https://github.com/google/open-knowledge-format) for the bundle format and sample bundles
* [obsidian-local-rest-api](https://github.com/coddingtonbear/obsidian-local-rest-api) for the design of a local server inside Obsidian
* [Model Context Protocol](https://modelcontextprotocol.io) and its TypeScript SDK
* [Obsidian developer docs](https://docs.obsidian.md)
<p align="right">(<a href="#readme-top">back to top</a>)</p>
<!-- MARKDOWN LINKS & IMAGES -->
[contributors-shield]: https://img.shields.io/github/contributors/ysasiwat/obsidian-okf-wiki.svg?style=for-the-badge
[contributors-url]: https://github.com/ysasiwat/obsidian-okf-wiki/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/ysasiwat/obsidian-okf-wiki.svg?style=for-the-badge
[forks-url]: https://github.com/ysasiwat/obsidian-okf-wiki/network/members
[stars-shield]: https://img.shields.io/github/stars/ysasiwat/obsidian-okf-wiki.svg?style=for-the-badge
[stars-url]: https://github.com/ysasiwat/obsidian-okf-wiki/stargazers
[issues-shield]: https://img.shields.io/github/issues/ysasiwat/obsidian-okf-wiki.svg?style=for-the-badge
[issues-url]: https://github.com/ysasiwat/obsidian-okf-wiki/issues
[license-shield]: https://img.shields.io/github/license/ysasiwat/obsidian-okf-wiki.svg?style=for-the-badge
[license-url]: https://github.com/ysasiwat/obsidian-okf-wiki/blob/main/LICENSE
[TypeScript-shield]: https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white
[TypeScript-url]: https://www.typescriptlang.org/
[Obsidian-shield]: https://img.shields.io/badge/Obsidian-7C3AED?style=for-the-badge&logo=obsidian&logoColor=white
[Obsidian-url]: https://obsidian.md/
[MCP-shield]: https://img.shields.io/badge/MCP-000000?style=for-the-badge&logo=modelcontextprotocol&logoColor=white
[MCP-url]: https://modelcontextprotocol.io/
[Zod-shield]: https://img.shields.io/badge/Zod-3E67B1?style=for-the-badge&logo=zod&logoColor=white
[Zod-url]: https://zod.dev/
[esbuild-shield]: https://img.shields.io/badge/esbuild-FFCF00?style=for-the-badge&logo=esbuild&logoColor=black
[esbuild-url]: https://esbuild.github.io/
[Vitest-shield]: https://img.shields.io/badge/Vitest-6E9F18?style=for-the-badge&logo=vitest&logoColor=white
[Vitest-url]: https://vitest.dev/
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues