Headless Obsidian MCP
Headless Obsidian MCP Server gives AI assistants full, structure-aware access to an Obsidian vault for searching, browsing, traversing, querying, auditing, and optionally editing notes—without needing Obsidian running.
Search:
search_notesfor literal/regex ripgrep searches with scoping, pagination, and context;search_notes_rankedfor BM25 relevance-ranked full-text;resolve_noteandresolve_daily_notefor human-friendly name resolution.Browse & Read:
read_notes,list_notes,list_files,list_folders;get_outline,read_section;get_frontmatter,get_property;list_templates,list_tasks.Traverse:
get_links(outbound wikilinks, unresolved links, backlinks);get_related_notes(ranked by shared tags, links, co-citations).Query & Filter:
query_noteswith frontmatter operators (eq,ne,gt,contains, etc.);find_by_tag;list_recent_notes;list_tags,list_properties,list_property_values.Audit:
get_vault_stats(overall health);list_vault_issues(orphans, broken wikilinks, dead anchors, conflicts).Editing (opt-in): Create, append, prepend, move, delete notes; surgical tag/frontmatter/section edits; bulk edit; folder management. Moving/renaming auto‑updates inbound links; deletions go to
.trash; write operations report any broken links they introduce.Tasks: List checkbox tasks and toggle their state.
Templates: List and apply Obsidian core templates with variable expansion.
Git Sync (opt-in): Auto‑commits after writes; pull/push; non‑destructive merge conflict resolution.
Safety & Config: Read‑only by default; writes are opt‑in and per‑tool group restrictable;
get_configalways available to report tool policy, git sync status, and template settings.
Provides tools for interacting with an Obsidian vault, enabling full-text search, link graph navigation, tag management, structure-aware editing, and vault hygiene operations.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Headless Obsidian MCPsearch my vault for meeting notes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Headless Obsidian MCP
An MCP server that gives AI assistants full access to an Obsidian vault — search, the link graph, tags, and structure-aware editing — without needing a running copy of Obsidian. Ideal for a headless server running your Hermes or OpenClaw agents.
It reduces token cost and removes the need for your agent to understand Obsidian vault conventions, so your agent can read your vault as a knowledge base rather than a folder of text files: [[wikilinks]] resolve the way Obsidian resolves them, tags unify inline #tags with frontmatter, and edits are surgical (change one section or one tag without rewriting the note).
Read-only by default. Out of the box the server exposes only read tools; writing is opt-in through a single environment variable.
Status: 0.x. The server is tested and in daily use, but the tool surface is still settling — tool names, parameters, and return shapes may change between releases. Following semver's 0.x convention, breaking changes bump the minor version (0.2.0) and fixes bump the patch (0.1.1). Pin a version if you depend on a specific tool contract.
What it can do
Literal/regex search via ripgrep ( | |
List notes, folders, attachments, tags, and frontmatter properties. Read a note's outline or one section without loading the whole thing. | |
Resolve | |
Filter notes by frontmatter conditions ( | |
Whole-vault stats, then drill into the actual orphaned notes, broken wikilinks, and dead heading anchors. | |
Edit (opt-in) | Create, append, prepend, move, and delete notes. Change a tag, a frontmatter field, or one section without rewriting the note. Bulk-edit many notes in one call. Create, move, and delete folders too. See Enabling writes. |
Moving a note rewrites the wikilinks that point to it; renaming a heading rewrites inbound anchors. Every write reports any broken links it introduced. Deletes go to | |
Sync (opt-in) | If the vault is a git repo, snapshot every write as a commit — optionally pulling and pushing a remote per write or on a background timer. Merge conflicts are resolved non-destructively: your version is always preserved. See Git safety net. |
Templates from Obsidian's core Templates plugin are supported ({{title}}, {{date:FORMAT}}, …); Templater scripting is not.
→ Full tool reference — all 49 tools with parameters and return shapes.
Related MCP server: Obsidian MCP Tool Server
Quick start
Requires Node.js 20+, ripgrep, and an Obsidian vault.
git clone <this-repo> && cd headless-obsidian-mcp
npm install && npm run build
export OBSIDIAN_VAULT_PATH="/path/to/your/vault"
npm startThen point an MCP client at it. For Claude Desktop (~/.config/claude/claude_desktop_config.json on macOS/Linux, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"obsidian": {
"command": "node",
"args": ["/absolute/path/to/headless-obsidian-mcp/dist/index.js"],
"env": {
"OBSIDIAN_VAULT_PATH": "/absolute/path/to/your/vault"
}
}
}
}Restart the client and the server appears as obsidian. To let the agent edit the vault, add "OBSIDIAN_TOOLS": "all" to that env block — see Enabling writes.
Ready-to-copy configs for Claude Desktop, Claude Code, and Docker are in examples/.
Configuration
Only OBSIDIAN_VAULT_PATH is required. .env.example documents all eight variables the server reads.
Nothing here loads a
.envfile — an MCP server inherits its environment from the client that spawns it. Set variables in your client'senvblock (or pass--env-fileto Docker).
Enabling writes
OBSIDIAN_TOOLS selects exactly which tools the server exposes. Unset, it means reads: the 24 write tools are hidden from the tool list, and calling one is rejected.
OBSIDIAN_TOOLS="all" # everything
OBSIDIAN_TOOLS="reads,tasks.write,sections.write" # read all; write only tasks and sections
OBSIDIAN_TOOLS="all,-bulk,-delete_note" # everything except the destructive ones
OBSIDIAN_TOOLS="-templates,-tasks" # reads, minus two groups
OBSIDIAN_TOOLS="search,notes.read" # minimal search-and-read agentSelectors are case-insensitive and applied left to right — a plain token adds, a - prefix subtracts. Valid tokens are the meta-groups all / reads / writes, a domain group, a mode slice like notes.write, or an individual tool name. Evaluation starts from nothing, unless the first token subtracts, in which case it starts from reads — so -templates trims the read surface and can never accidentally expose writes.
The eleven domain groups:
Group | Read | Write |
| search_notes, search_notes_ranked | — |
| read_notes, list_notes, list_recent_notes, resolve_note, resolve_daily_note | write_note, append_note, prepend_note, patch_note, delete_note, move_note |
| get_outline, read_section | add_section, append_to_section, replace_section, rename_section |
| get_links, get_related_notes | — |
| list_tags, find_by_tag | add_tag, remove_tag |
| get_frontmatter, list_properties, list_property_values, query_notes, get_property | set_frontmatter, add_property_values, remove_property_values, rename_property |
| list_tasks | set_task_state |
| list_templates | apply_template, insert_template |
| list_files, list_folders | move_file, create_folder, move_folder, delete_folder |
| get_vault_stats, list_vault_issues | — |
| — | bulk_edit |
get_config sits in no group and is always exposed — its tools section reports the active policy, so an agent can discover why a tool is missing.
Excluding tools also saves tokens: an excluded tool is a schema the client never carries in context.
An unknown selector, or a policy that selects nothing, aborts startup with the valid vocabulary listed. The policy gates the MCP server only; the query CLI is the operator's own tool and ignores it.
Git safety net (OBSIDIAN_GIT_SYNC)
If your vault is a git repository, the server can snapshot every write:
Mode | Behavior |
| No git involvement. |
| Commits after every write, with a message naming the tool. No remote. |
| Commits, then pulls and pushes the remote after each write. |
| Commits per write; pulls and pushes on a background interval instead. |
OBSIDIAN_GIT_SYNC_INTERVAL sets the timer cadence in seconds (default 300); OBSIDIAN_GIT_REMOTE names the remote (default origin).
The guard is fail-closed: in any mode but off, a write is refused before touching disk if the vault isn't a usable git repo, and a failed post-write commit throws — a write never lands without its snapshot. The lone exception is the background timer tick, whose failures are recorded in get_config's sync.last_error rather than thrown, since no write is in flight to fail.
Conflicts are never blocking or destructive. On a real merge conflict, per file: if both sides changed the note, your version is preserved as a <note> (conflicted YYYY-MM-DD HHMMSS) copy and the canonical path takes the remote's; if the remote deleted a note you'd modified, the same copy preserves your version; if you deleted a note the remote modified, the remote version is restored. Find unreconciled copies with list_vault_issues kind:"conflicts".
Docker
The Dockerfile builds a multi-stage node:20-alpine image with ripgrep and git installed — both are hard runtime dependencies, not conveniences.
docker build -t headless-obsidian-mcp .
docker run -i --rm -v "$HOME/vault:/vault:ro" headless-obsidian-mcp-i is load-bearing: this is a stdio server, and without an open stdin the transport never comes up. The vault mounts at /vault and the container runs as the unprivileged node user. For writes, drop :ro and add --user "$(id -u):$(id -g)" so new files land owned by you. Client config: examples/mcp.docker.json.
There's no docker-compose.yml by design — an MCP stdio server is spawned per client, not supervised as a service.
Development
npm run dev # watch mode via tsx, no build step
npm run build # compile to dist/
npm test # node:test via tsx
npm run query # query CLI — see docs/CLI.mdmise run <task> works for each if you use mise.
The query CLI calls the tools directly and prints raw JSON, which makes it the fastest way to try something without wiring up a client.
Tests build a throwaway fixture vault in a temp directory and cover link resolution, tag aggregation, listing and recency, index cache invalidation, and the security guards (path traversal, symlink escapes, frontmatter hardening). CI runs build and tests on Node 20 and 22 for every PR and push to main, installing real ripgrep and a git identity — the suite drives the actual rg binary and real repositories rather than stubs.
Design rationale, tool-naming taxonomy, and the invariants that keep the tool surface coherent live in CLAUDE.md.
Agent skill
skills/obsidian-vault/SKILL.md is a copyable Agent Skill — drop it in ~/.claude/skills/obsidian-vault/ to give an agent workflow guidance for this server: which tool answers which intent, anti-patterns worth avoiding, and multi-step recipes for fixing broken links, processing the daily note, and restructuring without breaking the graph.
Acknowledgments
This project began as a Node.js port of notes-mcp by Boaz Yaniv, and has since been substantially extended with knowledge-base, structure-aware editing, and vault-management tools. The original is MIT licensed; that license and copyright are retained in LICENSE.
Thanks also to mcpvault by bitbonsai, whose Obsidian MCP server was a useful reference while shaping this project's tool surface.
License
Released under the MIT License.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityFmaintenanceA local MCP server that enables AI applications like Claude Desktop to securely access and work with Obsidian vaults, providing capabilities for reading notes, executing templates, and performing semantic searches.831MIT
- Alicense-qualityDmaintenanceProvides an MCP server that allows AI assistants to interact with Obsidian vaults, enabling reading/writing notes, managing metadata, searching content, and working with daily notes.36MIT
- Flicense-qualityDmaintenanceA local MCP server that wraps the Obsidian CLI to give AI assistants direct access to read, edit, and manage notes within an Obsidian vault. It enables advanced operations such as frontmatter property management, context-aware searching, and the execution of internal Obsidian commands.2
- AlicenseBqualityDmaintenanceAn MCP server that enables AI assistants to access and manage your local Obsidian vault through a standardized protocol.142,4721Apache 2.0
Related MCP Connectors
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
Driflyte MCP server which lets AI assistants query topic-specific knowledge from web and GitHub.
An MCP server that gives your AI access to the source code and docs of all public github repos
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/emguide/headless-obsidian-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server