使用说明
Obsidian MCP
An MCP (Model Context Protocol) server that connects your LLM to your Obsidian vault. Read, write, search, and organize your notes through natural conversation.
Built on top of the Obsidian Local REST API plugin. This MCP requires Local REST API 5.0.0 or newer and targets 5.2.0.
Background
This project started as a personal tool for managing a D&D campaign in Obsidian — keeping NPCs, session notes, world lore, and plot threads consistent with the help of an LLM. If you've ever wanted an AI that actually knows your vault, can cross-reference your notes, and helps you keep everything coherent across dozens of interlinked documents, that's the itch this scratches.
It's built for personal use, but structured and documented enough to be useful to anyone doing something similar.
Features
- Read & write notes — create, update, append, copy, move, and trash notes
- Search — find notes by filename, path text, structured query, or full-text search across the vault
- Batch operations — read, append, or trash multiple notes in parallel
- Tree view — display vault structure with configurable depth
- Section editing — update content under a specific heading without rewriting the whole note
- Frontmatter — update YAML frontmatter fields (tags, dates, metadata)
Prerequisites
- Obsidian with the Local REST API community plugin installed and enabled; requires Local REST API 5.0.0+
- uv (Python package manager)
- Python 3.13+
- (Optional) Obsidian 1.12+ with the CLI enabled (Settings → General → Advanced → "Command line interface") — required only for
get_unresolved_links
Docs
Setup
1. Configure the Obsidian plugin
- Open Obsidian → Settings → Community Plugins
- Search for Local REST API, install and enable it
- In the plugin settings, copy your API key and note the port (default
27123)
2. Install the MCP server
git clone https://github.com/Vosloo/Obsidian-MCP.git
cd Obsidian-MCP
uv sync
3. Set environment variables
cp .env.example .env
Edit .env:
OBSIDIAN_API_URL=https://127.0.0.1:27124
OBSIDIAN_API_KEY=your_api_key_here
4. Test the connection
uv run obsidian-mcp
If the server starts without errors, you're good to go. Press Ctrl+C to stop it.
To test the MCP manually with the MCP Inspector from the project directory:
npx @modelcontextprotocol/inspector uv run obsidian-mcp
Connecting to your LLM
Claude Desktop
Edit your config file:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Add the server entry (replace the path with your actual project path):
{
"mcpServers": {
"obsidian": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/Obsidian-MCP",
"run",
"obsidian-mcp"
],
"env": {
"OBSIDIAN_API_URL": "https://127.0.0.1:27124",
"OBSIDIAN_API_KEY": "your_api_key_here"
}
}
}
}
Restart Claude Desktop. The Obsidian tools should appear in the interface.
Claude Code (CLI)
Add to your .claude/settings.json or run:
claude mcp add obsidian -- uv --directory /absolute/path/to/Obsidian-MCP run obsidian-mcp
Set the environment variables in your shell or .env file before launching.
Other MCP clients
Any client that supports the Model Context Protocol can connect. Point it at:
uv --directory /path/to/Obsidian-MCP run obsidian-mcp
The server communicates over stdio.
Available tools
| Tool | Description |
|---|---|
search_by_filename |
Find notes vault-wide by filename, filename stem, or path text; wildcards are also supported |
search_simple |
Search text across the vault using the Local REST API's server-side search |
search_query |
Run an advanced JsonLogic search against note metadata, paths, tags, and content |
search_in_note |
Search text within a specific Markdown note |
search_in_directory |
Search text across notes directly inside one directory; not recursive |
read_note |
Read a Markdown note as valid JSON with metadata, including unresolvedLinks from Local REST API 5.x |
read_note_markdown |
Read a .md note as raw Markdown |
read_image |
View a raster attachment as an MCP image block, resized by default or at full resolution up to 20 MiB |
create_note |
Create or overwrite a .md note |
append_to_note |
Append content to a .md note |
update_section |
Update content under a specific heading, with optional optimistic concurrency and duplicate-append protection |
update_frontmatter |
Update a frontmatter field |
move_note |
Move or rename a note to a new path using Local REST API native MOVE support |
copy_note |
Copy a note to a new path; existing destinations are protected by default |
delete_note |
Move a note to the trash configured in Obsidian |
list_directory |
List contents of a directory, or the vault root when path is omitted or / |
create_directory |
Prepare a directory path with a temporary placeholder; empty directories may not persist |
delete_directory |
Recursively move every file in a directory to configured Obsidian trash |
batch_read_notes |
Read multiple notes in parallel as per-path JSON results |
batch_append_to_notes |
Append to multiple Markdown notes and report each success or failure |
batch_delete_notes |
Trash multiple notes and report each success or failure |
tree_view |
Display directory structure as a tree |
get_vault_info |
Get vault name, path, API status, and MCP compatibility metadata |
get_unresolved_links |
Return filtered, structured JSON for broken wikilinks across the vault (requires Obsidian CLI) |
Local REST API 5.x behavior
- Note-content read and write tools accept only paths ending in
.md(case-insensitive). They reject attachments and other non-Markdown files before making an API request, preventing accidental binary decoding or text overwrites. Byte-safe listing, move, copy, trash, and directory operations remain available for all vault files.read_imageseparately accepts PNG, JPEG, WebP, GIF (first frame), BMP, and TIFF attachments. It resizes to a 1568-pixel long edge by default, with a 256 MiB download limit and early JPEG downsampling;full_resolution: truepreserves dimensions with a 20 MiB byte limit. SVG, binary writes, and signed-URL tools are not exposed. copy_noteandmove_notedefault toallow_overwrite: false. Set it totrueonly when replacing the destination is intentional.delete_note,batch_delete_notes, anddelete_directoryexplicitly sendpermanent=false. Local REST API then follows the deletion destination chosen in Obsidian: the vault.trashfolder, system trash, or permanent deletion if the user configured Obsidian itself that way.delete_directoryrefuses the vault root and reports every trashed or failed file individually.update_sectionacceptsreject_if_content_preexists: trueforappendandprepend. This makes retries fail instead of inserting the same text twice.read_noteandbatch_read_notesreturn valid JSON. Each Local REST API 5.x note object includesunresolvedLinks; batch results preserve the requested path and report failures individually.get_unresolved_linksremains the efficient vault-wide aggregator. Its JSON response includesavailable,filters,link_count, andlinks. Each link has avault_reference_countreported by the CLI and filteredsources. The count is explicitly vault-wide because the CLI cannot recalculate reference counts after source filtering.
Troubleshooting
| Problem | Solution |
|---|---|
OBSIDIAN_API_KEY must be set |
Create a .env file with your API key, then restart |
| Connection refused | Make sure Obsidian is running and the Local REST API plugin is enabled |
| Module not found | Run uv sync to install dependencies |
| Tools not showing in Claude | Check that the path in your config is absolute and uses forward slashes |
License
MIT