MCPVault

Local stdio server for reading, searching and editing notes in an Obsidian vault on disk

By Mauricio Wolff (individual) TypeScript Local · stdio ProductivityKnowledge and memory

82 popularity score ★ 1.7k ↓ 27k/wk

Connect your client

Local (npm)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

Claude CodeTerminal
claude mcp add mcpvault -- npx -y @bitbonsai/mcpvault@latest '<VAULT_PATH>'
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "mcpvault": {
      "command": "npx",
      "args": [
        "-y",
        "@bitbonsai/mcpvault@latest",
        "<VAULT_PATH>"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "mcpvault": {
      "command": "npx",
      "args": [
        "-y",
        "@bitbonsai/mcpvault@latest",
        "<VAULT_PATH>"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "mcpvault": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@bitbonsai/mcpvault@latest",
        "<VAULT_PATH>"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.mcpvault]
command = "npx"
args = ["-y", "@bitbonsai/mcpvault@latest", "<VAULT_PATH>"]
Gemini CLITerminal
gemini mcp add --scope user mcpvault npx -- -y @bitbonsai/mcpvault@latest '<VAULT_PATH>'

What it does

MCPVault is started by an MCP client as a local process and pointed at one Obsidian vault folder. It works on the Markdown files directly, so Obsidian itself does not have to be open and no Obsidian plugin is installed. Note tools handle .md, .markdown, .txt, .base and .canvas files; listing and move_file also see other files such as images and PDFs.

It has 18 tools: reading whole notes, line ranges or just a heading outline; writing, patching, appending or prepending; moving, renaming and deleting; reading and merging YAML frontmatter; adding and removing tags; a vault-wide tag list; vault statistics; resolving [[wiki links]]; and a keyword search ranked with BM25. Frontmatter edits keep the formatting of fields that were not changed.

Two launch options follow the vault path. --read-only (since 0.15.0) hides the 7 tools that change the vault and refuses them if called, leaving 11 read tools. --exclude <subtree> (since 0.17.0, repeatable, also --exclude=<subtree>) hides a vault-relative folder from search_notes and list_directory; a per-call excludePaths on search_notes adds to it. The read and write tools can still open excluded files, so it is a tidiness filter, not an access control, and list_directory called on an excluded folder returns an error rather than an empty list (src/createServer.ts). The server does not read Obsidian's own excluded-files setting.

The code sets caps the README examples do not spell out: search_notes returns 5 results unless limit is given and never more than 20, get_vault_stats lists 5 recent files by default and at most 20, and read_multiple_notes takes up to 10 paths (src/createServer.ts). Any argument that is not one of the two options is joined into the vault path, so a mistyped flag becomes part of the path rather than an error (src/cli.ts). Note tools have refused dotfiles such as .env since 0.14.1, and unresolved symlinks have failed closed since 0.17.1 (CHANGELOG.md).

What it needs

RuntimeNode.js 22.12+
Runs onmacOS, Windows, Linux
Also
  • An Obsidian vault or folder of Markdown notes on the same machine

Node.js 22.12.0 or later, which also supplies npx. Since 0.18.0 Node 20 is no longer supported; anyone who must stay on Node 20 can pin @bitbonsai/mcpvault@0.17.3, the last release that runs there. An MCP client that can launch local stdio servers. No account, API key or running Obsidian app is needed. Add --read-only or --exclude <subtree> to the args after the vault path to use those options.

Limits

  • Not covered Search is keyword matching with BM25 ranking, not semantic or embedding search.
  • Size cap search_notes returns 5 results by default and at most 20; read_multiple_notes takes at most 10 paths.
  • Limit delete_note deletes permanently unless trashMode is set to local or system.
  • Not covered move_file moves single files, not folders.
  • Not covered Dotfiles, .obsidian, .git and node_modules are hidden from every tool.
  • Limit --exclude only hides folders from search_notes and list_directory; read and write tools still reach them.
  • Limit With no vault path given, the server uses the directory the client starts it in; unknown arguments become part of the path.
  • Not covered One vault per server entry; several vaults need several entries.
  • Limit The README's snippets omit -y for npx; the command here adds it so npx does not stop to ask before installing.

Search is plain keyword matching with BM25 ranking, not semantic search; it returns 5 results by default and at most 20. Batch reads stop at 10 notes. delete_note deletes permanently unless trashMode is set to local or system. move_file moves single files, not folders. Dotfiles, .obsidian, .git, node_modules and .trash are hidden from every tool. If no vault path is passed, the server uses the directory the client starts it in. One vault per server entry; several vaults need several entries. The README's own snippets omit -y for npx; the command here adds it so npx does not stop to ask before installing.

Who it suits

Suits someone who keeps notes in Obsidian, or any Markdown folder, and wants an assistant to read, search and tidy them locally without installing an Obsidian plugin or keeping the app open. With --read-only it fits sensitive vaults where the assistant should only look; --exclude keeps archives out of search results but does not wall them off. Pick something else if you need semantic or embedding search, access to a vault on another machine or a sync service, or control of the Obsidian app itself (commands, plugins, the open editor), which this server does not touch.

Tools 18

11 only read, 5 change things, 2 can delete or overwrite. A ? marks an optional parameter.

read_note
Return one note's content with its frontmatter parsed.path: stringprettyPrint?: boolean
write_note deletes
Create or replace a note, or append or prepend to it, with optional frontmatter.path: stringcontent: stringfrontmatter?: objectmode?: enum
patch_note changes
Replace an exact string in a note; fails on multiple matches unless replaceAll is set.path: stringoldString: stringnewString: stringreplaceAll?: boolean
list_directory
List folders and files at a path, leaving out subtrees set with --exclude.path?: stringprettyPrint?: boolean
delete_note deletes
Delete a note after a matching confirmPath; permanent by default, or to vault or system trash.path: stringconfirmPath: stringtrashMode?: enum
search_notes
Keyword search over note text and optionally frontmatter, BM25-ranked; 5 results by default, 20 at most.query: stringlimit?: numbersearchContent?: booleansearchFrontmatter?: booleancaseSensitive?: booleanpathPrefix?: stringexcludePaths?: arrayprettyPrint?: boolean
move_note changes
Move or rename a note file.oldPath: stringnewPath: stringoverwrite?: boolean
move_file changes
Move or rename any single file, such as an image, with both paths confirmed.oldPath: stringnewPath: stringconfirmOldPath: stringconfirmNewPath: stringoverwrite?: boolean
read_multiple_notes
Read up to 10 notes in one call.paths: arrayincludeContent?: booleanincludeFrontmatter?: booleanprettyPrint?: boolean
update_frontmatter changes
Merge or replace a note's frontmatter without touching its body.path: stringfrontmatter: objectmerge?: boolean
get_notes_info
Return size, modified time and frontmatter presence for notes.paths: arrayprettyPrint?: boolean
get_frontmatter
Return only a note's YAML frontmatter.path: stringprettyPrint?: boolean
manage_tags changes
List, add or remove tags on a note.path: stringoperation: enumtags?: array
get_vault_stats
Count notes, folders and total size, and list recently changed files.recentCount?: numberprettyPrint?: boolean
list_all_tags
Collect frontmatter and inline tags across the vault, sorted by frequency.prettyPrint?: boolean
wiki_link
Resolve a [[wiki link]] to a note and return it, with any other matching paths.document: stringprettyPrint?: boolean
get_note_outline
List a note's headings with levels and line numbers.path: stringprettyPrint?: boolean
read_note_lines
Return a chosen line range from a note.path: stringstartLine: numberendLine: numberprettyPrint?: boolean

Similar servers