{
  "markdown": "<div align=\"center\">\n\n# kObsidian MCP\n\n**Filesystem-first MCP server for Obsidian vaults — with an LLM-Wiki layer on top.**\n\n_Inspired by [Andrej Karpathy's **LLM Wiki**](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) idea._\nYou curate the sources; the LLM does the bookkeeping.\n\n<br />\n\n[![npm version](https://img.shields.io/npm/v/kobsidian-mcp?color=cb3837&label=npm&logo=npm)](https://www.npmjs.com/package/kobsidian-mcp)\n[![npm downloads](https://img.shields.io/npm/dt/kobsidian-mcp?color=cb3837&label=downloads&logo=npm)](https://www.npmjs.com/package/kobsidian-mcp)\n[![GitHub release](https://img.shields.io/github/v/release/bezata/kObsidian?color=1e88e5&label=release&logo=github&sort=semver)](https://github.com/bezata/kObsidian/releases/latest)\n[![license](https://img.shields.io/npm/l/kobsidian-mcp?color=blue)](LICENSE)\n[![Release CI](https://img.shields.io/github/actions/workflow/status/bezata/kObsidian/release.yml?branch=main&label=CI&logo=github)](https://github.com/bezata/kObsidian/actions/workflows/release.yml)\n\n[![MCP](https://img.shields.io/badge/MCP-2025--11--25-1e88e5?logo=anthropic&logoColor=white)](https://modelcontextprotocol.io)\n[![Bun](https://img.shields.io/badge/runtime-Bun_1.3+-f472b6?logo=bun&logoColor=white)](https://bun.sh)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![Tools](https://img.shields.io/badge/MCP_tools-66-1e88e5)](docs/tools.md)\n[![Resources](https://img.shields.io/badge/MCP_resources-4-1e88e5)](docs/tools.md#resources)\n[![Prompts](https://img.shields.io/badge/MCP_prompts-3-1e88e5)](docs/tools.md#prompts)\n[![Smithery](https://img.shields.io/badge/Smithery-listed-8b5cf6)](https://smithery.ai)\n[![MCP Registry](https://img.shields.io/badge/MCP_Registry-listed-10b981)](https://registry.modelcontextprotocol.io)\n[![VirusTotal](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fbezata%2FkObsidian%2Fmain%2F.github%2Fbadges%2Fvirustotal.json)](https://github.com/bezata/kObsidian/releases/latest)\n\n<br />\n\n[**Install**](#install) ·\n[**Quick start**](#quick-start) ·\n[**Architecture**](#architecture) ·\n[**LLM Wiki**](#llm-wiki-60-seconds) ·\n[**Tools**](#tool-surface) ·\n[**Docs**](docs/README.md)\n\nDocs: [简体中文](docs/i18n/zh-CN/README.md) / [日本語](docs/i18n/ja/README.md) / [한국어](docs/i18n/ko/README.md)\n\n[![kObsidian MCP server](https://glama.ai/mcp/servers/bezata/kObsidian/badges/card.svg)](https://glama.ai/mcp/servers/bezata/kObsidian)\n\n</div>\n\n---\n\n> **🧰 The only Obsidian MCP with workspaces.** `vault.list` / `vault.select`\n> let an LLM discover and switch between your Obsidian vaults in-session —\n> no restart, no config edit, no per-tool path threading. Backwards\n> compatible with `OBSIDIAN_VAULT_PATH`. Added in v0.3.0.\n> See **[docs/WORKSPACES.md](docs/WORKSPACES.md)**.\n\n---\n\n## Why kObsidian\n\n- **Filesystem-first.** Operates on your vault directly. Obsidian doesn't need to be running for 55+ of the 66 tools.\n- **66 typed MCP tools** across vaults, notes, links, tags, tasks, Dataview, Canvas, Kanban, fenced blocks, Marp, Templates — every one Zod-validated with `structuredContent` output and the full 4-hint MCP annotation set (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`).\n- **Multi-vault `vault.*` (v0.3.0).** The LLM can `vault.list` your known Obsidian vaults (discovered from Obsidian's own registry or `OBSIDIAN_VAULT_<NAME>` env vars) and `vault.select` between them for the session. Fully backwards compatible: `OBSIDIAN_VAULT_PATH` stays the default and per-call `vaultPath` arguments always win.\n- **LLM-Wiki orchestration** — a `wiki.*` namespace that turns your vault into a compounding knowledge base: ingest sources, auto-update an index + greppable log, lint for orphans / broken links / stale pages. Agent applies cross-refs via a `proposedEdits` contract so every write is visible in the transcript.\n- **Both transports.** Classic stdio for local MCP clients and Streamable HTTP (Hono) for remote, with CORS preflight, `MCP-Protocol-Version` handling, origin 403, and optional bearer auth — all per the 2025-11-25 spec.\n- **Ships everywhere.** npm (`npx -y kobsidian-mcp`), cross-platform `.mcpb` bundles for Claude Desktop drag-and-drop, a `smithery.yaml` for Smithery, and a `server.json` for the MCP Registry. Each `.mcpb` release asset is VirusTotal-scanned with links appended to the release body.\n\n---\n\n## Install\n\nPick your client below. **Every client supports the full hybrid mode**\n— filesystem-first tools (80+ of them) run against the vault path\nalone, and the same config can *simultaneously* carry the Local REST\nAPI key to unlock `workspace.*`, `commands.*`, and live DQL via\n`dataview.query*`. Set the whole env block once per client and every\ntool namespace lights up; leave the REST key blank and the\nfilesystem-first tools keep working.\n\n| Env var | Needed for |\n|---|---|\n| `OBSIDIAN_VAULT_PATH` | **Required everywhere.** Absolute path to the vault. |\n| `OBSIDIAN_API_URL` | Base URL of the Local REST API plugin. Default `https://127.0.0.1:27124`. |\n| `OBSIDIAN_API_VERIFY_TLS` | _Optional._ Defaults to `false` (the REST API plugin uses a self-signed cert on `127.0.0.1`). Set `true` only after trusting the cert in your OS keychain. |\n| `OBSIDIAN_REST_API_KEY` | Local REST API plugin bearer key — only for `workspace.*` / `commands.*` / live `dataview.query*`. |\n\nFull list in [`docs/ENVIRONMENT.md`](docs/ENVIRONMENT.md). Swap `npx`\nfor `bunx` anywhere if you want ≈10 ms cold-start instead of ≈200 ms.\n\n<details>\n<summary><b>Claude Code</b> — <code>claude mcp add</code></summary>\n\n```bash\nclaude mcp add kobsidian -s user \\\n  --env OBSIDIAN_VAULT_PATH=/absolute/path/to/vault \\\n  --env OBSIDIAN_API_URL=https://127.0.0.1:27124 \\\n  --env OBSIDIAN_REST_API_KEY=only-if-you-use-workspace-or-commands-tools \\\n  -- npx -y kobsidian-mcp\n```\n\nOn Windows, wrap the command in `cmd /c`:\n`-- cmd /c npx -y kobsidian-mcp`.\n\n</details>\n\n<details>\n<summary><b>Claude Desktop</b> — drag-and-drop <code>.mcpb</code></summary>\n\nDownload `kobsidian-<platform>.mcpb` from the\n[latest release](https://github.com/bezata/kObsidian/releases/latest) and\ndrag it into Claude Desktop. The installer prompts for vault path +\noptional API URL / key. Every release asset is VirusTotal-scanned — the\nlinks are in the release body.\n\nBuild one locally:\n\n```bash\nbun install\nbun run build:compile   # → dist/kobsidian (or .exe on Windows)\nbun run bundle:mcpb     # → kobsidian.mcpb\n```\n\n</details>\n\n<details>\n<summary><b>Codex CLI</b> (OpenAI) — <code>codex mcp add</code></summary>\n\n```bash\ncodex mcp add kobsidian \\\n  --env OBSIDIAN_VAULT_PATH=/absolute/path/to/vault \\\n  --env OBSIDIAN_API_URL=https://127.0.0.1:27124 \\\n  --env OBSIDIAN_REST_API_KEY=only-if-you-use-workspace-or-commands-tools \\\n  -- npx -y kobsidian-mcp\n```\n\n</details>\n\n<details>\n<summary><b>Cursor</b> — <code>~/.cursor/mcp.json</code> or deeplink</summary>\n\nEdit `~/.cursor/mcp.json` (or the per-project `.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"kobsidian\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"kobsidian-mcp\"],\n      \"env\": {\n        \"OBSIDIAN_VAULT_PATH\": \"/absolute/path/to/vault\",\n        \"OBSIDIAN_API_URL\": \"https://127.0.0.1:27124\",\n        \"OBSIDIAN_REST_API_KEY\": \"only-if-you-use-workspace-or-commands-tools\"\n      }\n    }\n  }\n}\n```\n\nOr hand a one-click deeplink to your users:\n`cursor://anysphere.cursor-deeplink/mcp/install?name=kobsidian&config=<base64-encoded-config>`.\n\n</details>\n\n<details>\n<summary><b>VS Code</b> (Copilot) — <code>code --add-mcp</code></summary>\n\n```bash\ncode --add-mcp '{\"name\":\"kobsidian\",\"command\":\"npx\",\"args\":[\"-y\",\"kobsidian-mcp\"],\"env\":{\"OBSIDIAN_VAULT_PATH\":\"/absolute/path/to/vault\",\"OBSIDIAN_API_URL\":\"https://127.0.0.1:27124\",\"OBSIDIAN_REST_API_KEY\":\"only-if-you-use-workspace-or-commands-tools\"}}'\n```\n\nOr create `.vscode/mcp.json` in your workspace with the same shape under\na top-level `servers` key.\n\n</details>\n\n<details>\n<summary><b>Gemini CLI</b> — <code>gemini mcp add</code></summary>\n\n```bash\ngemini mcp add kobsidian \\\n  --env OBSIDIAN_VAULT_PATH=/absolute/path/to/vault \\\n  --env OBSIDIAN_API_URL=https://127.0.0.1:27124 \\\n  --env OBSIDIAN_REST_API_KEY=only-if-you-use-workspace-or-commands-tools \\\n  -- npx -y kobsidian-mcp\n```\n\nOr hand-edit `~/.gemini/settings.json` under `mcpServers`.\n\n</details>\n\n<details>\n<summary><b>Antigravity</b> (Google) — <code>mcp_config.json</code></summary>\n\nEdit `~/.gemini/antigravity/mcp_config.json`\n(Windows: `%USERPROFILE%\\.gemini\\antigravity\\mcp_config.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"kobsidian\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"kobsidian-mcp\"],\n      \"env\": {\n        \"OBSIDIAN_VAULT_PATH\": \"/absolute/path/to/vault\",\n        \"OBSIDIAN_API_URL\": \"https://127.0.0.1:27124\",\n        \"OBSIDIAN_REST_API_KEY\": \"only-if-you-use-workspace-or-commands-tools\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Zed</b> — <code>settings.json</code> under <code>context_servers</code></summary>\n\nIn `~/.config/zed/settings.json`:\n\n```json\n{\n  \"context_servers\": {\n    \"kobsidian\": {\n      \"source\": \"custom\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"kobsidian-mcp\"],\n      \"env\": {\n        \"OBSIDIAN_VAULT_PATH\": \"/absolute/path/to/vault\",\n        \"OBSIDIAN_API_URL\": \"https://127.0.0.1:27124\",\n        \"OBSIDIAN_REST_API_KEY\": \"only-if-you-use-workspace-or-commands-tools\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>OpenCode</b> — <code>opencode.json</code> under <code>mcp</code></summary>\n\n```json\n{\n  \"mcp\": {\n    \"kobsidian\": {\n      \"type\": \"local\",\n      \"command\": [\"npx\", \"-y\", \"kobsidian-mcp\"],\n      \"environment\": {\n        \"OBSIDIAN_VAULT_PATH\": \"/absolute/path/to/vault\",\n        \"OBSIDIAN_API_URL\": \"https://127.0.0.1:27124\",\n        \"OBSIDIAN_REST_API_KEY\": \"only-if-you-use-workspace-or-commands-tools\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Factory Droid</b> — <code>droid mcp add</code></summary>\n\n```bash\ndroid mcp add kobsidian \"npx -y kobsidian-mcp\" \\\n  --env OBSIDIAN_VAULT_PATH=/absolute/path/to/vault \\\n  --env OBSIDIAN_API_URL=https://127.0.0.1:27124 \\\n  --env OBSIDIAN_REST_API_KEY=only-if-you-use-workspace-or-commands-tools\n```\n\n</details>\n\n<details>\n<summary><b>Other clients</b> (Cline, JetBrains AI, Continue, custom hosts) — generic <code>mcpServers</code> JSON</summary>\n\nAny MCP client that reads a standard `mcpServers` object will accept:\n\n```json\n{\n  \"mcpServers\": {\n    \"kobsidian\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"kobsidian-mcp\"],\n      \"env\": {\n        \"OBSIDIAN_VAULT_PATH\": \"/absolute/path/to/vault\",\n        \"OBSIDIAN_API_URL\": \"https://127.0.0.1:27124\",\n        \"OBSIDIAN_REST_API_KEY\": \"only-if-you-use-workspace-or-commands-tools\"\n      }\n    }\n  }\n}\n```\n\n`\"type\": \"stdio\"` is optional on clients that infer transport from\n`command` (Claude Code), but **required by Claude Desktop, Cursor,\nVSCode, and Antigravity** — include it for maximum portability.\n\n</details>\n\n### Smithery\n\n[smithery.ai](https://smithery.ai) renders an install UI straight from\n[`smithery.yaml`](smithery.yaml) and collects the four env vars for you\n— vault path plus the optional Local REST API URL / TLS / bearer key\ntrio, so hybrid mode works out of the box.\n\n### From source (contributing / hacking)\n\n```bash\ngit clone https://github.com/bezata/kObsidian\ncd kObsidian\nbun install\nbun run dev:stdio    # or dev:http\n```\n\n---\n\n## Obsidian plugins\n\nkObsidian is **filesystem-first** — 55+ of the 66 tools work against a\nbare vault directory with no Obsidian plugins installed. The plugins\nbelow only matter if you want the specific tool namespaces that depend\non them.\n\n### Enabling community plugins (one-time, if not already on)\n\nObsidian ships with community plugins disabled by default. Enable them\nonce per vault:\n\n1. Open your vault in Obsidian.\n2. **Settings** (⚙️, bottom-left) → **Community plugins**.\n3. Click **Turn on community plugins**.\n4. **Browse** → search → **Install** → **Enable**.\n\n### Required for the REST-bridged tools\n\n**[Obsidian Local REST API](obsidian://show-plugin?id=obsidian-local-rest-api)** (by Adam Coddington) — needed for:\n- `workspace.*` (activeFile, openFile, navigate, closeActiveFile, toggleEditMode)\n- `commands.*` (execute, list)\n- `dataview.query` / `dataview.listByTag` / `dataview.listByFolder` / `dataview.table` (runtime DQL — the offline `dataview.fields.*` / `dataview.index` / `blocks.*` tools work without it)\n- `templates.use` with `engine: \"templater\"`\n\n**Setup after install:**\n\n1. Enable the plugin.\n2. Open its settings — scroll to **API key** → click **Copy** (or **Reset** first if you want a fresh one).\n3. Paste that key as `OBSIDIAN_REST_API_KEY` in your MCP client config's `env:` block. The `OBSIDIAN_API_URL` default (`https://127.0.0.1:27124`) works out of the box.\n\nLeave the plugin running while you use the REST-bridged tools — the endpoint is local-only (`127.0.0.1`) so nothing leaves your machine.\n\n### Enhances (but not required for) specific tool namespaces\n\n| Plugin | Link | What it unlocks |\n|---|---|---|\n| **[Dataview](obsidian://show-plugin?id=dataview)** | `id=dataview` | All `dataview.*` tools still work on the raw markdown; Dataview plugin is what makes DQL queries in `dataview.query*` actually execute. Also renders your fields + queries visually inside Obsidian. |\n| **[Templater](obsidian://show-plugin?id=templater-obsidian)** | `id=templater-obsidian` | Runtime template rendering via the REST API (`templates.use` with `engine:\"templater\"`). The offline filesystem engine (`templates.use` with `engine:\"filesystem\"`) and `templates.list` work without it. |\n| **[Marp](obsidian://show-plugin?id=marp-slides)** | `id=marp-slides` | Marp `marp.*` tools parse + edit Marp-front-matter markdown even without the plugin; the plugin is what renders slides / exports to PDF inside Obsidian. |\n| **[Kanban](obsidian://show-plugin?id=obsidian-kanban)** | `id=obsidian-kanban` | `kanban.*` tools read/write the plain markdown board format regardless of plugin; the plugin is what renders the board as draggable columns inside Obsidian. |\n| **[Tasks](obsidian://show-plugin?id=obsidian-tasks-plugin)** | `id=obsidian-tasks-plugin` | `tasks.*` tools understand the Tasks-plugin emoji syntax (📅 ⏳ 🛫 ✅ 🔼 🔁) regardless of plugin; the plugin is what provides filtering / querying / toggling inside Obsidian. |\n\n> The `obsidian://show-plugin?id=…` links jump straight to the plugin\n> in Obsidian's in-app browser — click one with Obsidian open and it\n> deep-links to the install screen.\n\n### TLDR\n\n| You want to … | Minimum you need |\n|---|---|\n| Use `notes.*` / `tags.*` / `links.*` / `stats.vault` / `tasks.*` / `wiki.*` / `kanban.*` / `blocks.*` / `marp.*` / `canvas.*` / `templates.list` + `templates.use` (`engine:\"filesystem\"`) / offline `dataview.*` | **Just a vault path.** No plugins required. |\n| Use `workspace.*` / `commands.*` | + **Local REST API** plugin + API key env var |\n| Run live DQL queries (`dataview.query` / `dataview.listBy*` / `dataview.table`) | + **Local REST API** + **Dataview** |\n| Run Templater templates at runtime | + **Local REST API** + **Templater** |\n\nNo combination of plugins makes kObsidian depend on Obsidian being\nrunning — the REST-bridged tools just return a clear error if the\nplugin isn't reachable, and the filesystem-first tools keep working.\n\n---\n\n## Quick start\n\n> **Before the first session** — kObsidian works on a bare Obsidian vault,\n> but enabling a few Obsidian plugins unlocks the full tool surface.\n> See [Obsidian plugins](#obsidian-plugins) below for the 5-minute\n> setup (Local REST API, Dataview, Templater, Marp, Kanban, Tasks).\n> Skip it if you only need the 80+ filesystem-first tools.\n\nOnce installed, a typical session opens with three natural-language\nprompts. The `wiki.*` tools + the `.claude` skills handle the rest.\n\n```\nYou:  \"Set up a wiki in this vault.\"\nLLM:  wiki.init  →  wiki/{Sources,Concepts,Entities}/ + index.md + log.md + wiki-schema.md\n\nYou:  \"Ingest this: https://… (paper on Memex)\"\nLLM:  wiki.ingest  →  creates wiki/Sources/as-we-may-think.md + log entry\n      returns proposedEdits:\n        - insertAfterHeading  index.md#Sources\n        - createStub          Concepts/memex.md\n        - createStub          Entities/vannevar-bush.md\n      LLM applies each via notes.*  (you see every write in the transcript)\n\nYou:  \"What does the wiki say about memex vs hypertext?\"\nLLM:  wiki.query memex  →  top-ranked pages\n      notes.read on each  →  cited synthesis\n      offers to file the synthesis back via wiki.summaryMerge\n\nYou:  \"Audit the wiki.\"\nLLM:  wiki.lint  →  {orphans, brokenLinks, stale, missingPages, tagSingletons, indexMismatch}\n      proposes concrete fixes; applies after you confirm\n```\n\nFull loop, frontmatter contracts, and the `proposedEdits` design in\n[`docs/wiki.md`](docs/wiki.md).\n\n---\n\n## Example use cases\n\nThe same primitives cover several real-world flavors of knowledge base.\nThree worked examples below; longer walkthroughs in [`docs/examples.md`](docs/examples.md).\n\n### A. Personal research wiki\n\n```\nYou: \"Ingest this paper on in-context learning: <url or pasted markdown>\"\nLLM:  wiki.ingest title=\"In-Context Learning — A Survey\" sourceType=paper\n        tags=[icl, prompting] relatedConcepts=[In-Context Learning, Few-Shot Prompting]\n        relatedEntities=[Brown 2020]\n      → wiki/Sources/in-context-learning-a-survey.md\n      → proposedEdits:\n          • createStub  wiki/Concepts/in-context-learning.md\n          • createStub  wiki/Concepts/few-shot-prompting.md\n          • createStub  wiki/Entities/brown-2020.md\n          • insertAfterHeading  wiki/index.md#Sources\n      LLM applies each via notes.create / notes.edit (mode: \"after-heading\").\n```\n\n### B. Architecture Decision Records (ADRs) for a codebase\n\nModel each ADR as a Source, architectural patterns as Concepts, and\nservices / teams / libraries as Entities. The wiki becomes your ADR\narchive with cross-links you never have to maintain by hand.\n\n```\nYou: \"Record ADR-004: we're switching internal service comms from REST\n      to gRPC. Context: <paste>\"\nLLM:  wiki.ingest title=\"ADR-004 — gRPC for internal service comms\"\n        sourceType=note tags=[adr, architecture, rpc]\n        relatedConcepts=[gRPC, Service Mesh, Internal RPC]\n        relatedEntities=[order-service, payment-service, inventory-service]\n      → wiki/Sources/adr-004-grpc-for-internal-service-comms.md\n      → proposedEdits:\n          • createStub   wiki/Concepts/grpc.md\n          • createStub   wiki/Concepts/service-mesh.md\n          • insertAfterHeading  wiki/Entities/order-service.md#Notable Facts\n          • insertAfterHeading  wiki/Entities/payment-service.md#Notable Facts\n          • …\n\nThree weeks later —\nYou: \"Why did we pick gRPC for internal comms?\"\nLLM:  wiki.query \"grpc internal comms\"\n      notes.read top matches\n      → \"Per [[wiki/Sources/adr-004-grpc-for-internal-service-comms.md|ADR-004]],\n         chosen over REST because of native streaming + typed schemas; tradeoff\n         accepted: browser clients still use REST via an edge gateway\n         ([[wiki/Concepts/service-mesh.md]]).\"\n```\n\n### C. Codebase wiki (design docs + post-mortems + RFCs)\n\nEngineering teams abandon wikis because nobody updates them. Let the\nLLM do it. Ingest design docs, RFCs, and post-mortems as Sources;\narchitectural patterns become Concepts; services and teams become\nEntities.\n\n```\nYou: \"We had an incident today — payment-service timeouts cascaded\n      into order-service. Here's the post-mortem: <paste>\"\nLLM:  wiki.ingest title=\"Postmortem 2026-04-10 — Payment timeouts cascade\"\n        sourceType=other tags=[postmortem, incident, reliability]\n        relatedConcepts=[Circuit Breaker, Cascade Failure, Timeout Budget]\n        relatedEntities=[payment-service, order-service]\n      → wiki/Sources/postmortem-2026-04-10-payment-timeouts-cascade.md\n      → proposedEdits:\n          • createStub  wiki/Concepts/circuit-breaker.md\n          • createStub  wiki/Concepts/cascade-failure.md\n          • insertAfterHeading  wiki/Entities/payment-service.md#Notable Facts\n          • insertAfterHeading  wiki/Entities/order-service.md#Notable Facts\n\nPeriodic housekeeping —\nYou: \"Audit the codebase wiki.\"\nLLM:  wiki.lint\n      → 3 orphan RFCs (unlinked from any Concept; link or archive?)\n      → 1 broken link: [[wiki/Entities/legacy-auth-service.md]]\n        (deprecated in Q1; remove the link from\n         [[wiki/Sources/adr-002-session-migration.md]]?)\n      → 4 post-mortems past the 180-day stale threshold — tag with\n        \"needs-review\" or re-ingest with updated lessons-learned?\n      → 2 tag singletons: `retry-logic` (merge into `retry-policy`?),\n        `observability` (first use; keep).\n```\n\n**Why this works for engineering teams**\n\n- The `proposedEdits` contract means every cross-reference write is\n  visible in the transcript — no silent vault corruption from an LLM\n  hallucination about which services a decision affects.\n- The greppable log format (`## [YYYY-MM-DD] ingest | ADR-004 …`) makes\n  `grep '^## \\[' wiki/log.md | tail -20` a valid \"what did the team\n  decide recently\" query.\n- `wiki.lint` surfaces broken links to services that were deprecated\n  months ago — the bookkeeping humans never get around to.\n\n---\n\n## Architecture\n\n```\n┌──────────────────────────────────────────────────────────────────────┐\n│                           MCP Clients                                │\n│   Claude Code · Claude Desktop · Cursor · VSCode · Antigravity · Zed │\n│   JetBrains AI · Cline · Continue · ChatGPT · Smithery · …           │\n└────────────────────────────┬─────────────────────────────────────────┘\n                             │ JSON-RPC 2.0 · MCP 2025-11-25\n         ┌───────────────────┴──────────────────────┐\n         ▼                                          ▼\n┌──────────────────┐                   ┌─────────────────────────┐\n│ stdio transport  │                   │ Streamable HTTP (Hono)  │\n│                  │                   │ + OPTIONS / CORS        │\n│                  │                   │ + MCP-Protocol-Version  │\n│                  │                   │ + Origin 403 / bearer   │\n└────────┬─────────┘                   └────────┬────────────────┘\n         │                                      │\n         └──────────────────┬───────────────────┘\n                            ▼\n          ┌──────────────────────────────────┐\n          │          McpServer               │\n          │  ┌────────────┐ ┌─────────────┐  │\n          │  │  90 Tools  │ │ 4 Resources │  │\n          │  └────────────┘ └─────────────┘  │\n          │  ┌────────────┐ ┌─────────────┐  │\n          │  │ 3 Prompts  │ │ structured  │  │\n          │  │            │ │   content   │  │\n          │  └────────────┘ └─────────────┘  │\n          └────────────┬─────────────────────┘\n                       │\n                       ▼\n          ┌──────────────────────────────────┐\n          │      Domain layer (pure)         │\n          │  notes · links · tags · tasks    │\n          │  dataview · canvas · kanban      │\n          │  blocks · marp · templates       │\n          │  wiki/ orchestration             │\n          └──────┬─────────────────┬─────────┘\n                 │                 │\n                 ▼                 ▼\n         ┌──────────────┐   ┌──────────────────────┐\n         │  vault/ (FS) │   │ Obsidian Local REST  │\n         │ authoritative│   │ API plugin (optional)│\n         └──────────────┘   └──────────────────────┘\n```\n\nFull module map in [`docs/architecture.md`](docs/architecture.md).\n\n---\n\n## LLM Wiki (60 seconds)\n\n> The tedious part of maintaining a knowledge base is not the reading or\n> the thinking — it's the bookkeeping. Humans abandon wikis because the\n> maintenance burden grows faster than the value. **LLMs don't get\n> bored.**\n\nkObsidian implements the **LLM Wiki** pattern from\n[Andrej Karpathy's gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f):\na persistent, compounding knowledge base the LLM maintains. The vault becomes a\nprivate, curated Memex (Vannevar Bush, 1945) where cross-references,\nlog-keeping, and lint are the LLM's job while you focus on curating\nsources and asking questions.\n\n> \"Instead of just retrieving from raw documents at query time, the LLM\n> incrementally builds and maintains a persistent wiki — a structured,\n> interlinked collection of markdown files that sits between you and the\n> raw sources.\" — Andrej Karpathy\n\n```\n              User drops a source\n                      │\n                      ▼\n            ┌──────────────────────┐    proposedEdits\n            │     wiki.ingest      │ ─────────────────────┐\n            └──────────┬───────────┘                      │\n                       │ creates 1 file                   ▼\n                       │              ┌──────────────────────────────┐\n                       ▼              │ LLM applies edits via        │\n              wiki/Sources/           │  notes.edit (after-heading)  │\n              <slug>.md               │  notes.edit (replace)        │\n                       │              │  notes.create                │\n                       │ appends      └──────────────────────────────┘\n                       ▼\n                 wiki/log.md\n\n   Anytime: wiki.query   → top pages → notes.read → cited synthesis\n   Periodic: wiki.lint   → orphans · broken · stale · missing · tag-drift\n   Curate:   wiki.summaryMerge — add cited section to concept/entity page\n```\n\nDefault layout under the vault:\n\n```\nwiki/\n├── Sources/           per-source summary pages\n├── Concepts/          topic / idea pages (LLM-maintained)\n├── Entities/          people / places / orgs / works\n├── index.md           categorized catalog (wiki.indexRebuild)\n├── log.md             greppable chronological log\n└── wiki-schema.md     vault-local copy of the contract\n```\n\n**The key design decision** is that `wiki.ingest` never rewrites\ncross-references blindly. It creates exactly one file (the Sources\npage), appends one file (`log.md`), and returns a `proposedEdits` array\nthe agent applies with existing `notes.*` tools. Every write is visible\nin the transcript — so LLM hallucinations show up as reviewable edits\nrather than silent vault corruption.\n\nFull contract in [`docs/wiki.md`](docs/wiki.md).\n\n### Claude Code skills\n\nFour skills at [`skills/`](skills/) trigger on natural language:\n`wiki-bootstrap`, `wiki-ingest`, `wiki-query`, `wiki-lint`. Copy or\nsymlink them into `~/.claude/skills/` — see\n[`skills/README.md`](skills/README.md).\n\n---\n\n## Tool surface\n\n**66 MCP tools across 16 namespaces** (v0.2.5 consolidated from ~90 to 62;\nv0.3.0 added the `vault.*` namespace for multi-vault support — see\n[CHANGELOG](CHANGELOG.md) for the full history). Always-current\ninventory at **[`docs/tool-inventory.json`](docs/tool-inventory.json)**.\n\n| Namespace | Count | Highlights |\n|---|---:|---|\n| `vault.*` | 4 | `list` · `current` · `select` · `reset` — multi-vault discovery and session switching (v0.3.0) |\n| `notes.*` | 8 | `read` (content/metadata/stats via `include`) · `create` (note or folder) · `edit` (replace/append/prepend/after-heading/after-block) · `frontmatter` · `delete` · `move` · `list` · `search` |\n| `tags.*` | 4 | `modify` (add/remove/replace/merge) · `search` · `analyze` · `list` |\n| `links.*` | 8 | Backlinks · outgoing · broken · orphans · hubs · graph · health · connections |\n| `stats.*` | 1 | `stats.vault` (per-note stats moved into `notes.read`) |\n| `tasks.*` | 5 | Tasks-plugin format (📅 ⏳ 🛫 ✅ 🔼 🔁) — search · create · toggle · updateMetadata · stats |\n| `dataview.*` | 7 | `query` + sugar wrappers (`listByTag`/`listByFolder`/`table`) · `index` · `fields.read` · `fields.write` |\n| `blocks.*` | 3 | Unified fenced-block API (`list`/`read`/`update`) across `dataview`, `dataviewjs`, `mermaid` |\n| `marp.*` | 2 | `read` (deck/slides/slide) · `update` (slide/frontmatter) |\n| `kanban.*` | 3 | `parse` · `stats` · `card` (add/move/toggle) |\n| `canvas.*` | 4 | `create` · `parse` · `connections` · `edit` (add-node/add-edge/remove-node) |\n| `templates.*` | 2 | `list` · `use` (engine × action) |\n| `workspace.*` | 5 | Live Obsidian UI bridge (requires Local REST API plugin) |\n| `commands.*` | 2 | `list` (with optional query) · `execute` |\n| `wiki.*` | 7 | init · ingest · log · indexRebuild · query · lint · summaryMerge |\n| `system.*` | 1 | `version` |\n\n**Client-safety annotations** (MCP 2025-11-25):\n\n| Hint | Tools |\n|---|---:|\n| `readOnlyHint: true` (clients can auto-approve) | 47 |\n| `destructiveHint: true` (clients prompt more firmly) | 6 |\n| `idempotentHint: true` (safe to retry) | 12 |\n| `openWorldHint: true` (reaches outside the vault) | 16 |\n\n**MCP resources** (URI-addressable; any client can browse without tool\ncalls):\n\n```\nkobsidian://wiki/index              wiki/index.md\nkobsidian://wiki/log                wiki/log.md\nkobsidian://wiki/schema             wiki/wiki-schema.md\nkobsidian://wiki/page/{+path}       any Sources/Concepts/Entities page\n```\n\n**MCP prompts** (for clients that don't consume the `skills/` files):\n`ingest-source`, `answer-from-wiki`, `health-check-wiki`.\n\nDetails in [`docs/tools.md`](docs/tools.md).\n\n---\n\n## Configuration\n\n| Env var | Default | Purpose |\n|---|---|---|\n| `OBSIDIAN_VAULT_PATH` | — | **Required.** Absolute path to the vault. |\n| `OBSIDIAN_API_URL` | `https://127.0.0.1:27124` | Obsidian Local REST API base; only for `workspace.*` / `commands.*` / `dataview.query*`. |\n| `OBSIDIAN_API_VERIFY_TLS` | `false` | Set `true` if you've trusted the REST API's self-signed cert. |\n| `OBSIDIAN_REST_API_KEY` | — | Bearer key for the REST API plugin (if used). |\n| `KOBSIDIAN_HTTP_HOST` | `127.0.0.1` | Bind host for `dev:http`. |\n| `KOBSIDIAN_HTTP_PORT` | `3000` | Bind port for `dev:http`. |\n| `KOBSIDIAN_HTTP_BEARER_TOKEN` | — | Optional bearer for the Streamable HTTP transport. |\n| `KOBSIDIAN_ALLOWED_ORIGINS` | `http://localhost,http://127.0.0.1` | Comma-separated CORS allowlist. |\n| `KOBSIDIAN_WIKI_ROOT` | `wiki` | Wiki directory under the vault. |\n| `KOBSIDIAN_WIKI_SOURCES_DIR` | `Sources` | Per-source summary pages. |\n| `KOBSIDIAN_WIKI_CONCEPTS_DIR` | `Concepts` | Topic / idea pages. |\n| `KOBSIDIAN_WIKI_ENTITIES_DIR` | `Entities` | People / places / orgs / works. |\n| `KOBSIDIAN_WIKI_INDEX_FILE` | `index.md` | Wiki catalog filename. |\n| `KOBSIDIAN_WIKI_LOG_FILE` | `log.md` | Wiki log filename. |\n| `KOBSIDIAN_WIKI_SCHEMA_FILE` | `wiki-schema.md` | Seed schema filename. |\n| `KOBSIDIAN_WIKI_STALE_DAYS` | `180` | `wiki.lint` stale-page threshold. |\n| `KOBSIDIAN_WIKI_INDEX_SOURCES_HEADING` | `Sources` | `index.md` section that lists sources; `wiki.ingest` files new entries under it. |\n| `KOBSIDIAN_WIKI_INDEX_CONCEPTS_HEADING` | `Concepts` | `index.md` section that lists concepts. |\n| `KOBSIDIAN_WIKI_INDEX_ENTITIES_HEADING` | `Entities` | `index.md` section that lists entities. |\n| `KOBSIDIAN_WIKI_CONCEPT_PAGE_HEADING` | `Discussion` | Concept-page heading that receives `wiki.ingest` citations / `wiki.summaryMerge` sections. |\n| `KOBSIDIAN_WIKI_ENTITY_PAGE_HEADING` | `Notable Facts` | Entity-page heading that receives `wiki.ingest` citations / `wiki.summaryMerge` sections. |\n| `KOBSIDIAN_VAULT_CONFIG_FILE` | `.kobsidian.json` | Vault-relative path of the per-vault config file (below). |\n\nEvery wiki tool also accepts a per-call `wikiRoot` override, and `wiki.ingest`\naccepts per-call `indexHeading` / `conceptHeading` / `entityHeading` overrides\nfor vaults whose pages use localized headings (e.g. `## Fontes`). When a\ntarget heading is missing from a page, the proposal degrades to `append` so it\ncan still be applied via `notes.edit`.\n\n### Per-vault config file\n\nSettings that belong to one vault rather than to the server — folder names,\nfilenames, and section headings of a localized wiki — go in a\n`.kobsidian.json` at the vault root. Every key is optional and beats the\nmatching env var; a per-call tool argument beats both\n(**per-call → `.kobsidian.json` → env → default**).\n\n```json\n{\n  \"$schema\": \"https://raw.githubusercontent.com/bezata/kObsidian/main/docs/kobsidian.config.schema.json\",\n  \"wiki\": {\n    \"root\": \"wiki\",\n    \"sourcesDir\": \"Fontes\",\n    \"staleDays\": 90,\n    \"headings\": {\n      \"indexSources\": \"Fontes\",\n      \"indexConcepts\": \"Conceitos\",\n      \"indexEntities\": \"Entidades\",\n      \"conceptPage\": \"Discussão\",\n      \"entityPage\": \"Fatos Notáveis\"\n    }\n  }\n}\n```\n\nUnknown keys and malformed JSON are rejected with the file path in the error\nso typos surface immediately; `vault.current` returns the effective\nconfiguration under `config` (or the error).\n\n---\n\n## Docs\n\nLocalized docs are available in **[简体中文](docs/i18n/zh-CN/README.md)**,\n**[日本語](docs/i18n/ja/README.md)**, and\n**[한국어](docs/i18n/ko/README.md)**.\n\n| | |\n|---|---|\n| [architecture.md](docs/architecture.md) | Stack, module map, layering rules |\n| [wiki.md](docs/wiki.md) | LLM-Wiki contract, loop, frontmatter, lint categories |\n| [examples.md](docs/examples.md) | Personal research wiki · engineering ADRs · codebase wiki — end-to-end |\n| [tools.md](docs/tools.md) | Namespace table, annotations, resources, prompts |\n| [SECURITY.md](docs/SECURITY.md) | Origin/CORS, VirusTotal scans, env hygiene |\n| [TESTING.md](docs/TESTING.md) | `bun run …` commands + coverage |\n| [ENVIRONMENT.md](docs/ENVIRONMENT.md) | Every env var with defaults |\n| [MIGRATION.md](docs/MIGRATION.md) | Upgrade notes |\n\n---\n\n## Roadmap\n\nThe next two milestones are tracked in [`TODO.md`](TODO.md):\n\n- **v0.4 — Obsidian LiveSync bridge.** Free, end-to-end-encrypted\n  vault access via the community\n  [Self-Hosted LiveSync](https://github.com/vrtmrz/obsidian-livesync)\n  plugin (CouchDB / S3 / R2 / WebRTC peer) — so an MCP client can\n  reach the same Obsidian vault from any machine the user owns,\n  without Obsidian itself being live.\n- **v0.5 — Cross-semantic vault verification.** A `wiki.crossCheck`\n  tool that reconciles two or more LiveSync-paired vaults at the\n  wiki layer, gated by a new `schema_version` frontmatter field that\n  uses the project's semver discipline as the compatibility contract.\n\n`TODO.md` carries the motivation, the per-milestone task breakdown,\nand the rules for how items move from there into the CHANGELOG.\n\n---\n\n## Development\n\n```bash\nbun install\nbun run typecheck\nbun run lint\nbun run test          # 56 tests across 14 files\nbun run build         # node-target stdio.js + bun-target http.js\nbun run inventory     # regenerate docs/tool-inventory.json\n```\n\nProject conventions in [`AGENTS.md`](AGENTS.md).\n\n---\n\n## Security & supply chain\n\n- **Every `.mcpb` release asset is VirusTotal-scanned.** The `Release`\n  workflow uploads each `kobsidian-<platform>.mcpb` bundle to\n  [VirusTotal](https://www.virustotal.com) via\n  [`crazy-max/ghaction-virustotal@v4`](https://github.com/crazy-max/ghaction-virustotal)\n  right after the release is published, then appends the analysis links\n  to the release body. Any user installing from a GitHub release can\n  click through to the public VirusTotal report for their platform's\n  bundle **before** they run it — no trust in the maintainer required.\n\n- **Transport hardening.** Streamable HTTP validates `Origin` against\n  an allowlist (403 on mismatch), implements CORS preflight\n  (`OPTIONS /mcp` → 204 + `Access-Control-*`), requires or defaults\n  `MCP-Protocol-Version`, and supports optional bearer auth via\n  `KOBSIDIAN_HTTP_BEARER_TOKEN`. stdio has no network surface.\n\n- **Pinned SDK floor.** `@modelcontextprotocol/sdk@^1.26.0` — mitigates\n  `GHSA-345p-7cg4-v4c7` (cross-client response leak) and\n  `CVE-2026-0621` (UriTemplate ReDoS). This repo pins `1.30.0`.\n\n- **npm Trusted Publishing.** No long-lived `NPM_TOKEN` is stored in the\n  repo. GitHub Actions mints a short-lived OIDC token on every tag push\n  and the npm CLI exchanges it for a one-time publish token scoped to\n  this exact workflow file (`.github/workflows/release.yml` on the\n  `bezata/kObsidian` repo). Provenance attestations are automatic — every\n  published version has a cryptographically-linked build statement\n  pointing at the exact Actions run that produced it. Forks, other\n  branches, or modified workflow files cannot publish — the OIDC\n  audience claim won't match.\n\nFull notes in [`docs/SECURITY.md`](docs/SECURITY.md).\n\n---\n\n## Compatibility notes\n\n- **Protocol version** — `2025-11-25` (current MCP spec). HTTP clients\n  without `MCP-Protocol-Version` fall back to `2025-03-26` per spec;\n  explicit-but-unsupported versions return 400.\n- **Dataview split** — offline tools index frontmatter / inline / list /\n  task / fenced `dataview` / fenced `dataviewjs` blocks. Runtime DQL is\n  delegated to Obsidian + Dataview through the Local REST API.\n  DataviewJS is source-preserving but not executed inside this server.\n- **Mermaid + Marp** — source-preserving parse/edit only; rendering is\n  the client's job.\n- **SDK floor** — `@modelcontextprotocol/sdk@^1.26.0` (mitigates\n  `GHSA-345p-7cg4-v4c7` cross-client response leak + `CVE-2026-0621`\n  UriTemplate ReDoS). This repo pins `1.30.0`.\n\n---\n\n## Credits\n\n- **LLM Wiki pattern** — [Andrej Karpathy's gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f).\n  kObsidian is one concrete, filesystem-first TypeScript implementation\n  of the idea.\n- **Memex** — Vannevar Bush, [_As We May Think_, 1945](https://www.theatlantic.com/magazine/archive/1945/07/as-we-may-think/303881/).\n  The associative-trails concept is what the wiki's cross-reference\n  graph tries to be.\n- **Model Context Protocol** — [Anthropic + the Agentic AI Foundation](https://modelcontextprotocol.io).\n- **Obsidian** — [obsidian.md](https://obsidian.md). The vault format\n  is authoritative; kObsidian respects it, doesn't migrate it.\n\n## License\n\nMIT — see [LICENSE](LICENSE). Contributions welcome; open an issue first\nfor anything non-trivial.\n",
  "bytes": 37980,
  "sha": "7406e18753fa857c402e5b6146fab05bc56719c1d534cbc63d9c096888337fe3",
  "repo_slug": "bezata/kobsidian",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_bezata_kobsidian_mcp_116d1e13/readme"
}