obsidian-mcp-complete
# obsidian-mcp-complete
Local-first MCP server for Obsidian vaults. Works without Obsidian running, no plugins required.
**66 tools** across: read/write/search notes, BM25 smart search, graph traversal, JSON Canvas, tasks, periodic notes, frontmatter, batch ops, and an optional bridge to the Obsidian Local REST API.
<p align="center">
<img src="docs/architecture.svg" alt="Architecture diagram" width="780"/>
</p>
<p align="center">
<img src="docs/tools-overview.svg" alt="Tool categories overview" width="760"/>
</p>
---
## Install
### npx (zero install, always latest)
```bash
npx obsidian-mcp-complete "/path/to/vault"
```
### npm global
```bash
npm install -g obsidian-mcp-complete
obsidian-mcp "/path/to/vault"
```
### Homebrew
```bash
brew tap jagoff/obsidian-mcp
brew install obsidian-mcp
obsidian-mcp "/path/to/vault"
```
### Smithery (MCP store)
Search for `obsidian-mcp-complete` at [smithery.ai](https://smithery.ai) and configure from the UI.
---
## Configure in Claude Code / Claude Desktop
Add to your `~/.claude/claude_desktop_config.json` (Desktop) or `~/.mcp.json` (Claude Code):
```json
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["-y", "obsidian-mcp-complete", "/path/to/your/vault"],
"env": {
"OBSIDIAN_MAX_SEARCH_RESULTS": "80"
}
}
}
}
```
Multi-vault with named vaults:
```json
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": [
"-y", "obsidian-mcp-complete",
"notes=/Users/you/Documents/Notes",
"work=/Users/you/Documents/work-vault"
],
"env": {
"OBSIDIAN_DEFAULT_VAULT": "notes",
"OBSIDIAN_MAX_SEARCH_RESULTS": "80"
}
}
}
}
```
---
## Environment variables
| Variable | Default | Description |
|---|---|---|
| `OBSIDIAN_VAULT_PATH` | — | Single vault path |
| `OBSIDIAN_VAULTS` | — | `name=path,name2=path2` pairs |
| `OBSIDIAN_DEFAULT_VAULT` | first vault | Vault used when tool call omits `vault` |
| `OBSIDIAN_READ_ONLY` | `0` | Set to `1` to disable all writes |
| `OBSIDIAN_ENABLE_DELETE` | `0` | Set to `1` to allow delete operations |
| `OBSIDIAN_MAX_SEARCH_RESULTS` | `50` | Max results from search tools |
| `OBSIDIAN_MCP_PRETTY` | `0` | Pretty-print JSON responses |
| `OBSIDIAN_RAG_COMMAND` | `rag` | Path/command for obsidian-rag CLI |
| `OBSIDIAN_API_KEY` | — | Obsidian Local REST API key |
| `OBSIDIAN_REST_URL` | `https://127.0.0.1:27124` | Obsidian Local REST API URL |
| `OBSIDIAN_REST_INSECURE_TLS` | `0` | Skip TLS verification for local REST |
| `OBSIDIAN_ENABLE_COMMANDS` | `0` | Enable command-palette tools |
| `OBSIDIAN_ENABLE_UI_OPEN` | `0` | Allow `open obsidian://` system call |
| `OBSIDIAN_DAILY_FOLDER` | `00-Inbox` | Folder for daily notes |
| `OBSIDIAN_DAILY_PATTERN` | `YYYY-MM-DD.md` | Filename pattern for daily notes |
---
## Tool catalog
**Discovery, search, intelligence**
`obsidian_status` · `obsidian_list_vaults` · `obsidian_list_files` · `obsidian_search` · `obsidian_smart_search` · `obsidian_search_paths` · `obsidian_recent_notes` · `obsidian_vault_stats` · `obsidian_rag_query` · `obsidian_query_notes` · `obsidian_list_tags` · `obsidian_graph_stats` · `obsidian_vault_graph` · `obsidian_vault_themes` · `obsidian_vault_suggest` · `obsidian_diff_notes`
**Reading**
`obsidian_read_note` · `obsidian_read_many` · `obsidian_get_frontmatter` · `obsidian_links` · `obsidian_get_backlinks` · `obsidian_canvas_read` · `obsidian_open_uri`
**Writing**
`obsidian_create_note` · `obsidian_upsert_note` · `obsidian_append_to_note` · `obsidian_patch_note` · `obsidian_replace_in_note` · `obsidian_regex_replace` · `obsidian_update_frontmatter` · `obsidian_manage_tags` · `obsidian_move_note` · `obsidian_update_links` · `obsidian_batch_rename` · `obsidian_delete_note` · `obsidian_delete_folder` · `obsidian_prune_empty_dirs` · `obsidian_batch_create_notes` · `obsidian_batch` · `obsidian_update_task` · `obsidian_daily_note` · `obsidian_periodic_note` · `obsidian_apply_template` · `obsidian_import_attachment` · `obsidian_write_canvas` · `obsidian_canvas_create` · `obsidian_canvas_patch` · `obsidian_canvas_relayout`
**Graph**
`obsidian_traverse_graph` · `obsidian_shortest_path` · `obsidian_find_orphans` · `obsidian_find_broken_links`
**Tasks and assets**
`obsidian_list_tasks` · `obsidian_list_attachments`
**Obsidian Local REST API** _(requires plugin + `OBSIDIAN_API_KEY`)_
`obsidian_rest_status` · `obsidian_rest_request` · `obsidian_get_active` · `obsidian_post_active` · `obsidian_put_active` · `obsidian_patch_active` · `obsidian_delete_active`* · `obsidian_list_commands`* · `obsidian_execute_command`* · `obsidian_search_dataview` · `obsidian_search_jsonlogic` · `obsidian_open_in_ui`†
_* requires `OBSIDIAN_ENABLE_COMMANDS=1` · † requires `OBSIDIAN_ENABLE_UI_OPEN=1`_
---
## Security
- Paths are validated and scoped to configured vault roots — traversal and absolute paths are rejected
- `.obsidian/` and `.git/` directories are never exposed
- Writes are atomic (write to temp + rename)
- Delete is opt-in (`OBSIDIAN_ENABLE_DELETE=1`) and requires explicit `confirmation` field
- Read-only mode disables all mutations (`OBSIDIAN_READ_ONLY=1`)
---
## Development
```bash
git clone https://github.com/jagoff/obsidian-mcp
cd obsidian-mcp
npm install
npm run build
npm test
```
Smoke test:
```bash
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
| node dist/stdio.js "/path/to/vault"
```
### Release
Tag a version to trigger the release workflow (CI → npm publish → GitHub Release):
```bash
git tag v0.2.0
git push origin v0.2.0
```
Requires `NPM_TOKEN` secret set in the GitHub repo settings.
---
## Inspired by
- `@bitbonsai/mcpvault` — direct vault access without plugins
- `cyanheads/obsidian-mcp-server` — surgical frontmatter editing
- `yanxue06/obsidian-mcp` and `aaronsb/obsidian-mcp-plugin` — graph, backlinks, daily notes, batch ops
TDQS
Scored across 66 tools
Most tools have clearly distinct purposes, but the multiple search tools (obsidian_search, obsidian_smart_search, obsidian_rag_query, etc.) and several note manipulation tools could cause confusion for an agent without careful reading of descriptions.
All tools follow the consistent pattern 'obsidian_verb_noun' using snake_case, which is predictable and easy to navigate.
66 tools is a large number, but the scope of Obsidian vault management is broad, covering notes, canvas, search, graph, batch operations, and more. However, some tools may be redundant, making the count feel somewhat heavy.
The tool set comprehensively covers CRUD for notes, canvases, tags, links, attachments, graph traversal, batch operations, and vault analysis. Minor gaps exist, such as no explicit folder creation tool.