Contents

Build an LLM-maintained wiki in Obsidian with wiki-keeper

Introduction

Wiki-keeper is a Claude Code plugin that turns an Obsidian vault into a sanitized, LLM-maintained multi-wiki knowledgebase. Web clips land in a shared inbox, get sanitized against prompt injection and other attack vectors, and are routed — through a conversation, not an automation — into the right wiki. This article walks through installing the plugin, bootstrapping a vault, configuring the Obsidian Web Clipper, and filing a first clip. By the end, a new wiki will exist that grew from that single article.

Prerequisites

  • Claude Code with a plugin marketplace configured (or comfort adding one).
  • An Obsidian vault you are willing to point the plugin at.
  • uv installed on the machine running Claude Code. The plugin’s sanitation and ingest scripts declare their dependencies inline via PEP 723 and are invoked with uv run.
  • Basic familiarity with the Obsidian Web Clipper.

Steps

1. Install the plugin

The plugin ships the skill, its sanitation scripts, and the Web Clipper template as one unit, so a single install wires up everything the later steps depend on.

/plugin marketplace add manfre/plugin-marketplace
/plugin install wiki-keeper@manfre-plugins

Skip the first command if the marketplace is already added. The marketplace source is at manfre/plugin-marketplace. After install, the wiki-keeper skill is available and activates in any vault that contains a .wiki-keeper.yml marker.

2. Bootstrap the vault

The skill refuses to touch a vault that lacks a .wiki-keeper.yml marker, and it never seeds wikis — they grow from the first ingest. Bootstrapping creates just the skeleton directories and the registry.

Open Claude Code in the vault directory and ask it to bootstrap wiki-keeper. The skill will first survey the existing top-level folders and flag anything that might collide (a stray wiki/ folder, a notes/ pile). It proposes the layout below, then waits for explicit confirmation before creating anything.

<vault>/
├── .wiki-keeper.yml          # synced — wiki registry
├── .wiki-keeper/             # device-local — ledger + audit log
├── raw/
   ├── inbox/                # device-local — clipper target
   ├── assets/               # downloaded images
   └── _quarantine/          # device-local — sanitizer rejects
└── wikis/
    └── README.md             # explains the organic-growth model

Note: Exclude .wiki-keeper/, raw/inbox/, and raw/_quarantine/ from Obsidian Sync, Syncthing, and any git repo. They are device-local or unsafe to replicate. The plugin README covers the full sync model.

3. Configure the Obsidian Web Clipper

The clipper is the ingestion front door. Everything downstream expects clips to land in raw/inbox/ with a shape the sanitation pipeline can read.

In the Obsidian Web Clipper settings:

  1. Add a new template. Paste this content as the template body:

    ---
    title: "{{title}}"
    source_url: "{{url}}"
    clipped_at: "{{date}} {{time}}"
    site_name: "{{domain}}"
    author: "{{author}}"
    ---
    
    # {{title}}
    
    {{content}}
  2. Set the note path to raw/inbox/ inside the vault.

  3. Save.

The sanitizer only keeps title, source_url, and clipped_at from clipper-supplied frontmatter and drops everything else, so the template is safe to extend with extra keys — they just won’t reach the wiki page.

4. Clip an article

The next step needs real input. Open any article in the browser, invoke the Web Clipper, and pick the wiki-keeper template. A new file should appear at raw/inbox/<slug>.md with the frontmatter shape the sanitizer expects.

5. Ingest the clip

This is the core loop, and the first pass doubles as wiki creation — the skill will propose a new wiki when the registry is empty. Ask Claude, in the vault, to process the inbox. Four things happen in order:

Sanitize. The pipeline strips invisible characters, HTML, and known prompt-injection patterns, then dedupes against the device-local ledger. Claude does not read the raw clip directly — only the sanitized staging file and the pipeline’s report. Quarantined clips halt the flow and surface to you before any further action.

Routing conversation. With no wikis registered yet, the skill proposes creating one. It asks for a name and an asset policy: optimize (resize, WebP, strip EXIF — good for text-first wikis) or preserve (keep originals at full quality — good for art, design, or photography). You pick; the skill writes the wiki into .wiki-keeper.yml.

Takeaways. Before drafting the wiki page, the skill asks what from the clip is actually worth capturing. This is deliberate. The page is written from your takeaways informed by the sanitized text — not dumped from the article body.

Draft and write. The skill dispatches a subagent to draft the wiki page, reviews the output, and writes final files. The new page lands under wikis/<wiki>/<topic>/, index.md and log.md pick up entries, and the sanitized source is filed to raw/<wiki>/YYYY-MM-DD-<slug>.md with a hash for future dedupe.

Result

When the ingest finishes, the vault should contain:

  • A new page at wikis/<wiki>/<topic>/<page>.md with wiki-keeper’s required frontmatter (title, type, wiki, topic, tags, sources, created, updated).
  • An updated wikis/<wiki>/index.md listing the new page.
  • A fresh ## [YYYY-MM-DD] ingest | <title> entry in wikis/<wiki>/log.md.
  • The filed source at raw/<wiki>/YYYY-MM-DD-<slug>.md carrying hash: and source_url: in its frontmatter.
  • An empty raw/inbox/.

Open the new page in Obsidian and confirm the [[wikilinks]] resolve.

From here, clip more articles and watch the wiki grow. When topics start overlapping, run /wiki-retopic to get merge, split, and move suggestions. If the wiki grows past the point where reading index.md is cheap, install QMD and register a collection per wiki — routing and query then use semantic search instead of direct index reads.