obsidian-mcp
Provides tools for listing to-dos, reading note content, and updating task completion status in an Obsidian vault.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@obsidian-mcpWhat are my pending to-dos?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Obsidian MCP Server
A Model Context Protocol (MCP) server that connects your Obsidian vault directly to Claude and Cursor, allowing you to manage your to-dos without retyping tasks.
Portuguese version: README.pt.md
What is MCP?
Model Context Protocol is an open protocol that allows integrating external tools (like your Obsidian) with AIs (Claude, Cursor, etc). Think of it as a "universal adapter" that tells Claude: "Hey, you can use these tools to access my to-dos in Obsidian".
Without MCP, you'd have to copy and paste your tasks every time. With MCP, Claude accesses directly.
Related MCP server: Obsidian MCP Server
Features
✅ List all to-dos from your Obsidian vault automatically
✅ Mark tasks as complete directly via Claude/Cursor
✅ Read entire notes for context
✅ Works with Claude Desktop and Cursor simultaneously
✅ Recursive search across all folders
✅ Support for standard Obsidian checkboxes (
- [ ]and- [x])
Project Structure
obsidian-mcp-server/
├── src/
│ ├── __init__.py # Marks folder as Python package
│ └── obsidian_mcp.py # Main MCP server (critical file)
│
├── venv/ # Python virtual environment (ignored in git)
│
├── requirements.txt # Project dependencies
├── .env.example # Configuration template
├── .gitignore # Files ignored by git
├── README.md # Portuguese documentation
├── README.en.md # English documentation
└── setup.py # Package metadata (optional)What each file does:
File | Function |
| Heart of the project. Defines 3 tools: |
| Isolated Python with MCP packages installed. When Claude calls the server, it runs this Python |
| Lists packages: |
| Your local file (not committed) with |
| Config that Claude Desktop reads from |
| Config that Cursor reads from |
Installation
Prerequisites
macOS (tested on 11.0+)
Python 3.11 or higher
Homebrew (to install Python)
Claude Desktop or Cursor installed
An existing Obsidian vault
Step 1: Clone or Create the Project
# If cloning from GitHub:
git clone git@github.com:YOUR-USER/obsidian-mcp.git
cd obsidian-mcp
# Or create from scratch:
mkdir obsidian-mcp
cd obsidian-mcpStep 2: Create Python Virtual Environment
python3.11 -m venv venv
source venv/bin/activateYour prompt should appear like this:
(venv) obsidian-mcp %Step 3: Install Dependencies
pip install --upgrade pip
pip install -r requirements.txtThis installs:
mcp(2.2.0+) — the MCP protocolpython-dotenv— to read environment variables
Step 4: Create .env File
# Copy the template:
cp .env.example .env
# Open and replace the path:
nano .envFind your vault path:
Open Obsidian
Go to Settings → About
Look for Vault location:
Copy the full path and paste in
.env
Example:
OBSIDIAN_VAULT_PATH=/Users/pauline/Documents/MyVaultSave (Ctrl+X, then y and Enter).
Step 5: Test the Server Locally
python3 src/obsidian_mcp.pyIf it works, the terminal waits (no error should appear). Press Ctrl+C to exit.
Configuration (Claude Desktop + Cursor)
Claude Desktop
Create the configuration folder:
mkdir -p ~/Library/Application\ Support/ClaudeCreate the
claude_desktop_config.jsonfile:
cat > ~/Library/Application\ Support/Claude/claude_desktop_config.json << 'EOF'
{
"mcpServers": {
"obsidian-mcp": {
"command": "/full/path/to/obsidian-mcp/venv/bin/python3",
"args": [
"/full/path/to/obsidian-mcp/src/obsidian_mcp.py"
],
"env": {
"OBSIDIAN_VAULT_PATH": "/Users/your-username/Documents/your-vault"
}
}
}
}
EOFReplace:
/full/path/to/obsidian-mcp→ the real path (ex:/Users/pauline/Documents/obsidian-mcp)/Users/your-username/Documents/your-vault→ your vault
Restart Claude Desktop (Cmd+Q and open again)
Cursor
Create the folder:
mkdir -p ~/.cursorCreate the
mcp.jsonfile:
cat > ~/.cursor/mcp.json << 'EOF'
{
"mcpServers": {
"obsidian-mcp": {
"command": "/full/path/to/obsidian-mcp/venv/bin/python3",
"args": [
"/full/path/to/obsidian-mcp/src/obsidian_mcp.py"
],
"env": {
"OBSIDIAN_VAULT_PATH": "/Users/your-username/Documents/your-vault"
}
}
}
}
EOFRestart Cursor (Cmd+Q and open again)
How to Use
In Claude Desktop
Open a conversation and ask anything related to tasks:
What are my to-dos in Obsidian?Claude will:
Call the
get_todostoolReceive JSON with all tasks (167 in your case!)
Format and display readably
You can also do:
Mark the task "Deploy the app" in Projects/project-x.md line 5 as completeClaude will automatically call update_todo.
In Cursor
Access the Claude tab (left side) and ask the same questions. Behavior is identical.
How It Works Under the Hood
Claude/Cursor (AIs)
↓
claude_desktop_config.json / mcp.json (configs)
↓
OS Executor (reads config and runs Python command)
↓
/venv/bin/python3 src/obsidian_mcp.py (server running)
↓
MCPServer ("listens" for MCP requests)
↓
Functions decorated with @mcp.tool():
- get_todos() → Sweeps .rglob("*.md"), extracts checkboxes
- get_note_content() → Opens file and returns content
- update_todo() → Writes [ ] or [x] and saves file
↓
JSON responses
↓
Claude/Cursor displays to youCode Structure
src/obsidian_mcp.py - The Jewel
from mcp.server.mcpserver import MCPServer
mcp = MCPServer("obsidian-mcp")
@mcp.tool()
def get_todos(folder: Optional[str] = None) -> str:
"""Tool 1: Lists all to-dos"""
# Sweeps vault_path recursively with .rglob("*.md")
# Searches for lines with "- [ ]" or "- [x]"
# Returns JSON with {file, line, completed, text}
@mcp.tool()
def get_note_content(note_path: str) -> str:
"""Tool 2: Reads entire note"""
# Opens file and returns raw content
@mcp.tool()
def update_todo(note_path: str, line_number: int, completed: bool) -> str:
"""Tool 3: Marks task as done/not done"""
# Reads file, replaces [ ] with [x] (or vice versa), saves
if __name__ == "__main__":
mcp.run() # Starts MCP server via stdioTask Flow
User: "Show me my to-dos"
Claude: Calls
get_todos()via MCPServer (your code):
Reads
OBSIDIAN_VAULT_PATHvariableTraverses all folders with
.rglob("*.md")For each file, searches for lines with
"- [ ]"or"- [x]"Returns JSON:
{"todos": [...], "count": 167}
Claude: Receives JSON, formats nicely and displays
You: See your 167 to-dos listed
Troubleshooting
"I don't have access to your Obsidian"
Means Claude couldn't connect to the server. Check:
Config file exists?
cat ~/Library/Application\ Support/Claude/claude_desktop_config.jsonPython path is correct?
ls /path/you/put/venv/bin/python3If not found, use the real path (run
which python3with venv activated)Vault path is correct?
ls /Users/your-username/your-vaultRestarted Claude Desktop after editing config?
"ModuleNotFoundError: No module named 'mcp'"
Means it's running the wrong Python (not from venv). Check the path in claude_desktop_config.json:
# Must be THIS:
/Users/pauline/Documents/obsidian-mcp/venv/bin/python3
# Not this:
python3.11Resources
Usage Examples - Advanced Filters
This document shows how to use the 3 filtering methods in Obsidian MCP Server.
1️⃣ Inline Tags (#tag)
File: Projects/oloroke-notes.md
# Oloroke Improvements
- [ ] Implement OAuth authentication #urgent #backend
- [ ] Improve carousel performance #performance #frontend
- [ ] Add unit tests #testing #backend
- [x] Review UI/UX #design #completed
- [ ] Document API #documentation #backendHow to call in Claude:
Show me all tasks with tag #urgent from olorokeClaude automatically calls:
get_todos(folder="Projects/oloroke-notes", tag="urgent")Returns:
{
"todos": [
{
"file": "Projects/oloroke-notes.md",
"line": 2,
"completed": false,
"text": "Implement OAuth authentication",
"tags": ["urgent", "backend"],
"priority": null,
"project": null
}
],
"count": 1
}Example questions:
Which tasks have #backend?
Show me tasks with #testing
Execute all #urgent tasks from oloroke2️⃣ Priority with Emoji (🔴🟡🟢⚫)
File: Projects/oloroke-notes.md
# Oloroke Improvements
- [ ] 🔴 Implement OAuth authentication
- [ ] 🟡 Improve carousel performance
- [ ] 🟢 Add unit tests
- [x] 🔵 Review UI/UX
- [ ] 🟡 Document API
- [ ] ⚫ Database migration (blocked)Emoji Legend:
Emoji | Meaning | Flag |
🔴 | High priority |
|
🟡 | Medium priority |
|
🟢 | Low priority |
|
⚫ | Blocked |
|
How to call in Claude:
Show me high priority tasks from olorokeClaude automatically calls:
get_todos(folder="Projects/oloroke-notes", priority="high")Returns:
{
"todos": [
{
"file": "Projects/oloroke-notes.md",
"line": 2,
"completed": false,
"text": "Implement OAuth authentication",
"tags": [],
"priority": "high",
"project": null
}
],
"count": 1
}Example questions:
Which are the red tasks (🔴)?
Show me everything that's blocked (⚫)
Execute medium priority tasks3️⃣ YAML Frontmatter (More Structured)
File: Projects/oloroke-notes.md
---
projeto: oloroke
prioridade: alta
tags: [urgent, backend]
responsavel: Pauline
deadline: 2024-12-31
---
# Oloroke Improvements
- [ ] Implement OAuth authentication
- [ ] Improve carousel performance
- [x] Review UI/UX
---
projeto: oloroke
prioridade: média
tags: [testing, refactor]
---
## Tests and Refactor
- [ ] Add unit tests
- [ ] Clean up legacy codeFrontmatter Structure:
---
projeto: project-name # Identifies the project
prioridade: high|medium|low # General priority for the note
tags: [tag1, tag2, tag3] # Tags applied to ALL to-dos
responsavel: Person's Name # Who is responsible
deadline: YYYY-MM-DD # Deadline (you can use for filtering)
---How to call in Claude:
Show me all tasks from oloroke project with high priorityClaude calls:
get_todos(folder="Projects/oloroke-notes", priority="high")Returns:
{
"todos": [
{
"file": "Projects/oloroke-notes.md",
"line": 0,
"completed": false,
"text": "Implement OAuth authentication",
"tags": ["urgent", "backend"],
"priority": "high",
"project": "oloroke"
},
{
"file": "Projects/oloroke-notes.md",
"line": 1,
"completed": false,
"text": "Improve carousel performance",
"tags": ["urgent", "backend"],
"priority": "high",
"project": "oloroke"
}
],
"count": 2
}Example questions:
What tasks are in oloroke project?
Show me everything about terreiro-app project
Execute high priority tasks from petloveCombining All Methods
File: Projects/oloroke-notes.md
---
projeto: oloroke
tags: [oloroke, app]
---
# Oloroke - Priority Tasks
## Backend
- [ ] 🔴 Implement OAuth authentication #urgent #backend
- [ ] 🟡 Improve carousel performance #performance #backend
- [ ] 🟢 Add unit tests #testing
## Frontend
- [ ] 🔴 Review interface design #urgent #design
- [ ] 🟡 Implement dark mode #ui #frontend
- [ ] ⚫ TypeScript migration #blocked #refactorHere you have:
Frontmatter: Identifies project
olorokeand general tagsInline tags: Specifies
#urgent,#backend,#testing, etcEmoji: Shows visual priority
🔴🟡🟢⚫
Powerful example questions:
"Execute all urgent (#urgent) tasks from oloroke project"
→ get_todos(folder="Projects/oloroke-notes", tag="urgent", project="oloroke")
"Which tasks are blocked that I need to unblock?"
→ get_todos(priority="blocked")
"What backend (#backend) work needs high priority?"
→ get_todos(tag="backend", priority="high")
"Which incomplete tasks from oloroke have #urgent?"
→ get_todos(folder="Projects/oloroke-notes", tag="urgent", completed=False)Comparison: Which to Use?
Method | Pros | Cons | Best For |
Inline Tags | Flexible, easy to add | Can pollute the line | Quick categorizations |
Emoji | Visual, intuitive | Limited to 4 priorities | Quick priority view |
Frontmatter | Structured, rich metadata | More work to maintain | Complex projects |
All 3 | Maximum flexibility | None! | Recommended! |
Installing Advanced Version
Replace
src/obsidian_mcp.pywith the advanced versionUpdate
requirements.txt:
cat > requirements.txt << 'EOF'
mcp>=0.2.0
python-dotenv>=1.0.0
pyyaml>=6.0
EOFReinstall dependencies:
pip install -r requirements.txtRestart Claude Desktop and Cursor
Pro Tips
1. Organize by project
---
projeto: oloroke
---2. Use tags for categories
- [ ] Task #backend #urgent #oauth3. Combine with emoji for quick visualization
- [ ] 🔴 #urgent Critical thing4. Add useful metadata in frontmatter
---
projeto: oloroke
deadline: 2024-12-31
responsavel: Pauline
reviewed_on: 2024-09-25
---5. Aggregate related notes
Create a folder per project:
Projects/
├── oloroke-notes.md
├── terreiro-app-notes.md
└── petlove-improvements.mdThen ask:
"What are all the tasks in the Projects folder?"Real Conversation Examples
Conversation 1: Explore a project
You: What projects do I have?
Claude: [lists via list_projects()]
You: Show me high priority tasks from oloroke
Claude: [calls get_todos(project="oloroke", priority="high")]
Shows 3 tasks 🔴
You: Execute the first one (OAuth)
Claude: [calls update_todo()]
Marks as complete and confirmsConversation 2: Filter by context
You: I'm working on tests now
Claude: Understood, show me only tasks with #testing tag
Claude: [calls get_todos(tag="testing")]
Shows 2 test tasks
You: Mark the first one as complete
Claude: [calls update_todo()]Conversation 3: Combine filters
You: What's my most urgent backend work in oloroke?
Claude: [calls get_todos(
folder="Projects/oloroke-notes",
tag="backend",
priority="high",
completed=False
)]
Shows: "Implement OAuth authentication"Done! Now you have 3 powerful ways to organize your tasks in Obsidian and Claude can filter exactly what you need.
License
MIT - Use freely! If you make improvements, consider submitting a pull request
Contributing
Found a bug or have an idea? Open an issue or submit a pull request!
Created by Pauline Oliveira
Questions? Open an issue on GitHub or reach out!
This server cannot be deployed
Maintenance
Related MCP Connectors
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
Read and write your Fresh Jots notes from Claude, Cursor, and any MCP client.
Notes and actions in one app. Let Claude or ChatGPT read and update them.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to manage tasks within an Obsidian vault by listing, adding, and updating todos via the Local REST API. It allows users to create new todos in daily notes and retrieve task statistics through natural language.53 npmMIT
- AlicenseNot gradedqualityDmaintenanceConnects Claude Desktop to your Obsidian vault, enabling reading, writing, searching, and organizing notes locally.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude to read your Obsidian vault and retrieve outstanding tasks from daily notes by parsing checkboxes.11,823 npmApache 2.0
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage and search Obsidian notes, folders, metadata, and links directly.-