Install
$ agentstack add mcp-lstpsche-obsidian-mcp ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
obsidian-mcp
[](https://github.com/lstpsche/obsidian-mcp/actions/workflows/ci.yml) [](https://crates.io/crates/obsidian-mcp) [](LICENSE)
A high-performance MCP server that gives AI agents full read/write access to Obsidian vaults. Written in Rust. Ships as a single binary.
No Obsidian plugins. No REST API. No Obsidian running. Just your vault on disk.
Why?
Existing solutions for AI + Obsidian require the Obsidian app to be running with a community plugin (obsidian-local-rest-api) and an MCP wrapper (mcp-obsidian) on top. That's fragile, slow, and limited to what the REST API exposes.
obsidian-mcp talks directly to the filesystem. It understands the Obsidian format natively — wikilinks, frontmatter, tags, block references, periodic notes, the full graph. It builds fast in-memory indices on startup and keeps them synced via a filesystem watcher. The result is a single dependency-free binary that works whether Obsidian is open or not.
Quick Start
# Install
cargo install obsidian-mcp
# Run (stdio — for MCP clients that launch the process)
obsidian-mcp /path/to/your/vault
# Run (HTTP — shared server for multiple agents)
obsidian-mcp --http /path/to/your/vault
Add to your MCP client config (Cursor, Claude Desktop, etc.) and you're done — 18 tools are available immediately.
What It Can Do
| Category | Capabilities | |----------|-------------| | Navigate | List files, tree view, vault stats | | Read & write | Create, read, overwrite, append, prepend, move, delete notes | | Patch | Edit individual heading sections, block references, or frontmatter fields without touching the rest of the note | | Search | BM25 full-text (Tantivy) with stemming, fuzzy matching, and per-field filtering. Semantic search via local embeddings. Regex. Tag and frontmatter queries. | | Graph | Backlinks, outgoing links, broken link detection, orphan discovery | | Frontmatter | Get/set/remove fields, query notes by metadata | | Periodic notes | Daily, weekly, monthly, quarterly, yearly — with Obsidian-compatible date formats and template expansion |
All indices (metadata, BM25, embeddings) update in real time via a filesystem watcher.
Installation
From crates.io
cargo install obsidian-mcp
For semantic search local compatibility mode (OBSIDIAN_SEMANTIC_MODE=local), build with embeddings:
cargo install obsidian-mcp --features embeddings
The embeddings feature adds ~60 MB to the binary (ONNX Runtime). In daemon mode, model/runtime cache is shared under semantic home; local mode keeps in-process embedding support in the MCP binary.
On Windows, local embeddings builds require a recent MSVC Build Tools toolset for ONNX Runtime. MSVC 14.44+ is known to work; older VS 2019-era 14.2x toolsets may fail to link with __std_find_trivial_8. Use --features embeddings-api instead if you want semantic search through an external /v1/embeddings server without bundling ONNX Runtime.
For API embedding backend (OpenAI, Ollama, vLLM, LM Studio, or any /v1/embeddings-compatible endpoint):
cargo install obsidian-mcp --features embeddings-api
This adds no model weight to the binary — embeddings are computed by an external server. Both features can be compiled simultaneously; OBSIDIAN_EMBEDDING_PROVIDER selects which runs.
API backend examples
# OpenAI
OBSIDIAN_EMBEDDINGS=true
OBSIDIAN_EMBEDDING_PROVIDER=api
OBSIDIAN_EMBEDDING_API_KEY=sk-...
OBSIDIAN_EMBEDDING_API_MODEL=text-embedding-3-small
# Ollama (local, no auth)
OBSIDIAN_EMBEDDINGS=true
OBSIDIAN_EMBEDDING_PROVIDER=api
OBSIDIAN_EMBEDDING_API_BASE=http://localhost:11434/v1
OBSIDIAN_EMBEDDING_API_MODEL=nomic-embed-text
OBSIDIAN_EMBEDDING_API_KEY=unused
# vLLM / LM Studio
OBSIDIAN_EMBEDDINGS=true
OBSIDIAN_EMBEDDING_PROVIDER=api
OBSIDIAN_EMBEDDING_API_BASE=http://localhost:8000/v1
OBSIDIAN_EMBEDDING_API_MODEL=BAAI/bge-small-en-v1.5
OBSIDIAN_EMBEDDING_API_KEY=unused
# OpenRouter (25+ embedding models from multiple providers)
OBSIDIAN_EMBEDDINGS=true
OBSIDIAN_EMBEDDING_PROVIDER=api
OBSIDIAN_EMBEDDING_API_BASE=https://openrouter.ai/api/v1
OBSIDIAN_EMBEDDING_API_MODEL=openai/text-embedding-3-small
OBSIDIAN_EMBEDDING_API_KEY=sk-or-v1-...
Pre-built binaries
Grab the latest from GitHub Releases:
| Platform | Archive | |----------|---------| | Linux x8664 | obsidian-mcp--x86_64-unknown-linux-gnu.tar.gz | | Linux ARM64 | obsidian-mcp--aarch64-unknown-linux-gnu.tar.gz | | macOS Intel | obsidian-mcp--x86_64-apple-darwin.tar.gz | | macOS Apple Silicon | obsidian-mcp--aarch64-apple-darwin.tar.gz | | Windows x8664 | obsidian-mcp--x86_64-pc-windows-msvc.zip |
Semantic daemon release assets are also published per target:
obsidian-semanticd--.tar.gz(Unix)obsidian-semanticd--.zip(Windows)
Install from source (edge)
If you have the repo cloned, you can install the latest main build locally:
./bin/install-edge
This pulls the latest main and runs cargo install --path . --features embeddings.
Semantic Runtime Compatibility
Current semantic daemon API version: 1 (DAEMON_API_VERSION in src/daemon/protocol.rs).
| Component | Compatibility contract | Enforcement | |----------|-------------------------|-------------| | obsidian-mcp | Daemon API version must match exactly | MCP daemon health handshake validates min_api_version/max_api_version against current API version and fails fast on mismatch | | obsidian-semantic-search-plugin | Daemon API version must match exactly | Plugin bootstrap performs daemon health handshake and surfaces explicit incompatibility notices |
Release asset compatibility expectations:
- Daemon auto-install clients expect release assets named
obsidian-semanticd--.{tar.gz|zip}pluschecksums.sha256. - Plugin releases should publish
main.js,manifest.json, and optionalstyles.cssas GitHub release assets.
Upgrade guidance:
- Prefer upgrading
obsidian-mcp,obsidian-semanticd, andobsidian-semantic-search-plugintogether. - If versions are skewed, startup/handshake fails with explicit API incompatibility errors rather than silent fallback.
Transport Modes
obsidian-mcp supports two transports. Both are always compiled in — choose the one that fits your workflow.
stdio (default)
The standard MCP transport. The AI client spawns the process and communicates over stdin/stdout.
Use when: your MCP client manages the server process (Cursor, Claude Desktop, most MCP clients).
obsidian-mcp /path/to/vault
Each client connection spawns its own process. Simple, zero-config, works everywhere.
Streamable HTTP
A persistent HTTP server that multiple clients can connect to simultaneously.
Use when: you run multiple headless agents (cursor agent -p, parallel Claude sessions, etc.) against the same vault and want to share a single server process instead of spawning one per agent.
# Foreground (for development / process managers like launchd, systemd)
obsidian-mcp --http /path/to/vault
# Background (ad-hoc daemonize — spawns child, parent exits)
obsidian-mcp serve /path/to/vault
The serve command daemonizes the server and redirects logs to a platform-specific file:
- macOS:
~/Library/Logs/obsidian-mcp.log - Linux:
$XDG_STATE_HOME/obsidian-mcp/obsidian-mcp.log - Windows:
%LOCALAPPDATA%/obsidian-mcp/obsidian-mcp.log
Default: http://127.0.0.1:37842. MCP tools are served at /mcp, health check at /health.
Benefits over stdio for multi-agent setups:
- Shared index — one in-memory BM25/embedding index instead of N copies
- Lower resource usage — single filesystem watcher, single process
- Process independence — server stays up when agents come and go
- Standard observability — HTTP health checks, logging, standard networking
Configure the address:
obsidian-mcp --http --port 9000 --host 0.0.0.0 /path/to/vault
# or via env vars
OBSIDIAN_TRANSPORT=http OBSIDIAN_HTTP_PORT=9000 obsidian-mcp /path/to/vault
Server Management
obsidian-mcp serve /path/to/vault # Start HTTP server in background
obsidian-mcp stop # Stop running server (default port)
obsidian-mcp stop --port 9000 # Stop server on specific port
obsidian-mcp restart /path/to/vault # Stop + start (picks up new binary after upgrade)
serve and restart wait for the server to pass a /health check before reporting success (up to 15s). If the server fails during startup, the exit code and log path are reported.
Client Setup
Cursor (stdio)
~/.cursor/mcp.json:
{
"mcpServers": {
"obsidian": {
"command": "obsidian-mcp",
"args": ["/path/to/your/vault"]
}
}
}
Cursor (HTTP — shared server)
Start the server once:
obsidian-mcp serve /path/to/your/vault
Then point Cursor at it:
{
"mcpServers": {
"obsidian": {
"url": "http://127.0.0.1:37842/mcp"
}
}
}
All Cursor agents (IDE, CLI, headless) share the same server.
Claude Desktop
{
"mcpServers": {
"obsidian": {
"command": "obsidian-mcp",
"env": {
"OBSIDIAN_VAULT_PATH": "/path/to/your/vault",
"OBSIDIAN_EMBEDDINGS": "true"
}
}
}
}
Config file location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Any MCP client
obsidian-mcp supports both stdio and Streamable HTTP MCP transports. Any MCP-compatible client can connect via either method. Pass the vault path as the first argument or via OBSIDIAN_VAULT_PATH.
Running as a Service
For always-on HTTP mode, use your OS process manager with --http (not serve). This lets the process manager handle restarts, logging, and lifecycle — serve daemonizes itself, which conflicts with process managers that expect to own the child process.
macOS (launchd)
Create ~/Library/LaunchAgents/com.obsidian-mcp.plist:
Label
com.obsidian-mcp
ProgramArguments
/Users/YOU/.cargo/bin/obsidian-mcp
--http
EnvironmentVariables
OBSIDIAN_VAULT_PATH
/path/to/your/vault
RunAtLoad
KeepAlive
StandardOutPath
/Users/YOU/Library/Logs/obsidian-mcp/launchd.out.log
StandardErrorPath
/Users/YOU/Library/Logs/obsidian-mcp/launchd.err.log
> Important: launchd does not source your shell profile (~/.zshrc, ~/.bashrc). All environment variables must be defined in the plist's EnvironmentVariables section.
# Load
launchctl load ~/Library/LaunchAgents/com.obsidian-mcp.plist
# Unload (stop)
launchctl unload ~/Library/LaunchAgents/com.obsidian-mcp.plist
# Restart (after upgrade)
launchctl unload ~/Library/LaunchAgents/com.obsidian-mcp.plist && \
launchctl load ~/Library/LaunchAgents/com.obsidian-mcp.plist
Linux (systemd)
Create ~/.config/systemd/user/obsidian-mcp.service:
[Unit]
Description=obsidian-mcp MCP server
After=network.target
[Service]
ExecStart=%h/.cargo/bin/obsidian-mcp --http
Environment=OBSIDIAN_VAULT_PATH=/path/to/your/vault
# Add embedding env vars if needed:
# Environment=OBSIDIAN_EMBEDDINGS=true
# Environment=OBSIDIAN_EMBEDDING_PROVIDER=api
# Environment=OBSIDIAN_EMBEDDING_API_KEY=sk-...
# Environment=OBSIDIAN_EMBEDDING_API_BASE=https://api.openai.com/v1
# Environment=OBSIDIAN_EMBEDDING_API_MODEL=text-embedding-3-small
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now obsidian-mcp
# Check status
systemctl --user status obsidian-mcp
# Restart (after upgrade)
systemctl --user restart obsidian-mcp
# View logs
journalctl --user -u obsidian-mcp -f
Upgrading
# Install new version
cargo install obsidian-mcp --force
# With features:
cargo install obsidian-mcp --features embeddings,embeddings-api --force
# Restart the running server to pick up the new binary
obsidian-mcp restart /path/to/vault
# Or if using a process manager:
launchctl unload ~/Library/LaunchAgents/com.obsidian-mcp.plist && \
launchctl load ~/Library/LaunchAgents/com.obsidian-mcp.plist
# systemd: systemctl --user restart obsidian-mcp
> cargo install --force replaces the binary on disk but does not restart any running server. You must restart manually — otherwise the old version continues serving.
Search
Three tiers, each suited to different needs.
BM25 Full-Text — search_text
On by default. Powered by Tantivy, rebuilt in-memory on startup ( All 18 tools (click to expand)
Navigation
| Tool | Parameters | Description | |------|-----------|-------------| | vault_list | path?, recursive?, glob?, format?, max_depth? | List files (format: "list") or tree view (format: "tree") | | vault_info | — | Aggregate vault statistics |
Note CRUD
| Tool | Parameters | Description | |------|-----------|-------------| | note_read | path | Read full note content | | note_create | path, content?, frontmatter? | Create a new note | | note_write | path, content | Overwrite note content | | note_insert | path, content, position? | Insert at end ("end", default) or beginning ("beginning") | | note_patch | path, operation, target_type, target, content | Patch a heading section, block ref, or frontmatter field | | note_delete | path, confirm | Delete a note (requires confirm: true) | | note_move | from, to | Move or rename a note |
For note_patch heading targets, bare heading text such as "Log" is canonical. ATX marker-prefixed targets such as "## Log" are also accepted, so headings copied from note_inspect with view: "targets" can be used directly.
Search
| Tool | Parameters | Description | |------|-----------|-------------| | search_text | query, fuzzy?, fields?, context_length?, max_results? | BM25 full-text search with stemming | | search_semantic | query, top_k?, include_content?, lexical_prefetch?, alpha? | Semantic similarity search | | search_regex | pattern, context_length?, max_results? | Regex pattern search | | search_metadata | type, tag?, include_nested?, field?, value?, operator? | Find by tag (type: "tag") or frontmatter (type: "frontmatter") |
Introspection & Frontmatter
| Tool | Parameters | Description | |------|-----------|-------------| | note_inspect | path, view? | Metadata ("metadata", default) or patchable targets ("targets") | | frontmatter | action, path, key?, value? | Get ("get"), set ("set"), or remove ("remove") frontmatter fields |
Graph & Links
| Tool | Parameters | Description | |------|-----------|-------------| | wikilinks | query, path? | Backlinks, outgoing, broken, or orphans (query: "backlinks"/"outgoing"/"broken"/"orphans") |
Periodic Notes
| Tool | Parameters | Description | |------|-----------|-------------| | periodic | action, period, date?, content?, limit? | Get, create, or list periodic notes (action: "get"/"create"/"list") |
Utility
| Tool | Parameters | Description | |------|-----------|-------------| | open_in_obsidian | path, new_leaf? | Open note in Obsidian via obsidian:// URI |
Tool Filtering
Control which tools are exposed via the OBSIDIAN_TOOLS environment variable or per-session X-Obsidian-Tools HTTP header.
| Value | Effect | |-------|--------| | full (or unset) | All 18 tools | | core | 14 tools — drops search_semantic, search_regex, periodic, open_in_obsidian | | read | 10 tools — read-only (no c
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: lstpsche
- Source: lstpsche/obsidian-mcp
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.