Add a query tool group for the wiki-file-assets MCP server that queues fixed /wiki-query OpenCode jobs, exposes status/result/cancel/readiness tools, and keeps query disabled until explicitly enabled. Document the new service switches and config, keep remote query gated in AGENTS.md, preserve token behavior, and pass proxy environment through the managed service so OpenCode smoke/query jobs can reach the model provider. Validation: python3 -m unittest discover -v; python3 -m py_compile obsidian_wiki/mcp_query.py obsidian_wiki/mcp_server.py scripts/manage_mcp_service.py tests/test_mcp_query.py tests/test_mcp_server_remote.py tests/test_mcp_service.py; git diff --check.
649 lines
42 KiB
Markdown
649 lines
42 KiB
Markdown
# obsidian-wiki
|
||
|
||
|
||
<p align="center">
|
||
<a href="https://deepwiki.com/Ar9av/obsidian-wiki"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" /></a>
|
||
<a href="https://github.com/ar9av/obsidian-wiki/pulls"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" /></a>
|
||
<a href="https://x.com/_ar9av"><img src="https://img.shields.io/badge/@__ar9av-black?logo=x&logoColor=white" alt="X" /></a>
|
||
</p>
|
||
|
||
<p align="center">
|
||
<img width="768" height="512" alt="obisidan-wiki" src="https://github.com/user-attachments/assets/b44cf63b-3197-4fb1-8e18-dbc9a39f27a7" />
|
||
</p>
|
||
|
||
A knowledge mgmt system inspired by [gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) published by Andrej Karpathy about maintaining a personal knowledge base with LLMs : the "LLM Wiki" pattern.
|
||
|
||
Instead of asking an LLM the same questions over over (or doing RAG every time), you compile knowledge once into interconnected markdown files and keep them current. In this case Obsidian is the viewer and the LLM is the maintainer.
|
||
|
||
We took that and built a framework around it. The whole thing is a set of markdown skill files that any AI coding agent (Claude Code, Cursor, Windsurf, Pi, whatever you use) can read and execute. You point it at your Obsidian vault and tell it what to do.
|
||
|
||
## Quick Start
|
||
|
||
### Install via pip (recommended)
|
||
|
||
```bash
|
||
pip install obsidian-wiki
|
||
obsidian-wiki setup --vault /path/to/your/vault
|
||
```
|
||
|
||
`obsidian-wiki setup` writes the config to `~/.obsidian-wiki/config` and installs every wiki skill into all your AI agents (Claude Code, Cursor, Codex, Gemini, Hermes, Pi, and more). Skills are symlinked to the installed package, so `pip install -U obsidian-wiki` upgrades them everywhere — just re-run `obsidian-wiki setup` to pick up new skills. Then open a project in your agent and say **"set up my wiki"**.
|
||
|
||
```bash
|
||
obsidian-wiki list # list the bundled skills
|
||
obsidian-wiki info # show install paths, version, and config
|
||
obsidian-wiki file-index rebuild # rebuild fast source-file lookup index
|
||
obsidian-wiki file-index search "FH52K 图纸" -n 10
|
||
obsidian-wiki setup --project . # also drop project-local skills + AGENTS.md into the current repo
|
||
obsidian-wiki setup --copy # copy skill files instead of symlinking
|
||
```
|
||
|
||
`OBSIDIAN_VAULT_PATH` is just any directory where you want your wiki documents to live — a new empty folder or an existing Obsidian vault. Omit `--vault` to be prompted (or set it later in `~/.obsidian-wiki/config`).
|
||
|
||
### Install via Skills CLI
|
||
|
||
```bash
|
||
npx skills add Ar9av/obsidian-wiki
|
||
```
|
||
|
||
This installs all wiki skills into your current agent (Claude Code, Cursor, Codex, etc.). Then open your agent and say **"set up my wiki"**.
|
||
|
||
Browse the full skill list at [skills.sh/ar9av/obsidian-wiki](https://skills.sh/ar9av/obsidian-wiki).
|
||
|
||
### Install via git clone
|
||
|
||
```bash
|
||
git clone https://github.com/Ar9av/obsidian-wiki.git
|
||
cd obsidian-wiki
|
||
bash setup.sh
|
||
```
|
||
|
||
`setup.sh` asks for your vault path, writes the config to `~/.obsidian-wiki/config`, symlinks skills into all your agents, and installs `wiki-update` globally so you can use it from any project.
|
||
|
||
`OBSIDIAN_VAULT_PATH` is just any directory where you want your wiki documents to live. It can be a new empty folder or an existing Obsidian vault. Obsidian will read from it directly.
|
||
|
||
Open the project in your agent and say **"set up my wiki"**. That's it.
|
||
|
||
## Agent Compatibility
|
||
|
||
Works with **any AI coding agent** that can read files — Claude Code, Cursor, Windsurf, Pi, Codex, Gemini CLI, Kiro, and more. `setup.sh` handles skill discovery for each one automatically.
|
||
|
||
<details>
|
||
<summary><b>Supported agents and manual setup instructions</b></summary>
|
||
|
||
| Agent | Bootstrap | Skills Directory | Slash Commands |
|
||
|---|---|---|---|
|
||
| **[Claude Code](https://claude.ai/code)** | `CLAUDE.md` | `.claude/skills/` + `~/.claude/skills/` | ✅ `/wiki-ingest`, `/wiki-status`, etc. |
|
||
| **[Cursor](https://cursor.com)** | `.cursor/rules/obsidian-wiki.mdc` | `.cursor/skills/` | ✅ `/wiki-ingest`, `/wiki-status`, etc. |
|
||
| **[Windsurf](https://windsurf.com)** | `.windsurf/rules/obsidian-wiki.md` | `.windsurf/skills/` | ✅ via Cascade |
|
||
| **[Codex (OpenAI)](https://openai.com/codex)** | `AGENTS.md` | `~/.codex/skills/` | `$wiki-ingest` (Codex uses `$`) |
|
||
| **[Gemini CLI](https://github.com/google-gemini/gemini-cli)** | `GEMINI.md` | `~/.gemini/skills/` | ✅ `/wiki-ingest`, `/wiki-query`, etc. |
|
||
| **[Google Antigravity](https://antigravity.google)** | `.agent/rules/` + `.agent/workflows/` | `.agents/skills/` | ✅ via workflows registry |
|
||
| **[Kiro IDE/CLI](https://kiro.dev)** | `.kiro/steering/obsidian-wiki.md` | `.kiro/skills/` + `~/.kiro/skills/` | ✅ `/wiki-ingest`, `/wiki-status`, etc. |
|
||
| **[Hermes](https://hermes-agent.nousresearch.com)** | `.hermes.md` | `~/.hermes/skills/` | ✅ `/wiki-history-ingest hermes`, etc. |
|
||
| **[OpenClaw](https://openclaw.ai)** | `AGENTS.md` | `~/.openclaw/skills/` + `~/.agents/skills/` | ✅ `/wiki-ingest`, `/wiki-history-ingest openclaw`, etc. |
|
||
| **[OpenCode](https://opencode.ai)** | `AGENTS.md` | `~/.agents/skills/` | ✅ `/wiki-ingest`, `/wiki-query`, etc. |
|
||
| **[Aider](https://aider.chat)** | `AGENTS.md` | `~/.agents/skills/` | Describe intent in chat |
|
||
| **[Factory Droid](https://factory.ai)** | `AGENTS.md` | `~/.agents/skills/` | ✅ `/wiki-ingest`, `/wiki-query`, etc. |
|
||
| **[Trae](https://trae.ai)** / **Trae CN** | `AGENTS.md` | `~/.trae/skills/` / `~/.trae-cn/skills/` | ✅ via Agent tool |
|
||
| **GitHub Copilot (VS Code)** | `.github/copilot-instructions.md` | — | Describe intent in chat |
|
||
| **GitHub Copilot (CLI)** | — | `~/.copilot/skills/` | ✅ `/wiki-ingest`, `/wiki-query`, etc. |
|
||
| **[Kilocode](https://kilo.ai/)** | `AGENTS.md` / `CLAUDE.md` | `.agents/skills/` + `.claude/skills/` | ✅ `/wiki-ingest`, `/wiki-status`, etc. |
|
||
| **[Pi](https://pi.dev)** | `AGENTS.md` | `.pi/skills/` + `~/.pi/agent/skills/` | ✅ `/wiki-ingest`, `/wiki-history-ingest pi`, etc. |
|
||
|
||
> Each agent has its own convention for discovering skills. `setup.sh` symlinks the canonical `.skills/` directory into each agent's expected location. You write skills once, every agent can use them.
|
||
|
||
### Manual setup (if you prefer `setup.sh`)
|
||
|
||
<details>
|
||
<summary>Claude Code</summary>
|
||
|
||
Skills are auto-discovered from `.claude/skills/`. Either run `setup.sh` or copy `.skills/*` to `.claude/skills/`. The `CLAUDE.md` file at the repo root is automatically loaded as project context.
|
||
|
||
```bash
|
||
cd /path/to/obsidian-wiki && claude "set up my wiki"
|
||
```
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Cursor</summary>
|
||
|
||
Skills are auto-discovered from `.cursor/skills/`. The `.cursor/rules/obsidian-wiki.mdc` file provides always-on context. Either run `setup.sh` or copy `.skills/*` to `.cursor/skills/`. Then type `/wiki-setup` in the chat.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Windsurf</summary>
|
||
|
||
Cascade reads rules from `.windsurf/rules/` and skills from `.windsurf/skills/`. Either run `setup.sh` or copy `.skills/*` to `.windsurf/skills/`. Then tell Cascade: "set up my wiki".
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Codex</summary>
|
||
|
||
Reads `AGENTS.md` for project context. `setup.sh` installs skills globally to `~/.codex/skills/`. Either run `setup.sh` or manually symlink `.skills/*` to `~/.codex/skills/`.
|
||
|
||
```bash
|
||
cd /path/to/obsidian-wiki && codex "set up my wiki"
|
||
```
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Gemini CLI</summary>
|
||
|
||
Reads `GEMINI.md` and discovers global skills from `~/.gemini/skills/`. Either run `setup.sh` or manually symlink `.skills/*` to `~/.gemini/skills/`.
|
||
|
||
```bash
|
||
cd /path/to/obsidian-wiki && gemini "set up my wiki"
|
||
```
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Google Antigravity</summary>
|
||
|
||
Always-on via `.agent/rules/` + `.agent/workflows/`. `setup.sh` ships both files and symlinks skills into `.agents/skills/`. The legacy `~/.gemini/antigravity/skills/` path is also wired.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Kiro IDE/CLI</summary>
|
||
|
||
Always-on via `.kiro/steering/*.md` with `inclusion: always`. `setup.sh` symlinks `.skills/*` into both `.kiro/skills/` and `~/.kiro/skills/`. Invoke with `/wiki-ingest`, `/wiki-query`, etc.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>OpenCode / Aider / Factory Droid / Trae</summary>
|
||
|
||
All read `AGENTS.md` at the repo root. `setup.sh` symlinks skills into `~/.agents/skills/` (shared discovery path). Trae also gets `~/.trae/skills/` and `~/.trae-cn/skills/`.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Hermes</summary>
|
||
|
||
Reads `.hermes.md` first, then falls back to `AGENTS.md`. Skills discovered from `~/.hermes/skills/`. Run `setup.sh` or manually symlink `.skills/*` there.
|
||
|
||
```bash
|
||
cd /path/to/obsidian-wiki && hermes "set up my wiki"
|
||
# Mine Hermes history into the wiki:
|
||
/wiki-history-ingest hermes
|
||
```
|
||
</details>
|
||
|
||
<details>
|
||
<summary>OpenClaw</summary>
|
||
|
||
Reads `AGENTS.md` (priority 10). Discovers skills from `~/.openclaw/skills/` and `~/.agents/skills/`. Skills auto-register as slash commands.
|
||
|
||
```bash
|
||
cd /path/to/obsidian-wiki && openclaw "set up my wiki"
|
||
# Mine OpenClaw history:
|
||
/wiki-history-ingest openclaw
|
||
```
|
||
</details>
|
||
|
||
<details>
|
||
<summary>GitHub Copilot</summary>
|
||
|
||
**VS Code Chat:** reads `.github/copilot-instructions.md`. Say "set up my wiki" in Copilot Chat.
|
||
|
||
**CLI:** discovers skills from `~/.copilot/skills/`. Run `setup.sh` or manually symlink `.skills/*` there.
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Pi</summary>
|
||
|
||
Reads `AGENTS.md` (walking up from cwd). Discovers skills from `.pi/skills/`, `.agents/skills/`, and `~/.pi/agent/skills/`. Run `setup.sh` or manually symlink `.skills/*` to `~/.pi/agent/skills/`.
|
||
|
||
```bash
|
||
cd /path/to/obsidian-wiki && pi "set up my wiki"
|
||
# Mine Pi session history:
|
||
/wiki-history-ingest pi
|
||
```
|
||
</details>
|
||
|
||
</details>
|
||
|
||
## How it works
|
||
|
||
Every ingest runs through four stages:
|
||
|
||
**1. Ingest** — The agent reads your source material directly. It handles whatever you throw at it: markdown files, PDFs (with page ranges), JSONL conversation exports, plain text logs, chat exports, meeting transcripts, and images (screenshots, whiteboard photos, diagrams — vision-capable model required). No preprocessing step, no pipeline to run. The agent reads the file the same way it reads code.
|
||
|
||
**2. Pull Information** — From the raw source, the agent pulls out concepts, entities, claims, relationships, and open questions. A conversation about debugging a React hook yields a "stale closure" pattern. A research paper yields the key idea and its caveats. A work log yields decisions and their rationale. Noise gets dropped, signal gets kept. Each page also gets a 1–2 sentence `summary:` in its frontmatter at write time — later queries use this to preview pages without opening them.
|
||
|
||
**3. Merge** — New knowledge gets merged against what's already in the wiki. If a concept page exists, the agent updates it — merging new information, noting contradictions, strengthening cross-references. If it's genuinely new, a page gets created. Nothing is duplicated. Sources are tracked in frontmatter so every claim stays attributable.
|
||
|
||
**4. Schema** — The wiki schema isn't fixed upfront. It emerges from your sources and evolves as you add more. The agent maintains coherence: categories stay consistent, wikilinks point to real pages, the index reflects what's actually there. When you add a new domain (a new project, a new field of study), the schema expands to accommodate it without breaking what exists.
|
||
|
||
A `.manifest.json` tracks every source that's been ingested — path, timestamps, which wiki pages it produced. On the next ingest, the agent computes the delta and only processes what's new or changed.
|
||
|
||
|
||
## Visualization
|
||
|
||
Through Global Graph View visualize every note and link within your entire vault.
|
||
- **Ribbon Icon**: Click the "Open graph view" icon (looks like a connected network) on the left-side ribbon.
|
||
- **Command Palette**: Press Ctrl + P (Windows/Linux) or Cmd + P (Mac), type "Open graph view", and press Enter.
|
||
|
||
<img width="1632" height="963" alt="obsidian-wiki" src="https://github.com/user-attachments/assets/f2980840-4b5b-438a-8264-5ad1de42f483" />
|
||
|
||
### Color-coding the graph
|
||
|
||
Say **"color my graph"**, **"color code by tag"**, **"color by category"**, or **"highlight visibility in graph"** and the `graph-colorize` skill rewrites `<vault>/.obsidian/graph.json` so Obsidian tints nodes by tag, folder, or visibility. It scans your actual vocabulary, picks a colorblind-friendly palette, backs up the existing `graph.json` first, and only touches the `colorGroups` field — your zoom, physics, and filter preferences stay intact. Reload Obsidian (Cmd/Ctrl+R) to see the change.
|
||
|
||
Modes: `by-tag` (default — top 10 tags), `by-category` (the seven vault folders), `by-visibility` (highlight `visibility/pii` and `visibility/internal`), `combined` (visibility + tags), or `custom` (user-supplied mapping).
|
||
|
||
## What we added on top of Karpathy's pattern
|
||
|
||
- **Delta tracking.** A manifest tracks every source file that's been ingested: path, timestamps, which wiki pages it produced. When you come back later, it computes the delta and only processes what's new or changed. You're not re-ingesting your entire document library every time.
|
||
|
||
- **Project-based organization.** Knowledge gets filed under projects when it's project-specific, globally when it's not. Both are cross-referenced with wikilinks. If you're working on 10 different codebases, each one gets its own space in the vault.
|
||
|
||
- **Archive and rebuild.** When the wiki drifts too far from your sources, you can archive the whole thing (timestamped snapshot, nothing lost) and rebuild from scratch. Or restore any previous archive.
|
||
|
||
- **Multi-agent ingest.** Documents, PDFs, Claude Code history (`~/.claude`), Codex sessions (`~/.codex/`), Hermes memories and sessions (`~/.hermes/`), OpenClaw MEMORY.md and sessions (`~/.openclaw/`), Pi sessions (`~/.pi/agent/sessions/`), Windsurf data (`~/.windsurf`), ChatGPT exports, Slack logs, meeting transcripts, raw text. There are dedicated skills for Claude, Codex, Hermes, OpenClaw, and Pi history, plus a catch-all ingest skill for arbitrary text exports.
|
||
|
||
- **Cross-agent targeted search.** `/wiki-claude`, `/wiki-codex`, `/wiki-hermes`, `/wiki-openclaw`, `/wiki-copilot`, `/wiki-pi` — query-driven ingest from a specific agent's raw history. Say `/wiki-codex "rust ownership"` while in Claude Code and it finds your Codex sessions about that topic, extracts the relevant conversation blobs, distills them into wiki pages, and returns a synthesized answer you can use immediately. Different from bulk ingest: this is topic-first, not session-first. Each agent has its own extraction strategy (Codex rollout events, Claude JSONL turns, OpenClaw's pre-synthesized `MEMORY.md`, Pi tree-structured JSONL sessions, etc.). Pair with `/memory-bridge diff` to see what each tool uniquely contributed to a topic.
|
||
|
||
- **Audit and lint.** Find orphaned pages, broken wikilinks, stale content, contradictions, missing frontmatter. See a dashboard of what's been ingested vs what's pending.
|
||
|
||
- **Automated cross-linking.** After ingesting new pages, the cross-linker scans the vault for unlinked mentions and weaves them into the knowledge graph with `[[wikilinks]]`. No more orphan pages.
|
||
|
||
- **Tag taxonomy.** A controlled vocabulary of canonical tags stored in `_meta/taxonomy.md`, with a skill that audits and normalizes tags across your entire vault.
|
||
|
||
- **Provenance tracking.** Every claim on a wiki page is tagged: extracted (default), `^[inferred]` (LLM synthesis), or `^[ambiguous]` (sources disagree). A `provenance:` block in the frontmatter summarizes the mix per page, and `wiki-lint` flags pages that drift into mostly speculation. You can always tell what your wiki actually knows from what it guessed.
|
||
|
||
- **Source archive and catalog.** When `WIKI_ARCHIVE_SOURCES=true`, file-based ingest copies original sources into `_sources/archive/` inside the vault and records them in `_meta/source-registry.jsonl`. When `WIKI_SOURCE_CATALOG=true`, it also maintains `_sources/catalog/` pages organized by document type, product line, customer, competitor, standard, and market. Page citations can then point at vault-relative archived files instead of machine-local paths, while catalog pages provide clean business navigation without duplicating files.
|
||
|
||
- **SQLite file asset lookup.** `_meta/file-assets.sqlite` indexes archived and staged source files for low-latency file search. Use `obsidian-wiki file-index search "part/report/customer"` when the answer should be an original drawing, 3D/CAD file, spreadsheet, PDF, or test report path instead of a synthesized wiki answer. The database lives inside the vault and can be rebuilt from `_meta/source-registry.jsonl`; rebuilds preserve structured registry fields such as part numbers, series, pitch, pin count, product lines, customers, standards, related pages, and catalog paths.
|
||
|
||
- **Multimodal sources.** Screenshots, whiteboard photos, slide captures, and diagrams ingest the same way as text — the agent transcribes any visible text verbatim and tags interpreted content as inferred. Requires a vision-capable model.
|
||
|
||
- **Wiki insights.** Beyond delta tracking, `wiki-status` can analyze the shape of your vault itself: top hubs, bridge pages (nodes whose removal would partition the graph), tag cluster cohesion scores, scored surprising connections, a graph delta since last run, and suggested questions the wiki structure is uniquely positioned to answer. Output goes to `_insights.md`.
|
||
|
||
- **Graph export.** `wiki-export` turns the vault's wikilink graph into `graph.json` (queryable), `graph.graphml` (Gephi/yEd), `cypher.txt` (Neo4j), and a self-contained `graph.html` interactive browser visualization — no server required.
|
||
|
||
- **Tiered retrieval.** `wiki-query` reads titles, tags, and page summaries first and only opens page bodies when the cheap pass can't answer. Say "quick answer" or "just scan" to force index-only mode. Keeps query cost roughly flat as your vault grows from 20 pages to 2000.
|
||
|
||
- **QMD semantic search (optional).** [QMD](https://github.com/tobi/qmd) indexes your wiki and source documents for semantic search. When `QMD_WIKI_COLLECTION` is set in `.env`, `wiki-query` runs a lex+vec pass against the collection before falling back to Grep — enabling concept-level matches that exact-string search misses. When `QMD_PAPERS_COLLECTION` is set, `wiki-ingest` queries your indexed sources before writing a new page, surfacing related work, detecting contradictions, and deciding whether to create or merge. QMD can be used through MCP or the local CLI. Without QMD, both skills fall back to Grep/Glob and remain fully functional.
|
||
|
||
- **`_raw/` staging directory.** Drop rough notes, clipboard pastes, or quick captures into `_raw/` inside your vault. The next `wiki-ingest` run promotes them to proper wiki pages and removes the originals. Configured via `OBSIDIAN_RAW_DIR` in `.env` (defaults to `_raw`).
|
||
|
||
## Optional: QMD Semantic Search
|
||
|
||
By default, `wiki-ingest` and `wiki-query` use `Grep`/`Glob` for search — fully functional, no extra setup. If your vault grows large or you want concept-level matches across your sources, you can plug in [QMD](https://github.com/tobi/qmd), either through MCP or by letting the agent call the local `qmd` CLI.
|
||
|
||
**Setup:**
|
||
|
||
1. Install QMD. If you want MCP mode, also add it to your MCP config (see the QMD repo for instructions).
|
||
2. Index your wiki and/or source documents:
|
||
```bash
|
||
qmd index --name wiki /path/to/your/vault
|
||
qmd index --name papers /path/to/your/sources
|
||
```
|
||
3. Set the collection names and transport in your `.env`:
|
||
```env
|
||
QMD_WIKI_COLLECTION=wiki # used by wiki-query
|
||
QMD_PAPERS_COLLECTION=papers # used by wiki-ingest (source discovery)
|
||
QMD_TRANSPORT=mcp # mcp | cli
|
||
QMD_CLI_SEARCH_MODE=quality # quality | balanced | fast
|
||
```
|
||
|
||
`QMD_TRANSPORT=mcp` preserves the original behavior and uses an agent-configured QMD MCP server. `QMD_TRANSPORT=cli` runs the local `qmd` command directly. CLI mode defaults to `quality`, which uses `qmd query` with reranking for the best relevance. If that is too slow on CPU, set `QMD_CLI_SEARCH_MODE=balanced` to use `qmd query --no-rerank`, or `fast` for a lighter semantic pass.
|
||
|
||
**What changes with QMD enabled:**
|
||
|
||
- **`wiki-query`** runs a semantic pass (lex+vec) against your wiki collection before falling back to Grep. Finds conceptually related pages even when the exact terms don't match.
|
||
- **`wiki-ingest`** queries your papers collection before writing a new page — surfaces related sources, spots contradictions, and decides whether to create a new page or merge into an existing one.
|
||
|
||
Both skills degrade gracefully: if `QMD_WIKI_COLLECTION` / `QMD_PAPERS_COLLECTION` are not set, they skip the QMD step silently and use Grep instead.
|
||
|
||
## Optional: File Asset Lookup
|
||
|
||
When source archiving is enabled, the vault can also keep a SQLite locator for original files:
|
||
|
||
```bash
|
||
obsidian-wiki file-index init
|
||
obsidian-wiki file-index rebuild
|
||
obsidian-wiki file-index search "Mini FAKRA 高频测试" --doc-type test_report -n 10
|
||
obsidian-wiki file-index search "X4104 STEP" --source-type cad -n 10
|
||
```
|
||
|
||
The database is stored at `<vault>/_meta/file-assets.sqlite`. It is rebuilt from `<vault>/_meta/source-registry.jsonl`, so deleting the database is safe as long as the registry and `_sources/archive/` remain. Registry metadata is treated as durable index input: `bjd_part_numbers`, `competitor_part_numbers`, `series`, `pitch`, `pin_count`, `product_lines`, `customers`, `competitors`, `standards`, `business_categories`, `related_pages`, and `catalog_paths` are preserved and merged with automatic extraction on every rebuild. To queue a new file for later ingest, copy it into the vault inbox and add a staged index row:
|
||
|
||
```bash
|
||
obsidian-wiki file-index stage ./drawing.step --project bjd --doc-type drawing
|
||
```
|
||
|
||
Staging is for upload/intake only. The normal ingest flow should still classify the file, archive it under `_sources/archive/`, update source registry/catalog pages, and rebuild the file index.
|
||
|
||
### Optional: Source File MCP Server
|
||
|
||
Agents that support MCP can ask for original engineering files through a local stdio server:
|
||
|
||
```bash
|
||
pip install "obsidian-wiki[mcp]"
|
||
obsidian-wiki file-index rebuild
|
||
obsidian-wiki-mcp
|
||
```
|
||
|
||
Configure your agent to run `obsidian-wiki-mcp` as a stdio MCP server. The server exposes:
|
||
|
||
- `search_file_assets` — finds safe source files by product code, series, customer, doc type, or file type.
|
||
- `list_file_assets` — browses safe source files with optional filters.
|
||
- `get_file_asset_metadata` — returns one file's safe metadata and `asset://source/sha256/...` URI.
|
||
- `file_index_status` — shows vault/index/profile status.
|
||
- `asset://source/sha256/{digest}` — binary resource for an allowed archived file.
|
||
|
||
By default the MCP layer is stricter than local CLI lookup: it only serves engineering files such as drawings, 3D/STEP models, specifications, product parameters, and test reports. Customer-shareable engineering deliverables, such as PDF customer drawings, are allowed for source-file lookup when the active profile already allows technical engineering data. It blocks raw orders, prices, email correspondence, complaint evidence, claims, personal data, and files missing from `_meta/source-registry.jsonl`. Use `OBSIDIAN_MCP_BOT_PROFILE`, `OBSIDIAN_MCP_MAX_FILE_BYTES`, and `OBSIDIAN_MCP_EXPOSE_PATHS` to tune the runtime behavior.
|
||
|
||
Optional: run the same MCP server over Streamable HTTP for a remote MCP client:
|
||
|
||
```bash
|
||
export OBSIDIAN_MCP_TOKEN='<long-random-token>'
|
||
obsidian-wiki-mcp --transport streamable-http --host 127.0.0.1 --port 8765 --path /mcp
|
||
```
|
||
|
||
Remote HTTP requests must include:
|
||
|
||
```http
|
||
Authorization: Bearer <long-random-token>
|
||
```
|
||
|
||
Client configuration example:
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"wiki-file-assets": {
|
||
"type": "streamable-http",
|
||
"url": "http://127.0.0.1:8765/mcp",
|
||
"headers": {
|
||
"Authorization": "Bearer <long-random-token>"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
For long-running access from another machine, use the managed user service:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh start
|
||
```
|
||
|
||
`mcp_service.sh start` creates `.runtime/obsidian-wiki-mcp.env` with `0600` permissions if it does not exist, writes `~/.config/systemd/user/obsidian-wiki-mcp.service`, starts the service, and prints the remote URL, `Authorization` header, enabled tool groups, config file path, and client JSON to copy into another agent. When `ingest` is enabled, it also prints the `/mcp-ingest/uploads` file upload endpoint. It serves the configured `OBSIDIAN_VAULT_PATH` by default; pass `--vault /path/to/vault` to override. The service defaults to `0.0.0.0:8765/mcp` because it is intended for remote clients, but it still requires the bearer token. Prefer SSH tunnel, Tailscale, WireGuard, or another trusted network boundary instead of directly exposing the port to the public internet.
|
||
|
||
Customize the first startup if needed:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh start --vault /path/to/vault --host 0.0.0.0 --port 9876 --path /wiki-mcp
|
||
```
|
||
|
||
Tool groups are controlled by the same config file:
|
||
|
||
```bash
|
||
OBSIDIAN_MCP_ENABLED_TOOLS=file-assets
|
||
```
|
||
|
||
Edit that line directly, or use the service command:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh tools list
|
||
bash scripts/mcp_service.sh tools enable ingest
|
||
bash scripts/mcp_service.sh tools disable ingest
|
||
bash scripts/mcp_service.sh tools enable query
|
||
bash scripts/mcp_service.sh tools disable query
|
||
```
|
||
|
||
To let a remote MCP client upload files and ask this machine's local OpenCode to run the normal `wiki-ingest` workflow, enable the `ingest` tool group and restart/start the same service:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh start --enable-ingest
|
||
```
|
||
|
||
After `ingest` is enabled once, later `bash scripts/mcp_service.sh start` preserves the config file setting. Use `bash scripts/mcp_service.sh start --disable-ingest` or `bash scripts/mcp_service.sh tools disable ingest` to turn it off.
|
||
|
||
This adds write-capable MCP tools to the same `wiki-file-assets` server and bearer token. The server is tool-first: some MCP clients may show empty `resources` or `prompts` lists until a concrete `asset://source/sha256/...` URI is returned by `get_file_asset_metadata`, so use the tool list as the source of truth.
|
||
|
||
- `get_ingest_upload_instructions` — returns the preferred upload methods, HTTP endpoint path, fields, limits, and curl example for remote agents.
|
||
- `create_ingest_upload_ticket` — returns a short-lived, single-use upload token for the HTTP endpoint so remote agents can upload with curl without reading the main MCP bearer token.
|
||
- `check_ingest_opencode_readiness` — verifies the local OpenCode binary, required run flags, project ingest skills, and optionally runs a no-write smoke test that confirms `wiki-ingest` can be loaded.
|
||
- `start_ingest_job` — queues a local `opencode run --auto --format json` job with a fixed `/wiki-ingest` prompt for the completed uploads.
|
||
- `get_ingest_job_status`, `get_ingest_job_result`, `cancel_ingest_job` — inspect or cancel the local job.
|
||
|
||
For binary files, use the HTTP upload endpoint. If the remote agent cannot read the main MCP bearer token, first call `create_ingest_upload_ticket`, then upload with the returned token:
|
||
|
||
```bash
|
||
curl -H "X-Obsidian-Wiki-Upload-Token: <upload-token>" \
|
||
-F "files=@drawing.pdf" \
|
||
-F "project=bjd" \
|
||
-F "doc_type_hint=drawing" \
|
||
-F "start_job=true" \
|
||
http://127.0.0.1:8765/mcp-ingest/uploads
|
||
```
|
||
|
||
The endpoint accepts repeated `files` fields plus optional `project`, `doc_type_hint`, `note`, and `start_job` fields. It accepts either the same bearer token as `/mcp` or the single-use upload ticket header. Base64 file upload is intentionally not exposed as an MCP tool because large JSON arguments are fragile in many agent tool-call implementations.
|
||
|
||
Run `check_ingest_opencode_readiness` before the first remote upload. Use `run_smoke_test: true` when you want OpenCode itself to prove it can load the project `wiki-ingest` skill; otherwise the static preflight is also run automatically before every `start_ingest_job`.
|
||
|
||
Uploads land under `.runtime/mcp-ingest/uploads/`, outside the Obsidian vault, and are treated only as temporary source staging. Job state and logs live under `.runtime/mcp-ingest/jobs/`. The MCP server refuses to enable ingest if `OBSIDIAN_MCP_INGEST_RUNTIME_ROOT` points inside the vault; let `wiki-ingest` decide how to archive sources into `_sources/archive/`, update registries, and rebuild the file index. The ingest prompt is generated by the MCP service, requires OpenCode to load `wiki-ingest`, and restricts OpenCode to the uploaded file list; clients cannot pass arbitrary shell commands through this interface. Because enabling ingest gives the remote token write access to the vault through local OpenCode, keep it on a trusted network and rotate the token if it has been shared too broadly.
|
||
|
||
To let a remote MCP client ask synthesized questions against the compiled wiki, enable the `query` tool group:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh start --enable-query
|
||
```
|
||
|
||
After `query` is enabled once, later `bash scripts/mcp_service.sh start` preserves it. Use `bash scripts/mcp_service.sh start --disable-query` or `bash scripts/mcp_service.sh tools disable query` to turn it off.
|
||
|
||
This adds read-oriented OpenCode-backed query tools to the same `wiki-file-assets` server and bearer token:
|
||
|
||
- `check_query_opencode_readiness` — verifies the local OpenCode binary, required run flags, project `wiki-query`/`llm-wiki` skills, and optionally runs a no-write smoke test.
|
||
- `start_wiki_query` — queues a local `opencode run --auto --format default` job with a fixed `/wiki-query` prompt. Parameters: `query`, `mode` (`normal` or `index_only`), `public_only` (default `false`), and optional `note`.
|
||
- `get_wiki_query_status`, `get_wiki_query_result`, `cancel_wiki_query` — inspect, retrieve, or cancel the local query job.
|
||
|
||
`public_only` defaults to `false`, so the answer may use the same full vault visibility that a local operator sees. Set `public_only=true` when the remote answer must exclude `visibility/internal` and `visibility/pii` pages. Job state and logs live under `.runtime/mcp-query/jobs/`, outside the vault. A normal `wiki-query` log entry is allowed, but the generated prompt forbids ingest/update/rebuild workflows and arbitrary shell execution.
|
||
|
||
Rotate the token later with:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh new-token
|
||
```
|
||
|
||
Useful service commands:
|
||
|
||
```bash
|
||
bash scripts/mcp_service.sh show-config
|
||
bash scripts/mcp_service.sh tools list
|
||
bash scripts/mcp_service.sh tools enable ingest
|
||
bash scripts/mcp_service.sh tools disable ingest
|
||
bash scripts/mcp_service.sh stop
|
||
bash scripts/mcp_service.sh uninstall
|
||
bash scripts/mcp_service.sh status
|
||
```
|
||
|
||
### `_raw/` Staging Directory
|
||
|
||
`_raw/` is a staging area inside your vault for unprocessed captures — rough notes, clipboard pastes, quick voice-memo transcripts. Drop files there and the next `wiki-ingest` run will promote them to proper wiki pages and remove the originals.
|
||
|
||
The fastest way to feed `_raw/` during a live coding session is `/wiki-quick-chat-capture` — it scans the current conversation, extracts bugs and gotchas, and writes structured draft files in under 60 seconds with no subagents or manifest writes.
|
||
|
||
The directory is created automatically by `wiki-setup`. The path is configurable via `OBSIDIAN_RAW_DIR` in `.env` (defaults to `_raw`).
|
||
|
||
---
|
||
|
||
## Skills
|
||
|
||
Everything lives in `.skills/`. Each skill is a markdown file the agent reads when triggered:
|
||
|
||
| Skill | What it does | Slash Command |
|
||
| ----------------------- | ------------------------------------------------- | ------------------------ |
|
||
| `wiki-setup` | Initialize vault structure | `/wiki-setup` |
|
||
| `wiki-ingest` | Distill documents into wiki pages | `/wiki-ingest` |
|
||
| `wiki-history-ingest` | Unified history router (`claude`, `codex`, `hermes`, `pi`) | `/wiki-history-ingest <claude|codex|hermes|pi>` |
|
||
| `claude-history-ingest` | Mine your `~/.claude` conversations and memories from Claude code and desktop | `/claude-history-ingest` |
|
||
| `codex-history-ingest` | Mine your `~/.codex` sessions and rollout logs | `/codex-history-ingest` |
|
||
| `hermes-history-ingest` | Mine your `~/.hermes` memories and sessions | `/hermes-history-ingest` |
|
||
| `openclaw-history-ingest` | Mine your `~/.openclaw` MEMORY.md and sessions | `/openclaw-history-ingest` |
|
||
| `copilot-history-ingest` | Mine your `~/.copilot` CLI session history | `/copilot-history-ingest` |
|
||
| `pi-history-ingest` | Mine your `~/.pi/agent/sessions` JSONL history | `/pi-history-ingest` |
|
||
| `data-ingest` | Ingest any text — chat exports, logs, transcripts | `/data-ingest` |
|
||
| `ingest-url` | Fetch and ingest a URL directly into the wiki | `/ingest-url <url>` |
|
||
| `obsidian-wiki-ingest` | Project-scoped automation wrapper for wiki-ingest | `/obsidian-wiki-ingest` |
|
||
| `wiki-status` | Show what's ingested, what's pending, the delta | `/wiki-status` |
|
||
| `wiki-rebuild` | Archive, rebuild from scratch, or restore | `/wiki-rebuild` |
|
||
| `wiki-query` | Answer questions from the wiki | `/wiki-query` |
|
||
| `wiki-lint` | Find broken links, orphans, contradictions | `/wiki-lint` |
|
||
| `cross-linker` | Auto-discover and insert missing wikilinks | `/cross-linker` |
|
||
| `tag-taxonomy` | Enforce consistent tag vocabulary across pages | `/tag-taxonomy` |
|
||
| `llm-wiki` | The core pattern and architecture reference | `/llm-wiki` |
|
||
| `wiki-update` | Sync current project's knowledge into the vault | `/wiki-update` |
|
||
| `wiki-export` | Export vault graph to JSON, GraphML, Neo4j, HTML | `/wiki-export` |
|
||
| `wiki-capture` | Save the current conversation as a wiki note | `/wiki-capture` |
|
||
| `wiki-quick-chat-capture` | Zero-friction mid-session finding capture to `_raw/` | `/wiki-quick-chat-capture` |
|
||
| `wiki-research` | Autonomous multi-round web research, self-filed | `/wiki-research [topic]` |
|
||
| `wiki-dashboard` | Create dynamic Obsidian Bases dashboard views | `/wiki-dashboard` |
|
||
| `wiki-synthesize` | Discover and fill synthesis gaps across concepts | `/wiki-synthesize` |
|
||
| `wiki-agent` | Query-driven ingest from a specific agent's history | `/wiki-claude [topic]`, `/wiki-codex [topic]`, etc. |
|
||
| `memory-bridge` | Browse and diff knowledge by which AI tool wrote it | `/memory-bridge` |
|
||
| `daily-update` | Daily maintenance cycle — freshness, index, hot cache | `/daily-update` |
|
||
| `impl-validator` | Validate an implementation against its stated goal | `/impl-validator` |
|
||
| `graph-colorize` | Color-code the Obsidian graph by tag/category/visibility | `/graph-colorize` |
|
||
| `skill-creator` | Create new skills | `/skill-creator` |
|
||
|
||
> **Note:** Slash commands (`/skill-name`) work in Claude Code, Cursor, and Windsurf. In other agents, just describe what you want and the agent will find the right skill.
|
||
|
||
### Recommended: Obsidian Skills by Kepano
|
||
|
||
We handle the knowledge management workflow — ingest, query, lint, rebuild. For Obsidian format mastery, we recommend installing [**kepano/obsidian-skills**](https://github.com/kepano/obsidian-skills) alongside this framework. These are optional but improve the quality of wiki output:
|
||
|
||
| Skill | What it adds |
|
||
|---|---|
|
||
| `obsidian-markdown` | Teaches the agent correct Obsidian-flavored syntax — wikilinks, callouts, embeds, properties |
|
||
| `obsidian-bases` | Create and edit `.base` files (database-like views of notes) |
|
||
| `json-canvas` | Create and edit `.canvas` files (visual mind maps, flowcharts) |
|
||
| `obsidian-cli` | Interact with a running Obsidian instance via CLI (search, create, manage notes) |
|
||
| `defuddle` | Extract clean markdown from web pages — less noise than raw fetch, saves tokens during ingest |
|
||
|
||
Both projects use the same [Agent Skills spec](https://agentskills.io/specification), so they coexist in the same `.skills/` directory with no conflicts.
|
||
|
||
**Install:**
|
||
|
||
```bash
|
||
npx skills add kepano/obsidian-skills
|
||
```
|
||
|
||
After installing, your agent will automatically pick up the new skills alongside the existing wiki skills.
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
obsidian-wiki/
|
||
├── .skills/ # ← Canonical skill definitions (source of truth)
|
||
│ ├── wiki-setup/SKILL.md
|
||
│ ├── wiki-ingest/SKILL.md
|
||
│ ├── wiki-history-ingest/SKILL.md
|
||
│ ├── claude-history-ingest/SKILL.md
|
||
│ ├── codex-history-ingest/SKILL.md
|
||
│ ├── hermes-history-ingest/SKILL.md
|
||
│ ├── openclaw-history-ingest/SKILL.md
|
||
│ ├── pi-history-ingest/SKILL.md
|
||
│ ├── data-ingest/SKILL.md
|
||
│ ├── wiki-status/SKILL.md
|
||
│ ├── wiki-rebuild/SKILL.md
|
||
│ ├── wiki-query/SKILL.md
|
||
│ ├── wiki-lint/SKILL.md
|
||
│ ├── cross-linker/SKILL.md
|
||
│ ├── tag-taxonomy/SKILL.md
|
||
│ ├── wiki-update/SKILL.md
|
||
│ ├── llm-wiki/SKILL.md
|
||
│ ├── wiki-export/SKILL.md
|
||
│ └── skill-creator/SKILL.md
|
||
│
|
||
├── CLAUDE.md # Bootstrap → Claude Code / Kilocode (→ AGENTS.md)
|
||
├── GEMINI.md # Bootstrap → Gemini CLI (→ AGENTS.md)
|
||
├── AGENTS.md # Bootstrap → Codex, OpenCode, Aider, Droid, Trae, Hermes, OpenClaw, Kilocode
|
||
├── .hermes.md # Bootstrap → Hermes (symlink → AGENTS.md)
|
||
├── .cursor/rules/obsidian-wiki.mdc # Always-on → Cursor (alwaysApply: true)
|
||
├── .windsurf/rules/obsidian-wiki.md # Always-on → Windsurf
|
||
├── .kiro/steering/obsidian-wiki.md # Always-on → Kiro (inclusion: always)
|
||
├── .agent/rules/obsidian-wiki.md # Always-on → Google Antigravity
|
||
├── .agent/workflows/obsidian-wiki.md # Slash-command registry → Google Antigravity
|
||
├── .github/copilot-instructions.md # Always-on → GitHub Copilot (VS Code Chat)
|
||
│
|
||
├── .claude/skills/ → symlinks to .skills/* (created by setup.sh)
|
||
├── .cursor/skills/ → symlinks to .skills/* (created by setup.sh)
|
||
├── .windsurf/skills/ → symlinks to .skills/* (created by setup.sh)
|
||
├── .agents/skills/ → symlinks to .skills/* (created by setup.sh)
|
||
├── .pi/skills/ → symlinks to .skills/* (created by setup.sh)
|
||
├── .kiro/skills/ → symlinks to .skills/* (created by setup.sh)
|
||
│
|
||
├── ~/.claude/skills/ → portable skills (wiki-update, wiki-query)
|
||
├── ~/.gemini/skills/ → global symlinks — Gemini CLI
|
||
├── ~/.gemini/antigravity/skills/ → global symlinks — Antigravity (legacy path)
|
||
├── ~/.codex/skills/ → global symlinks — Codex
|
||
├── ~/.hermes/skills/ → global symlinks — Hermes
|
||
├── ~/.openclaw/skills/ → global symlinks — OpenClaw (managed)
|
||
├── ~/.copilot/skills/ → global symlinks — GitHub Copilot CLI
|
||
├── ~/.trae/skills/ → global symlinks — Trae
|
||
├── ~/.trae-cn/skills/ → global symlinks — Trae CN
|
||
├── ~/.kiro/skills/ → global symlinks — Kiro CLI
|
||
├── ~/.pi/agent/skills/ → global symlinks — Pi
|
||
├── ~/.agents/skills/ → global symlinks — OpenCode, Aider, Droid, generic
|
||
│
|
||
├── setup.sh # One-command agent setup
|
||
├── .env.example # Configuration template
|
||
├── README.md # You are here
|
||
└── SETUP.md # Detailed setup guide
|
||
```
|
||
|
||
## Using from other projects
|
||
|
||
The whole point is that your wiki should stay up to date as you work across different codebases. You don't want to come back to the obsidian-wiki repo every time. So `setup.sh` installs two global skills that work from any project: `wiki-update` and `wiki-query`.
|
||
|
||
When you run `bash setup.sh`, it does the following:
|
||
|
||
1. Writes a config to `~/.obsidian-wiki/config` with your vault path and the repo location. This is how the skills know where to read and write.
|
||
2. Symlinks `wiki-update` and `wiki-query` into `~/.claude/skills/` so they're available everywhere in Claude Code.
|
||
3. Symlinks all skills into every agent's global discovery path:
|
||
- `~/.gemini/skills/` — Gemini CLI (canonical)
|
||
- `~/.gemini/antigravity/skills/` — Google Antigravity (legacy)
|
||
- `~/.codex/skills/` — Codex
|
||
- `~/.hermes/skills/` — Hermes
|
||
- `~/.openclaw/skills/` — OpenClaw (managed)
|
||
- `~/.copilot/skills/` — GitHub Copilot CLI
|
||
- `~/.trae/skills/` + `~/.trae-cn/skills/` — Trae / Trae CN
|
||
- `~/.kiro/skills/` — Kiro CLI
|
||
- `~/.pi/agent/skills/` — Pi
|
||
- `~/.agents/skills/` — OpenCode, Aider, Factory Droid, and other AGENTS.md-aware agents
|
||
|
||
After that, you're in some project, say `~/projects/my-cool-app`, working with Claude or Pi. Two commands:
|
||
|
||
```bash
|
||
# You're working on some project
|
||
cd ~/projects/my-cool-app
|
||
claude
|
||
|
||
# Write to the wiki: distill what you've learned
|
||
> /wiki-update
|
||
|
||
# Read from the wiki: pull context about anything you've captured before
|
||
> /wiki-query what do I know about rate limiting?
|
||
```
|
||
|
||
`/wiki-update` reads your project, figures out what's worth keeping, and distills it into your Obsidian vault. Architecture decisions, patterns you discovered, key concepts, trade-offs you evaluated. It doesn't copy code or dump file listings. It distills the stuff you'd forget in 3 months. Next time you run it from the same project, it checks what changed since last sync (via git log) and only processes the delta.
|
||
|
||
`/wiki-query` goes the other direction. You're working on something and you want to know what your wiki says about a topic. Maybe you solved a similar problem 2 months ago in a different project and the answer is already in your vault. The agent searches the wiki, reads the relevant pages, and gives you a synthesized answer with citations.
|
||
|
||
Both skills follow the same Karpathy pattern as everything else. If a concept page already exists in the vault, it merges into it. Everything gets cross-linked with `[[wikilinks]]`, tracked in `.manifest.json`, and logged.
|
||
|
||
## Contributing
|
||
|
||
This is early. The skills work but there's a lot of room to make them smarter — better cross-referencing, smarter deduplication, handling larger vaults, new ingest sources. If you've been thinking about this problem or have a workflow that could be a skill, PRs are welcome.
|
||
|
||
### Adding a new skill
|
||
|
||
1. Create a folder in `.skills/your-skill-name/`
|
||
2. Add a `SKILL.md` with YAML frontmatter (`name`, `description`) and markdown instructions
|
||
3. Run `bash setup.sh` to symlink into all agent directories
|
||
4. Test with your agent by saying something that matches the description
|
||
|
||
See `.skills/skill-creator/SKILL.md` for the full guide on writing effective skills.
|