obsidian-mcp
An MCP server that gives an AI agent read and write access to a folder ofMarkdown notes. Point it at an Obsidian vault, a Logseq graph, or any notesdirectory.
Four tools, no dependencies beyond the MCP SDK, one file.
search_notes full-text search with surrounding context
read_note read one note by relative path
list_notes enumerate notes, optionally under a subfolder
write_note create a note, or append to an existing one
Setup
pip install -r requirements.txt
Register it with Claude Code by adding a .mcp.json at the root of yourproject:
{
"mcpServers": {
"vault": {
"command": "python",
"args": ["/path/to/server.py"],
"env": { "VAULT_ROOT": "/path/to/your/vault" }
}
}
}
Restart your session. You'll be asked to approve the server on first use βit can write files, so that prompt is doing real work.
Configuration
| variable | default | meaning |
|---|---|---|
VAULT_ROOT |
current directory | the folder to expose |
VAULT_READONLY |
unset | set to 1 to drop write_note entirely |
VAULT_MAX_RESULTS |
20 | search result cap |
VAULT_MAX_BYTES |
100000 | truncation limit for read_note |
VAULT_READONLY=1 removes the write tool from the advertised list rather thanjust refusing calls, so an agent never sees a capability it can't use.
Two things worth knowing
Path traversal is checked properly. Every caller-supplied path is resolvedand compared against the vault root:
p = (VAULT_ROOT / rel).resolve()
if not p.is_relative_to(VAULT_ROOT):
raise ValueError(...)
Resolve-then-compare, not a string prefix test β .. and symlinks both defeatstring comparison, and without this ../../.ssh/id_rsa is a valid note path.
Errors are returned, not raised. A tool that throws takes the server down,and a dead MCP server is a silent one β the agent simply stops having thecapability and carries on without mentioning it. Returning the error text meansthe agent can see what went wrong and tell you.
Scope
Deliberately small. No embeddings, no vector index, no frontmatter parsing, nograph traversal. Full-text search over Markdown covers most of what an agentactually needs, and it has no index to rebuild or fall out of date.
Search returns one hit per note, which keeps results readable when a termappears forty times in one file.
Licence
MIT