bitbonsai/mcp-obsidian
If you are the rightful owner of mcp-obsidian and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
MCP-Obsidian is a lightweight server designed to facilitate safe access to Obsidian vaults using the Model Context Protocol (MCP).
MCP-Obsidian
A universal AI bridge for Obsidian vaults using the Model Context Protocol (MCP) standard. Connect any MCP-compatible AI assistant to your knowledge base - works with Claude, ChatGPT, and future AI tools. This server provides safe read/write access to your notes while preventing YAML frontmatter corruption.
Universal Compatibility
Works with any MCP-compatible AI assistant including Claude Desktop, Claude Code, ChatGPT Desktop (Enterprise+), OpenCode, Gemini CLI, OpenAI Codex, IntelliJ IDEA 2025.1+, Cursor IDE, Windsurf IDE, and future AI platforms that adopt the MCP standard.
https://github.com/user-attachments/assets/657ac4c6-1cd2-4cc3-829f-fd095a32f71c
Quick Start (5 minutes)
-
Install Node.js runtime:
# Download from https://nodejs.org (v18.0.0 or later) # or use a package manager like nvm, brew, apt, etc. -
Test the server:
If using the published package:
npx @modelcontextprotocol/inspector npx @mauricio.wolff/mcp-obsidian@latest /path/to/your/vault -
Configure your AI client:
Claude Desktop - Copy this to
claude_desktop_config.json:{ "mcpServers": { "obsidian": { "command": "npx", "args": ["@mauricio.wolff/mcp-obsidian@latest", "/path/to/your/vault"] } } }Claude Code - Copy this to
~/.claude.json:{ "mcpServers": { "obsidian": { "command": "npx", "args": ["@mauricio.wolff/mcp-obsidian@latest", "/path/to/your/vault"], "env": {} } } }OpenCode - Copy this to
~/.config/opencode/opencode.json{ "mcp": { "obsidian": { "type": "local", "command": [ "npx", "@mauricio.wolff/mcp-obsidian@latest", "/path/to/your/vault/" ], "enabled": true } } }Replace
/path/to/your/vaultwith your actual Obsidian vault path.For other platforms, see detailed configuration guides below.
-
Test with your AI:
- "List files in my Obsidian vault"
- "Read my note called 'project-ideas.md'"
- "Create a new note with today's date"
Success indicators: Your AI should be able to list files and read notes from your vault.
Why MCP-Obsidian?
Universal AI Compatibility
Built on the open Model Context Protocol standard, MCP-Obsidian is not locked to any single AI provider. As more AI assistants adopt MCP, your investment in this tool grows more valuable. Today it works with Claude and ChatGPT - tomorrow it will work with whatever AI tools emerge.
Future-Proof Your Knowledge Base
Instead of waiting for each AI company to build Obsidian integrations, MCP-Obsidian provides a universal adapter that works with any MCP-compatible assistant. One tool, endless possibilities.
Open Standard, No Lock-in
MCP is an open protocol. You're not tied to any specific vendor or platform. Your notes remain yours, accessible through any compatible AI assistant.
Features
- ✅ Safe frontmatter parsing and validation using gray-matter
- ✅ Path filtering to exclude
.obsidiandirectory and other system files - ✅ Complete MCP toolkit: 14 methods covering all vault operations
- File operations:
read_note,write_note,patch_note,delete_note,move_note,move_file - Directory operations:
list_directory - Batch operations:
read_multiple_notes - Search:
search_noteswith multi-word matching and BM25 relevance reranking - Metadata:
get_frontmatter,update_frontmatter,get_notes_info,get_vault_stats - Tag management:
manage_tags(add, remove, list)
- File operations:
- ✅ Write modes:
overwrite,append,prependfor flexible content editing - ✅ Tag management: add, remove, and list tags in notes
- ✅ Safe deletion with confirmation requirement to prevent accidents
- ✅ Automatic path trimming to handle whitespace in inputs
- ✅ TypeScript support with Node.js runtime (using tsx for execution)
- ✅ Comprehensive error handling and validation
- ✅ Token-optimized responses: 40-60% smaller responses with minified field names and compact JSON (v0.6.3+)
- ✅ Optional pretty-printing: Set
prettyPrint: truefor human-readable debugging - ✅ Performance optimized: No unnecessary token consumption, efficient for large vaults
- ✅ Zero dependencies: No Obsidian plugins required, works with any vault structure
Prerequisites
- Node.js runtime (v18.0.0 or later)
- An Obsidian vault (local directory with
.mdfiles) - MCP-compatible AI client (Claude Desktop, ChatGPT Desktop, Claude Code, etc.)
Installation
For End Users (Recommended)
No installation needed! Use npx to run directly:
npx @mauricio.wolff/mcp-obsidian@latest /path/to/your/obsidian/vault
For Developers
- Clone this repository
- Use the correct Node.js version:
nvm use # Uses Node 24 from .nvmrc
- Install dependencies with npm:
npm install # Corepack automatically uses npm 10.9.0
- Test locally with MCP inspector:
npx @modelcontextprotocol/inspector npm start /path/to/your/vault
Pro tip: Use MCP Inspector to test all server functionality before configuring with AI clients:
# Install globally for easier access
npm install -g @modelcontextprotocol/inspector
# Test with any vault
mcp-inspector npx @mauricio.wolff/mcp-obsidian@latest /path/to/your/vault
Usage
Running the Server
End users:
npx @mauricio.wolff/mcp-obsidian@latest /path/to/your/obsidian/vault
Developers:
npm start /path/to/your/obsidian/vault
AI Client Configuration
Claude Desktop
Add to your Claude Desktop configuration file:
Single Vault:
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": [
"@mauricio.wolff/mcp-obsidian@latest",
"/Users/yourname/Documents/MyVault"
]
}
}
}
Multiple Vaults:
{
"mcpServers": {
"obsidian-personal": {
"command": "npx",
"args": [
"@mauricio.wolff/mcp-obsidian@latest",
"/Users/yourname/Documents/PersonalVault"
]
},
"obsidian-work": {
"command": "npx",
"args": [
"@mauricio.wolff/mcp-obsidian@latest",
"/Users/yourname/Documents/WorkVault"
]
}
}
}
Configuration File Locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
C:\Users\{username}\AppData\Roaming\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
You can also access this through Claude Desktop → Settings → Developer → Edit Config
ChatGPT Desktop
Requirements: ChatGPT Enterprise, Education, or Team subscription (not available for individual Plus users)
ChatGPT uses MCP through Deep Research and developer mode. Configuration is done through the ChatGPT interface:
- Access ChatGPT developer mode (beta feature)
- Configure MCP servers through the built-in MCP client
- Create custom connectors for your organization
Note: ChatGPT Desktop's MCP integration is currently limited to enterprise subscriptions and uses a different setup process than file-based configuration.
Claude Code
Claude Code uses .claude.json configuration file:
User-scoped (recommended):
Edit ~/.claude.json:
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["@mauricio.wolff/mcp-obsidian@latest", "/path/to/your/vault"],
"env": {}
}
}
}
Project-scoped:
Edit .claude.json in your project or add to the projects section:
{
"projects": {
"/path/to/your/project": {
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["@mauricio.wolff/mcp-obsidian@latest", "/path/to/your/vault"]
}
}
}
}
}
Using Claude Code CLI:
claude mcp add obsidian --scope user npx @mauricio.wolff/mcp-obsidian /path/to/your/vault
Goose Desktop
On Goose Desktop settings, click Add custom extension, and on the command field add:
npx @mauricio.wolff/mcp-obsidian@latest /path/to/your/vault
Other MCP-Compatible Clients (2025)
Confirmed MCP Support:
- IntelliJ IDEA 2025.1+ - Native MCP client support
- Cursor IDE - Built-in MCP compatibility
- Windsurf IDE - Full MCP integration
- Zed, Replit, Codeium, Sourcegraph - In development
- Microsoft Copilot Studio - Native MCP support with one-click server connections
Most modern MCP clients use similar JSON configuration patterns. Refer to your specific client's documentation for exact setup instructions.
Examples
Ask your AI assistant about your notes:
- "What files are in my Obsidian vault?"
- "Read my note called 'project-ideas.md'"
- "Show me all notes with 'AI' in the title"
Have your AI assistant help with note management:
- "Create a new note called 'meeting-notes.md' with today's date in the frontmatter"
- "Append today's journal entry to my daily note"
- "Prepend an urgent task to my todo list"
- "Add the tags 'project' and 'urgent' to my task note"
- "List all tags in my research note"
- "Remove the 'draft' tag from my completed article"
- "List all markdown files in my 'Projects' folder"
- "Delete the old draft note 'draft-ideas.md' (with confirmation)"
Advanced Use Cases:
- Knowledge Synthesis: "Summarize all my research notes tagged with 'machine-learning' from the last month"
- Project Management: "Update the status in all project notes to 'completed' and add today's date"
- Content Analysis: "Find all notes that mention 'API design' and create a comprehensive guide"
- Smart Tagging: "Review my untagged notes and suggest appropriate tags based on content"
Troubleshooting
Common Issues
"command not found: npx"
- Solution: Install Node.js runtime from nodejs.org
- Alternative: Use global install:
npm install -g @mauricio.wolff/mcp-obsidian
"Usage: node server.ts /path/to/vault"
- Cause: No vault path provided
- Solution: Specify the full path to your Obsidian vault directory
"Permission denied" errors
- Cause: Insufficient file system permissions
- Solution: Ensure the vault directory is readable/writable by your user
"Path traversal not allowed"
- Cause: Trying to access files outside the vault
- Solution: All file paths must be relative to the vault root
AI client not recognizing the server
- Check the configuration file path is correct for your OS
- Ensure JSON syntax is valid (use a JSON validator)
- Restart your AI client after configuration changes
- Check your AI client's logs for error messages
- Verify your AI client supports MCP (Model Context Protocol)
".obsidian files still showing up"
- Expected: The path filter automatically excludes
.obsidian/**patterns - If still seeing them: The filter is working as designed for security
Debug Mode
Run with error logging:
npx @mauricio.wolff/mcp-obsidian /path/to/vault 2>debug.log
Getting Help
- Open an issue on GitHub
- Include your OS, Node.js version, and error messages
- Provide the vault directory structure (without sensitive content)
Testing
Run the test suite:
npm test
API Methods
read_note
Read a note from the vault with parsed frontmatter.
Request:
{
"name": "read_note",
"arguments": {
"path": "project-ideas.md",
"prettyPrint": false
}
}
Response (optimized for tokens):
{
"fm": {
"title": "Project Ideas",
"tags": ["projects", "brainstorming"],
"created": "2023-01-15T10:30:00.000Z"
},
"content": "# Project Ideas\n\n## AI Tools\n- MCP server for Obsidian\n- Voice note transcription\n\n## Web Apps\n- Task management system"
}
Response (with prettyPrint: true):
{
"fm": {
"title": "Project Ideas",
"tags": ["projects", "brainstorming"],
"created": "2023-01-15T10:30:00.000Z"
},
"content": "# Project Ideas\n\n## AI Tools\n- MCP server for Obsidian\n- Voice note transcription\n\n## Web Apps\n- Task management system"
}
write_note
Write a note to the vault with optional frontmatter and write mode.
Write Modes:
overwrite(default): Replace entire file contentappend: Add content to the end of existing fileprepend: Add content to the beginning of existing file
Request (Overwrite):
{
"name": "write_note",
"arguments": {
"path": "meeting-notes.md",
"content": "# Team Meeting\n\n## Agenda\n- Project updates\n- Next milestones",
"frontmatter": {
"title": "Team Meeting Notes",
"date": "2023-12-01",
"tags": ["meetings", "team"]
},
"mode": "overwrite"
}
}
Request (Append):
{
"name": "write_note",
"arguments": {
"path": "daily-log.md",
"content": "\n\n## 3:00 PM Update\n- Completed project review\n- Started new feature",
"mode": "append"
}
}
Response:
{
"message": "Successfully wrote note: meeting-notes.md (mode: overwrite)"
}
patch_note
Efficiently replace an exact string inside an existing note without rewriting the full file.
Request:
{
"name": "patch_note",
"arguments": {
"path": "meeting-notes.md",
"oldString": "- Next milestones",
"newString": "- Next milestones (owner: Alex)",
"replaceAll": false
}
}
Response (success):
{
"success": true,
"path": "meeting-notes.md",
"message": "Successfully replaced 1 occurrence",
"matchCount": 1
}
Response (multiple matches with replaceAll=false):
{
"success": false,
"path": "meeting-notes.md",
"message": "Found 3 occurrences of the string. Use replaceAll=true to replace all occurrences, or provide a more specific string to match exactly one occurrence.",
"matchCount": 3
}
list_directory
List files and directories in the vault.
Note: this includes non-note filenames (for example pdf, png, jpg) so AI assistants can see vault structure, but note tools like read_note and write_note still operate on note files only (.md, .markdown, .txt).
Request:
{
"name": "list_directory",
"arguments": {
"path": "Projects",
"prettyPrint": false
}
}
Response (optimized):
{
"dirs": ["AI-Tools", "Web-Development"],
"files": ["project-template.md", "roadmap.md"]
}
delete_note
Delete a note from the vault (requires confirmation for safety).
Request:
{
"name": "delete_note",
"arguments": {
"path": "old-draft.md",
"confirmPath": "old-draft.md"
}
}
Response (Success):
{
"success": true,
"path": "old-draft.md",
"message": "Successfully deleted note: old-draft.md. This action cannot be undone."
}
Response (Confirmation Failed):
{
"success": false,
"path": "old-draft.md",
"message": "Deletion cancelled: confirmation path does not match. For safety, both 'path' and 'confirmPath' must be identical."
}
⚠️ Safety Note: The confirmPath parameter must exactly match the path parameter to proceed with deletion. This prevents accidental deletions.
get_frontmatter
Extract only the frontmatter from a note without reading the full content.
Request:
{
"name": "get_frontmatter",
"arguments": {
"path": "project-ideas.md",
"prettyPrint": false
}
}
Response (optimized, returns frontmatter directly):
{
"title": "Project Ideas",
"tags": ["projects", "brainstorming"],
"created": "2023-01-15T10:30:00.000Z"
}
manage_tags
Add, remove, or list tags in a note. Tags are managed in the frontmatter and inline tags are detected.
Request (List Tags):
{
"name": "manage_tags",
"arguments": {
"path": "research-notes.md",
"operation": "list"
}
}
Request (Add Tags):
{
"name": "manage_tags",
"arguments": {
"path": "research-notes.md",
"operation": "add",
"tags": ["machine-learning", "ai", "important"]
}
}
Request (Remove Tags):
{
"name": "manage_tags",
"arguments": {
"path": "research-notes.md",
"operation": "remove",
"tags": ["draft", "temporary"]
}
}
Response:
{
"path": "research-notes.md",
"operation": "add",
"tags": ["research", "ai", "machine-learning", "important"],
"success": true,
"message": "Successfully added tags"
}
search_notes
Search for notes in the vault by content or frontmatter with multi-word matching and BM25 relevance reranking.
Request:
{
"name": "search_notes",
"arguments": {
"query": "machine learning",
"limit": 5,
"searchContent": true,
"searchFrontmatter": false,
"caseSensitive": false,
"prettyPrint": false
}
}
Response (optimized with minified field names):
[
{
"p": "ai-research.md",
"t": "AI Research Notes",
"ex": "...machine learning...",
"mc": 2,
"ln": 15,
"uri": "obsidian://open?vault=MyVault&file=ai-research.md"
}
]
Field names:
p= patht= titleex= excerpt (21 chars context)mc= match countln= line numberuri= Obsidian deep link for quick opening
move_note
Move or rename a note in the vault (.md, .markdown, .txt).
Request:
{
"name": "move_note",
"arguments": {
"oldPath": "drafts/article.md",
"newPath": "published/article.md",
"overwrite": false
}
}
Response:
{
"success": true,
"oldPath": "drafts/article.md",
"newPath": "published/article.md",
"message": "Successfully moved note from drafts/article.md to published/article.md"
}
move_file
Move or rename any file in the vault with binary-safe file operations (file-only; not recursive directory moves). For safety, this tool requires confirmation of both source and destination paths.
Request:
{
"name": "move_file",
"arguments": {
"oldPath": "Miro/attachments/Pasted image 20250812140124.png",
"newPath": "assets/images/Pasted image 20250812140124.png",
"confirmOldPath": "Miro/attachments/Pasted image 20250812140124.png",
"confirmNewPath": "assets/images/Pasted image 20250812140124.png",
"overwrite": false
}
}
Response:
{
"success": true,
"oldPath": "Miro/attachments/Pasted image 20250812140124.png",
"newPath": "assets/images/Pasted image 20250812140124.png",
"message": "Successfully moved file from Miro/attachments/Pasted image 20250812140124.png to assets/images/Pasted image 20250812140124.png"
}
Safety Note: confirmOldPath must exactly match oldPath, and confirmNewPath must exactly match newPath, otherwise the move is rejected.
read_multiple_notes
Read multiple notes in a batch (maximum 10 files).
Request:
{
"name": "read_multiple_notes",
"arguments": {
"paths": ["note1.md", "note2.md", "note3.md"],
"includeContent": true,
"includeFrontmatter": true,
"prettyPrint": false
}
}
Response (optimized, shortened field names):
{
"ok": [
{
"path": "note1.md",
"frontmatter": { "title": "Note 1" },
"content": "# Note 1\n\nContent here..."
}
],
"err": [{ "path": "note2.md", "error": "File not found" }]
}
Field names:
ok= successful readserr= failed reads
update_frontmatter
Update frontmatter of a note without changing content.
Request:
{
"name": "update_frontmatter",
"arguments": {
"path": "research-note.md",
"frontmatter": {
"status": "completed",
"updated": "2025-09-23"
},
"merge": true
}
}
Response:
{
"message": "Successfully updated frontmatter for: research-note.md"
}
get_notes_info
Get metadata for notes without reading full content.
Request:
{
"name": "get_notes_info",
"arguments": {
"paths": ["note1.md", "note2.md"],
"prettyPrint": false
}
}
Response (optimized, returns array directly):
[
{
"path": "note1.md",
"size": 1024,
"modified": 1695456000000,
"hasFrontmatter": true
}
]
get_vault_stats
Get high-level vault statistics without reading note contents.
Request:
{
"name": "get_vault_stats",
"arguments": {
"recentCount": 5,
"prettyPrint": false
}
}
Response (optimized):
{
"notes": 1248,
"folders": 76,
"size": 18349210,
"recent": [
{
"path": "Daily/2026-02-27.md",
"modified": 1772188800000,
"size": 2814
}
]
}
Security Considerations
This MCP server implements several security measures to protect your Obsidian vault:
Path Security
- Path Traversal Protection: All file paths are validated to prevent access outside the vault
- Relative Path Enforcement: Paths are normalized and restricted to the vault directory
- Symbolic Link Safety: Resolved paths are checked against vault boundaries
File Filtering
- Automatic Exclusions:
.obsidian,.git,node_modules, and system files are filtered - Extension Whitelist: Only
.md,.markdown, and.txtfiles are accessible by default - Hidden File Protection: Dot files and system directories are automatically excluded
Content Validation
- YAML Frontmatter Validation: Frontmatter is parsed and validated before writing
- Function/Symbol Prevention: Dangerous JavaScript objects are blocked from frontmatter
- Data Type Checking: Only safe data types (strings, numbers, arrays, objects) allowed
Best Practices
- Least Privilege: Server only accesses the specified vault directory
- Read-Only by Default: Consider running with read-only permissions for sensitive vaults
- Backup Recommended: Always backup your vault before using write operations
- Network Isolation: Server uses stdio transport (no network exposure)
What's NOT Protected
- File Content: The server can read/write any allowed file content
- Vault Structure: Directory structure is visible to AI assistants
- File Metadata: Creation times, file sizes, etc. are accessible
⚠️ Important: Only grant vault access to trusted AI conversations. The server provides full read/write access to your notes within the security boundaries above.
Architecture
server.ts- MCP server entry pointsrc/frontmatter.ts- YAML frontmatter handling with gray-mattersrc/filesystem.ts- Safe file operations with path validationsrc/pathfilter.ts- Directory and file filteringsrc/search.ts- Note search functionality with content and frontmatter supportsrc/uri.ts- Obsidian URI generation for deep linkssrc/types.ts- TypeScript type definitions
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes and add tests
- Ensure all tests pass:
npm test - Submit a pull request
License
MIT