@wickedevolutions/mcp-obsidian
v1.4.0
Published
Multi-vault Obsidian MCP server — full AI operations toolset for file management, wikilinks, semantic search, frontmatter queries, daily notes, tasks, properties, templates, and more.
Maintainers
Readme
mcp-obsidian
Multi-vault Obsidian MCP server — full AI operations toolset for file management, wikilinks, semantic search, frontmatter queries, daily notes, tasks, properties, templates, and more.
Two-tier architecture: 75 tools work without Obsidian running + 28 CLI tools access Obsidian's runtime API when the app is running with CLI enabled (1.12+).
New in 1.4.0: graph orientation — analyze_link_hierarchy ranks your vault's link graph into hub→leaf structural levels (Obsidian-authoritative when the app is running); graph-aware search — every semantic_search hit carries its structural role; slash commands — five human-triggered MCP prompts (/orient, /search, /excluded, /vault-health, /get-started); an opt-in reranker + HyDE; a read-only / untrusted-content safety surface; and honest concept-link reporting for vaults that link concepts before creating notes. See CHANGELOG.
Install
Claude Desktop — one click
Download mcp-obsidian.mcpb, double-click, enter your vault paths. Done.
The one-click bundle is built and tested on macOS (Apple Silicon) only — it ships a prebuilt native module for that platform. On Intel Mac, Windows, or Linux, install via npm below instead; it compiles the native module for your platform at install time. (A cross-platform bundle is tracked for a later release.)
npm
npm install -g @wickedevolutions/mcp-obsidianOr run directly without installing:
npx @wickedevolutions/mcp-obsidianFrom source
git clone https://github.com/Wicked-Evolutions/Mycelium-for-Obsidian.git
cd Mycelium-for-Obsidian
npm install
npm run buildSetup
Works with Claude Code, Claude Desktop, Gemini CLI, Cursor, Windsurf, VS Code, and any MCP-compatible client.
All clients use the same server config — the only difference is where the config file lives.
Claude Code — quick add
claude mcp add -e OBSIDIAN_VAULTS='{"My Vault":"/path/to/vault"}' obsidian -- npx @wickedevolutions/mcp-obsidianServer Config Block
If you installed via npm (npm install -g @wickedevolutions/mcp-obsidian):
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["mcp-obsidian"],
"env": {
"OBSIDIAN_VAULTS": "{\"My Vault\":\"/path/to/your/vault\"}"
}
}
}
}If you cloned and built from source:
{
"mcpServers": {
"obsidian": {
"command": "node",
"args": ["/path/to/mcp-obsidian/dist/index.js"],
"env": {
"OBSIDIAN_VAULTS": "{\"My Vault\":\"/path/to/your/vault\"}"
}
}
}
}Where to Put the Config
| Client | Config file |
|--------|-------------|
| Claude Code | .mcp.json in your project root, or ~/.mcp.json for global access |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows) |
| Gemini CLI | ~/.gemini/settings.json (add the server block inside the existing mcpServers object) |
| Cursor | .cursor/mcp.json in project root |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (Copilot) | .vscode/mcp.json in project root |
Any AI client or IDE that supports the Model Context Protocol can use mcp-obsidian — add the server config block to your client's MCP configuration.
Multiple Vaults — One Server, All Vaults
A single mcp-obsidian server handles all your vaults. Pass them as a JSON object in OBSIDIAN_VAULTS — most tools accept an optional vault parameter to target a specific vault (authoritative graph orientation via analyze_link_hierarchy requires an explicit one):
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["@wickedevolutions/mcp-obsidian"],
"env": {
"OBSIDIAN_VAULTS": "{\"Work\":\"/Users/me/Vaults/Work\",\"Personal\":\"/Users/me/Vaults/Personal\",\"Research\":\"/Users/me/Vaults/Research\",\"Client Projects\":\"/Users/me/Vaults/Client Projects\"}"
}
}
}
}Then use the vault parameter on any tool call to target a specific vault:
{ "tool": "read_file", "args": { "vault": "Work", "path": "my-note.md" } }{ "tool": "search_all_vaults", "args": { "query": "project deadline" } }Omitting vault defaults to the first vault in the list. Cross-vault tools like search_all_vaults, find_note_by_name, and get_cross_vault_links operate across all configured vaults in a single call.
Single Vault
For a single vault, you can use the simpler environment variables instead of OBSIDIAN_VAULTS:
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["@wickedevolutions/mcp-obsidian"],
"env": {
"OBSIDIAN_VAULT_PATH": "/Users/me/Vaults/My Vault",
"OBSIDIAN_VAULT_NAME": "My Vault"
}
}
}
}Disabling Tools
To prevent specific tools from being exposed to MCP clients, set OBSIDIAN_DISABLED_TOOLS in the env block:
{
"env": {
"OBSIDIAN_DISABLED_TOOLS": "search_replace_in_file,eval_obsidian"
}
}Comma-separated list. Disabled tools are removed from both the tool list and handler registry at startup.
Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| OBSIDIAN_VAULTS | JSON object: {"name":"path",...} for multi-vault | - |
| OBSIDIAN_VAULT_PATH | Path to single vault (alternative to OBSIDIAN_VAULTS) | - |
| OBSIDIAN_VAULT_NAME | Display name for single vault | - |
| OBSIDIAN_DISABLED_TOOLS | Comma-separated list of tools to disable | - |
| OLLAMA_HOST | Ollama API endpoint | http://localhost:11434 |
| OLLAMA_EMBEDDING_MODEL | Model for embeddings | nomic-embed-text |
| HTTP_MODE | Run as HTTP server instead of STDIO | false |
| HTTP_PORT | Port for HTTP server | 3456 |
Features
- Unified Multi-Vault: Single server process handles all vaults. Most tools accept an optional
vaultparameter; authoritative graph orientation (analyze_link_hierarchy) requires an explicit one. - Two-Tier Architecture: 75 tools always available + 28 CLI tools when Obsidian 1.12+ is running
- Orientation & Self-Correction:
get_startedanddiscover_toolsmap the server's surface; configured vault names surface as anenumin each tool's input schema; unknown vault/note names return closest-match suggestions instead of bare errors - File Operations: List, read, create, update, delete, move files with frontmatter support
- Wikilink Resolution: Resolve
[[wikilinks]], get outlinks/backlinks, follow link chains - Semantic Search: Vector-based similarity search using Ollama embeddings
- Frontmatter Queries: Dataview-like query engine with 10 filter operators
- Vault Analytics: Health reports, orphan detection, broken links, stale notes
- Section Editing: Append, prepend, or replace content within specific markdown sections
- Cross-Vault Search: Search across all vaults simultaneously
- Daily Notes: Read, append, prepend to daily notes (CLI)
- Tasks: List and update tasks across the vault (CLI)
- Properties: List all frontmatter properties with types, get all unique values for any property (CLI)
- Templates & Bases: Access templates and Obsidian database views (CLI)
- Commands & History: Execute Obsidian commands, access file version history (CLI)
- Tool Filtering: Disable specific tools via
OBSIDIAN_DISABLED_TOOLSenv var
Two-Tier Architecture
| Tier | Tools | Requires | Always Available | |------|-------|----------|-----------------| | Filesystem | 75 tools | Node.js only | Yes — works without Obsidian running | | CLI-only | 28 tools | Obsidian 1.12+ running | No — graceful error if app not running |
Filesystem tools read and write vault files directly. They work whether Obsidian is open or not.
CLI tools access Obsidian's runtime API (app.vault, app.metadataCache, app.fileManager, etc.) via the Obsidian CLI. They provide access to features that only exist in the running app — metadata cache, daily notes configuration, task parsing, property types, backlink index, version history, and more.
If Obsidian is not running, CLI tools return a clear error message. All filesystem tools continue to work normally.
Enabling the Obsidian CLI
To use the 28 CLI-only tools, you need Obsidian 1.12+ with CLI enabled. In Obsidian: Settings → General → Enable "Command line interface", then follow the prompt to register. See the Obsidian CLI documentation for install and troubleshooting details.
Available Tools (103)
Always Available (75 tools — no Obsidian required)
Orientation (2)
| Tool | Description |
|------|-------------|
| get_started | Orientation guide — configured vaults, tool categories with counts, and tier/resolver guidance. Call first in a new session |
| discover_tools | Compact paginated inventory of all tools with category and tier (filesystem/cli) |
File Operations (9)
| Tool | Description |
|------|-------------|
| list_files | List all markdown files in a vault |
| read_file | Read file contents with frontmatter |
| create_file | Create a new file with optional frontmatter |
| update_file | Overwrite file contents (use section editing for partial changes) |
| delete_file | Delete a file |
| get_frontmatter | Read only frontmatter metadata |
| update_frontmatter | Merge updates into frontmatter |
| search_content | Full-text regex search across files |
| move_note | Relocate a file and update all wikilinks pointing to it |
Wikilink Operations (5)
| Tool | Description |
|------|-------------|
| resolve_wikilink | Resolve a [[wikilink]] to its file path |
| get_outlinks | Get all wikilinks from a note |
| get_backlinks | Get all notes that link to a given note |
| follow_link | Resolve a wikilink and read the target file |
| rebuild_link_index | Rebuild the wikilink resolution index |
Semantic Search (5)
| Tool | Description |
|------|-------------|
| semantic_search | Find similar content using embeddings (requires Ollama) |
| index_vault | Index all files in a vault for search |
| index_file | Index a single file |
| get_similar | Find notes similar to a given note |
| index_status | Check indexing status and stats |
Frontmatter Queries (1)
| Tool | Description |
|------|-------------|
| query_notes | Dataview-like query engine for frontmatter fields |
Filter operators: equals, not_equals, contains, not_contains, in, not_in, exists, not_exists, greater_than, less_than
Example:
{
"tool": "query_notes",
"args": {
"vault": "Main",
"from": "Projects",
"where": [
{ "field": "type", "op": "equals", "value": "PROJECT" },
{ "field": "status", "op": "not_equals", "value": "archived" }
],
"fields": ["type", "status", "updated"],
"sort_by": "-updated",
"limit": 10
}
}Vault Analytics (4)
| Tool | Description |
|------|-------------|
| get_vault_health | Composite health report (orphans + broken links + stale notes) |
| get_orphan_notes | Find notes with zero inbound wikilinks |
| get_broken_links | Find wikilinks pointing to non-existent notes |
| get_stale_notes | Find notes not modified within N days |
Section Editing (3)
| Tool | Description |
|------|-------------|
| append_to_section | Add content to the end of a section |
| prepend_to_section | Add content to the beginning of a section |
| update_section | Replace all content within a section (heading preserved) |
Cross-Vault (5)
| Tool | Description |
|------|-------------|
| search_all_vaults | Search across all configured vaults |
| semantic_search_all | Semantic search across all configured vaults |
| find_note_by_name | Find a note by name across vaults |
| get_cross_vault_links | Find wikilinks between vaults |
| get_ecosystem_stats | Statistics across the entire knowledge ecosystem (all vaults) |
Daily Notes (4)
| Tool | Description |
|------|-------------|
| daily_read | Read today's daily note |
| daily_append | Append content to daily note |
| daily_prepend | Prepend content to daily note |
| daily_path | Get the configured daily note path |
Tasks (2)
| Tool | Description |
|------|-------------|
| list_tasks | List tasks with status, file, line number. Filter by done/todo |
| update_task | Toggle, complete, or uncomplete a task by file and line |
Tags (2)
| Tool | Description |
|------|-------------|
| list_tags | All tags with occurrence counts |
| get_tag_info | Tag details including file list |
Properties (5)
| Tool | Description |
|------|-------------|
| list_properties | All frontmatter properties with counts |
| get_property_values | All unique values for a property across the vault |
| property_read | Read a single property value from a file |
| property_set | Set a single frontmatter property |
| property_remove | Remove a single frontmatter property |
Targeted Editing (3)
| Tool | Description |
|------|-------------|
| file_append | Append content to end of any file |
| file_prepend | Prepend content to start of any file (after frontmatter) |
| search_replace_in_file | Find-and-replace — only changes matched text |
Metadata & Navigation (5)
| Tool | Description |
|------|-------------|
| list_aliases | List aliases in the vault or for a specific file |
| get_file_info | File metadata — name, path, size, created/modified dates |
| get_folder_info | Folder metadata — file count, folder count, size |
| list_folders | List folders in the vault, optionally filtered by parent |
| read_random | Read a random note |
Structure (2)
| Tool | Description |
|------|-------------|
| get_outline | Heading tree for a file |
| word_count | Word and character count |
Vault Structure (3)
| Tool | Description |
|------|-------------|
| list_orphans | Files with no incoming links |
| list_deadends | Files with no outgoing links |
| unresolved_links | Broken/unresolved wikilinks across the vault |
File Management (2)
| Tool | Description |
|------|-------------|
| rename_file | Rename a file and update all wikilinks |
| move_file | Move a file and update all wikilinks |
Bookmarks (2)
| Tool | Description |
|------|-------------|
| add_bookmark | Bookmark a file, folder, search query, or URL |
| list_bookmarks | List all bookmarks |
Search (1)
| Tool | Description |
|------|-------------|
| search_with_context | Search vault with matching line context |
Plugins (read-only) (3)
| Tool | Description |
|------|-------------|
| list_plugins | List installed plugins |
| get_plugin_info | Get detailed info about a specific plugin |
| list_enabled_plugins | List only enabled plugins |
Snippets & Themes (read-only) (3)
| Tool | Description |
|------|-------------|
| list_snippets | List installed CSS snippets |
| list_themes | List installed themes |
| get_active_theme | Get the active theme |
Vault & Workspace (3)
| Tool | Description |
|------|-------------|
| get_vault_info | Vault metadata — name, path, file/folder count, size |
| get_workspace | Workspace tree showing open panes and layout |
| list_bases | List all .base files in the vault |
CLI-Only (28 tools — require Obsidian 1.12+)
These tools access Obsidian's runtime state, plugin systems, or internal databases. They require the Obsidian app to be running with CLI enabled. If Obsidian is not running, they return a clear error message.
Commands (2)
| Tool | Description |
|------|-------------|
| list_commands | Available Obsidian commands with optional filter |
| execute_command | Run any Obsidian command by ID |
Obsidian Search (1)
| Tool | Description |
|------|-------------|
| vault_search | Full-text search using Obsidian's search engine (supports file:, tag:, path: operators) |
Templates (3)
| Tool | Description |
|------|-------------|
| list_templates | List available templates |
| read_template | Read template content, optionally with variables resolved |
| create_from_template | Create a new file using an Obsidian template |
Version History (5)
| Tool | Description |
|------|-------------|
| list_versions | File version history (local and sync) |
| read_version | Read a historical version of a file |
| diff_versions | Diff between file versions |
| restore_version | Restore a file to a previous version |
| list_files_with_history | List files that have version history |
Plugin State Changes (2)
| Tool | Description |
|------|-------------|
| enable_plugin | Enable an installed plugin |
| disable_plugin | Disable a plugin |
Sync (3)
| Tool | Description |
|------|-------------|
| sync_status | Sync status (paused/active/connected) |
| sync_history | Sync version history for a file |
| sync_read_version | Read a specific sync version |
Snippet & Theme State Changes (3)
| Tool | Description |
|------|-------------|
| list_enabled_snippets | List enabled CSS snippets |
| enable_snippet | Enable a CSS snippet |
| disable_snippet | Disable a CSS snippet |
| Tool | Description |
|------|-------------|
| set_theme | Set the active theme |
Bases (3)
| Tool | Description |
|------|-------------|
| query_base | Query a base view (JSON, CSV, TSV, markdown, or paths) |
| create_base_item | Create a new item in a base/database |
| list_base_views | List views in a base file |
Other (6)
| Tool | Description |
|------|-------------|
| eval_obsidian | Execute JavaScript inside Obsidian's process |
| list_recents | Recently opened files |
| list_known_vaults | List all vaults known to Obsidian with paths |
| get_hotkey | Get the hotkey for a specific command |
| list_hotkeys | List all hotkey bindings |
Semantic Search (Optional)
Semantic search requires Ollama running locally. All other tools work without Ollama.
# Install (macOS)
brew install ollama
# Pull embedding model (~274MB)
ollama pull nomic-embed-text
# Verify
curl http://localhost:11434/api/tagsFirst-Time Indexing
HTTP_MODE=true npx @wickedevolutions/mcp-obsidian &
curl http://localhost:3456/call \
-H "Content-Type: application/json" \
-d '{"tool": "index_vault", "args": {"vault": "MyVault"}}'HTTP Server Mode
HTTP_MODE=true HTTP_PORT=3456 npx @wickedevolutions/mcp-obsidian| Endpoint | Method | Description |
|----------|--------|-------------|
| /health | GET | Health check |
| /tools | GET | List available tools |
| /call | POST | Call any tool |
| /search | POST | Semantic search shorthand |
Architecture
src/
├── index.ts # Entry point, MCP server setup
├── http-server.ts # HTTP server mode
├── config.ts # Config loading + resolveVault() helper
├── types/index.ts # TypeScript type definitions
├── cli/
│ └── bridge.ts # Obsidian CLI bridge (1.12+)
├── parsers/
│ ├── markdown.ts # Markdown/frontmatter parsing, section extraction
│ └── wikilink.ts # Wikilink parsing + resolution
├── embeddings/
│ ├── ollama.ts # Ollama API client
│ ├── storage.ts # SQLite vector storage
│ └── watcher.ts # File watcher for auto-indexing
└── tools/
├── index.ts # Tool registration hub (11 modules)
├── files.ts # File ops (9 tools)
├── wikilinks.ts # Wikilink ops (5 tools)
├── semantic.ts # Semantic search (5 tools)
├── crossvault.ts # Cross-vault ops (5 tools)
├── sections.ts # Section editing (3 tools)
├── query.ts # Frontmatter queries (1 tool)
├── analytics.ts # Vault health (4 tools)
├── fs-promoted.ts # Filesystem-promoted tools (40 tools)
├── cli-tools.ts # CLI-only tools (28 tools)
├── get-started.ts # Onboarding tool (1 tool)
└── discover-tools.ts # Tool discovery (1 tool)Safety Notes
Three tools can cause data loss if used incorrectly. Understand their behavior before use.
search_replace_in_file — fixed in v1.0.1 (#4)
Fixed. Previously, when the search text was not found, the tool wrote the literal string "NO_CHANGE" as file content, destroying the original. Now it safely returns an error without modifying the file.
update_section on H1 headings — by design (#5)
Caution: When targeting an H1 heading (# Title), the section scope extends to the end of the file — because no heading of equal or higher level exists to close the section. This replaces everything below the title. Use update_section only on H2 and lower headings. For H1-level content, use update_file with full content instead.
update_file — by design (#6)
Caution: This tool replaces the entire file body (frontmatter is preserved if the frontmatter parameter is omitted). For partial updates, use append_to_section, prepend_to_section, update_section, or the CLI tools file_append and file_prepend.
Known Limitations
- CLI-only tools require Obsidian running — a subset of tools need Obsidian 1.12+ with CLI enabled. If Obsidian is not running, these tools return a clear error while all other tools continue working.
- Unicode filenames — Files with curly apostrophes (U+2019) and some Unicode characters may fail to resolve.
- Vault path changes — If a vault folder is renamed on disk, the
OBSIDIAN_VAULTSenvironment variable must be updated manually.
License
MIT — see LICENSE for details.
