Marcus Breiden400 downloadsSecurity-first MCP gateway with default-deny permissions and audit logging.
Security-first Model Context Protocol server plugin for Obsidian. Gives AI assistants controlled, granular access to your vault through eight tools: kado-read, kado-write, kado-delete, kado-rename, kado-search, kado-open-notes, kado-graph, and kado-graph-audit.
Part of the MiYo family. The plugin is referred to as MiYo Kado in the Obsidian community-plugin index and in the settings UI; "Kado" alone is used as a short form throughout this README and the source.
Letting an AI assistant talk to your vault sounds great until you realize most integrations give the assistant everything -- every note, every file, full read/write. Kado is built around the opposite default:
127.0.0.1 by default. No cloud, no telemetry, no third party.If you've ever wanted to say "this assistant can read my project notes but not my journal, and can delete drafts but never touch archived material", Kado is for you. For a deeper look at why AI permissioning matters for PKM workflows -- and why guardrails are not the same as real permissions -- see Permissioning your AI.
firstXChars, firstXWords for a Unicode-aware word preview, section by heading, range by line/char) and write in place (append/prepend, insertUnderHeading, replaceSection/replaceRange) without round-tripping the whole body; omitting the mode is byte-for-byte backward compatiblekado-rename renames or moves notes and files with backlinks updated automatically; one folder ⇒ rename (needs update), across folders ⇒ move (needs delete on the source + create on the target). Works best with Obsidian's "Automatically update internal links" on (silent, links updated); with it off the tool is hidden unless you opt in, and then each rename prompts Obsidian's link-update dialog (the file still moves, but inbound links update only when you answer)kado-write auto-creates missing parent folders (mkdir -p), kado-delete with operation="folder" trashes an empty folder (non-empty is refused — no recursive delete), and kado-rename with operation="folder" renames a folder in place (same parent). A folder rename is permission-neutral: if moving the subtree under the new name would change any descendant's effective access, the rename is refused rather than silently crossing a permission boundary — and Kado never rewrites your permission rules to make it fitbyContent is full-text ranked: it matches notes containing any query term, scores them by term coverage and proximity, and returns relevance snippets (with line numbers), best-firstkado-graph traverses the vault's link structure: backlinks, outgoing, neighbors (1-hop), related (2-hop, with the via neighbour), and dangling (unresolved link targets). Resolved nodes outside the key's scope are silently omitted, so a traversal can never disclose a path the key cannot readkado-graph-audit returns all orphans (notes with no resolved links in or out) and all dead wikilinks across the whole vault in a single call, ACL-filtered and paginated -- the whole-vault counterpart to kado-graph, answered from Obsidian's in-memory link index without per-note reads_hints array suggesting the sensible next step (re-read after a CONFLICT, fetch the next page when a cursor is present, continue a truncated read). Purely advisory and safe to ignore0 disables)MiYo Kado is one component of the MiYo multi-repo system. Kado is the Obsidian-side
MCP gateway: it owns the vault access-control model (two-layer path eligibility + per-key
CRUD scopes) and exposes the MCP tool surface that companion tools such as MiYo Tomo
consume. The authoritative record for cross-repo contracts, system-level architecture, and
governance decisions lives in MiYo Kokoro; this repo's local design docs (below, and
docs/XDD/specs/) defer to Kokoro for project-wide principles. Cross-component contract
changes (e.g. new MCP tools) are handed off to Kokoro via _outbox/for-kokoro/.
Internally Kado follows a four-layer clean architecture: MCP boundary (src/mcp/) →
permission gates + policy (src/core/) → Obsidian adapters (src/obsidian/) → canonical
types (src/types/). See How It Works for the enforcement flow.
| Document | Audience | Content |
|---|---|---|
| Installation | Everyone | Community Plugins, BRAT, manual install |
| Configuration Guide | Vault owners | Settings UI, security setup, API key management |
| Client Setup | Vault owners | Claude Code, Claude Desktop, Cursor, Windsurf |
| How It Works | Vault owners | Architecture, security model, enforcement logic, audit log |
| Example Configurations | Vault owners | Common setups with permission matrices |
| API Reference | MCP client developers | Tool schemas, parameters, examples, error codes |
| Development Guide | Contributors | Build, test, lint, architecture, live testing |
| Permissioning your AI | PKM practitioners | Why AI permissioning matters, guardrails vs enforcement |
Tracked as GitHub issues:
CONFLICT error and shows a Notice ("Kado wanted to modify <note> ..."). Your typing always wins. The AI client sees the same conflict signal used for any concurrent change and is expected to re-read and retry, so once you pause typing (~2 s Obsidian autosave) and it retries, its write is applied on top of your latest edits.notes/, projects/, or ** for full vault){
"mcpServers": {
"kado": {
"type": "http",
"url": "http://127.0.0.1:23026/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}
General tab -- server status, port, audit logging, and backup & restore.
Global Security tab -- whitelist of paths and tags that any key may reference. Permissions are set per data type (Notes, Frontmatter, Dataview, Files) for each path.
Permission Test tab -- dry-run any key + operation + path against the real permission chain (in memory) and see ALLOWED/DENIED with the deciding gate.
API Key tab -- per-key access. Each key has its own access mode, paths, tags, and permission matrix, all constrained by the global security scope.
Backup & restore -- export the whole config to a JSON file, or import one and choose per-section (general / global security / each key) what to restore.
Every request passes through five gates in order. The first denial stops the chain. For the full enforcement logic, see How It Works.
| # | Gate | Purpose |
|---|---|---|
| 0 | authenticate | Bearer token must match an enabled API key |
| 1 | global-scope | Path must be inside the global whitelist (or outside the blacklist) |
| 2 | key-scope | Path must be inside the key's own scope |
| 3 | datatype-permission | Key must have the required CRUD flag for the data type |
| 4 | path-access | Final path-traversal and validation check |
MCP Client -> [MCP API Handler] -> [Kado Core] -> [Obsidian Interface] -> Vault
Kado is part of MiYo, a small family of Obsidian-adjacent tools focused on giving you control over what your assistants can see and do. MiYo Kado is the gateway component -- the piece that turns your vault into a properly-scoped MCP server. More tools are in the works.
Live issues and upstream references live in GitHub Issues and docs/ai/memory/troubleshooting.md. No open issues at the time of this release.
If MiYo Kado is useful to you and you want to help me keep building, you can support development via:
Issues and pull requests are also very welcome.
Contributions are welcome. The short version:
master. Use a descriptive branch name (e.g. fix/search-tag-case, feat/granular-scopes).npm run build, npm test, and npm run lint before pushing.feat:, fix:, docs:, refactor:. Release notes are generated from commit history.master and reference the issue. Small, reviewable diffs get merged fastest.For security issues, please do not open a public issue -- email [email protected] instead.