Skip to main content
Glama
Obsidian MCP Server
by adrienthebo

Obsidian MCP Server

šŸŽ‰ Version 2.0 Released!

Major improvements in v2.0:

  • ⚔ 5x faster searches with persistent SQLite indexing

  • šŸ–¼ļø Image support - View and analyze images from your vault

  • šŸ” Powerful regex search - Find complex patterns in your notes

  • šŸ—‚ļø Property search - Query by frontmatter properties (status, priority, etc.)

  • šŸš€ One-command setup - Auto-configure Claude Desktop with uvx --from obsidian-mcp obsidian-mcp-configure --vault-path /path/to/your/vault

  • šŸ”„ Direct filesystem access - No plugins required, works offline

  • šŸ“¦ 90% less memory usage - Efficient streaming architecture


A Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with your Obsidian vault. This server provides tools for reading, creating, searching, and managing notes in Obsidian through direct filesystem access with blazing-fast performance thanks to intelligent indexing.

Related MCP server: Obsidian MCP Server

Features

  • šŸ“– Read & write notes - Full access to your Obsidian vault with automatic overwrite protection

  • šŸ” Lightning-fast search - Find notes instantly by content, tags, properties, or modification date with persistent indexing

  • šŸ–¼ļø Image analysis - View and analyze images embedded in notes or stored in your vault

  • šŸ”Ž Regex power search - Use regular expressions to find code patterns, URLs, or complex text structures

  • šŸ—‚ļø Property search - Query notes by frontmatter properties with operators (=, >, <, contains, exists)

  • šŸ“ Browse vault - List and navigate your notes and folders by directory

  • šŸ·ļø Tag management - Add, remove, and organize tags (supports hierarchical tags, frontmatter, and inline tags)

  • šŸ”— Link management - Find backlinks, analyze outgoing links, and identify broken links

  • āœļø Smart rename - Rename notes with automatic link updates throughout your vault

  • šŸ“Š Note insights - Get statistics like word count and link analysis

  • šŸŽÆ AI-optimized - Clear error messages and smart defaults for better AI interactions

  • šŸ”’ Secure - Direct filesystem access with path validation

  • ⚔ Performance optimized - Persistent SQLite index, concurrent operations, and streaming for large vaults

  • šŸš€ Bulk operations - Create folder hierarchies and move entire folders with all their contents

Prerequisites

  • Obsidian vault on your local filesystem

  • Python 3.10+ installed on your system

  • Node.js (optional, for running MCP Inspector)

Installation

Quick Install with Auto-Configuration (Claude Desktop)

New in v2.0! Configure Claude Desktop automatically with one command:

# Install and configure in one step
uvx --from obsidian-mcp obsidian-mcp-configure --vault-path /path/to/your/vault

This command will:

  • āœ… Automatically find your Claude Desktop config

  • āœ… Add the Obsidian MCP server

  • āœ… Migrate old REST API configs to v2.0

  • āœ… Create a backup of your existing config

  • āœ… Work on macOS, Windows, and Linux

Manual Configuration

  1. Locate your Obsidian vault:

    • Find the path to your Obsidian vault on your filesystem

    • Example: /Users/yourname/Documents/MyVault or C:\Users\YourName\Documents\MyVault

  2. Configure your AI tool:

    Edit your Claude Desktop config file:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

    {
      "mcpServers": {
        "obsidian": {
          "command": "uvx",
          "args": ["obsidian-mcp"],
          "env": {
            "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault"
          }
        }
      }
    }

    Add to your Cursor settings:

    • Project-specific: .cursor/mcp.json in your project directory

    • Global: ~/.cursor/mcp.json in your home directory

    {
      "mcpServers": {
        "obsidian": {
          "command": "uvx",
          "args": ["obsidian-mcp"],
          "env": {
            "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault"
          }
        }
      }
    }

    Then: Open Settings → Cursor Settings → Enable MCP

    Edit your Windsurf config file:

    • Location: ~/.codeium/windsurf/mcp_config.json

    {
      "mcpServers": {
        "obsidian": {
          "command": "uvx",
          "args": ["obsidian-mcp"],
          "env": {
            "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault"
          }
        }
      }
    }

    Then: Open Windsurf Settings → Advanced Settings → Cascade → Add Server → Refresh

  3. Restart your AI tool to load the new configuration.

That's it! The server will now be available in your AI tool with access to your Obsidian vault.

Note: This uses uvx which automatically downloads and runs the server in an isolated environment. Most users won't need to install anything else. If you don't have uv installed, you can also use pipx install obsidian-mcp and change the command to "obsidian-mcp" in the config.

Try It Out

Here are some example prompts to get started:

  • "Show me all notes I modified this week"

  • "Create a new daily note for today with my meeting agenda"

  • "Search for all notes about project planning"

  • "Read my Ideas/startup.md note"

Development Installation

  1. Clone the repository:

    git clone https://github.com/natestrong/obsidian-mcp
    cd obsidian-mcp
  2. Set up Python environment:

    # Using pyenv (recommended)
    pyenv virtualenv 3.12.9 obsidian-mcp
    pyenv activate obsidian-mcp
    
    # Or using venv
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
  3. Install dependencies:

    pip install -r requirements.txt
  4. Configure environment variables:

    export OBSIDIAN_VAULT_PATH="/path/to/your/obsidian/vault"
  5. Run the server:

    python -m obsidian_mcp.server
  6. Add to Claude Desktop (for development):

    Edit your Claude Desktop config file:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

    {
      "mcpServers": {
        "obsidian": {
          "command": "/path/to/python",
          "args": ["-m", "obsidian_mcp.server"],
          "cwd": "/path/to/obsidian-mcp",
          "env": {
            "PYTHONPATH": "/path/to/obsidian-mcp",
            "OBSIDIAN_VAULT_PATH": "/path/to/your/obsidian/vault"
          }
        }
      }
    }

Project Structure

obsidian-mcp/
ā”œā”€ā”€ obsidian_mcp/
│   ā”œā”€ā”€ server.py           # Main entry point with rich parameter schemas
│   ā”œā”€ā”€ tools/              # Tool implementations
│   │   ā”œā”€ā”€ note_management.py    # CRUD operations
│   │   ā”œā”€ā”€ search_discovery.py   # Search and navigation
│   │   ā”œā”€ā”€ organization.py       # Tags, moves, metadata
│   │   └── link_management.py    # Backlinks, outgoing links, broken links
│   ā”œā”€ā”€ models/             # Pydantic models for validation
│   │   └── obsidian.py    # Note, SearchResult, VaultItem models
│   ā”œā”€ā”€ utils/              # Shared utilities
│   │   ā”œā”€ā”€ filesystem.py        # Direct filesystem access
│   │   ā”œā”€ā”€ validators.py        # Path validation, sanitization
│   │   └── validation.py        # Comprehensive parameter validation
│   └── constants.py       # Constants and error messages
ā”œā”€ā”€ tests/
│   ā”œā”€ā”€ run_tests.py       # Test runner
│   └── test_filesystem_integration.py # Integration tests
ā”œā”€ā”€ docs/                  # Additional documentation
ā”œā”€ā”€ requirements.txt       # Python dependencies
ā”œā”€ā”€ CLAUDE.md             # Instructions for Claude Code
└── README.md

Available Tools

Note Management

read_note

Read the content and metadata of a specific note.

Parameters:

  • path: Path to the note (e.g., "Daily/2024-01-15.md")

Returns:

{
  "path": "Daily/2024-01-15.md",
  "content": "# Daily Note\n\nContent here...",
  "metadata": {
    "tags": ["daily", "journal"],
    "aliases": [],
    "frontmatter": {}
  }
}

create_note

Create a new note or update an existing one.

Parameters:

  • path: Path where the note should be created

  • content: Markdown content of the note (consider adding tags for organization)

  • overwrite (default: false): Whether to overwrite existing notes

Best Practices:

  • Add relevant tags when creating notes to maintain organization

  • Use list_tags to see existing tags and maintain consistency

  • Tags can be added as inline hashtags (#tag) or in frontmatter

update_note

Update the content of an existing note.

āš ļø IMPORTANT: By default, this tool REPLACES the entire note content. Always read the note first if you need to preserve existing content.

Parameters:

  • path: Path to the note to update

  • content: New markdown content (REPLACES existing content unless using append)

  • create_if_not_exists (default: false): Create if doesn't exist

  • merge_strategy (default: "replace"): How to handle content

    • "replace": Overwrites entire note content (default)

    • "append": Adds new content to the end of existing content

Safe Update Pattern:

  1. ALWAYS read first to preserve content

  2. Modify the content as needed

  3. Update with the complete new content

  4. Or use append mode to add content to the end

edit_note_section

Edit a specific section of a note identified by a markdown heading.

Parameters:

  • path: Path to the note to edit

  • section_identifier: Markdown heading that identifies the section (e.g., "## Tasks", "### Status")

  • content: Content to insert, replace, or append

  • operation (default: "insert_after"): How to edit the section

    • "insert_after": Add content after the section heading

    • "insert_before": Add content before the section heading

    • "replace": Replace entire section including heading

    • "append_to_section": Add content at the end of the section

  • create_if_missing (default: false): Create section if it doesn't exist

Example usage:

# Add tasks to a specific section
await edit_note_section(
    "Daily/2024-01-15.md",
    "## Tasks",
    "- [ ] Review PR\n- [ ] Update docs",
    operation="append_to_section"
)

# Update a status section
await edit_note_section(
    "Projects/Website.md",
    "### Current Status",
    "### Current Status\n\nPhase 2 completed!",
    operation="replace"
)

Use cases:

  • Adding items to task lists without rewriting the whole note

  • Updating status sections in project notes

  • Building up notes incrementally by section

  • Inserting content at precise locations

delete_note

Delete a note from the vault.

Parameters:

  • path: Path to the note to delete

Search and Discovery

search_notes

Search for notes containing specific text or tags.

Parameters:

  • query: Search query (supports Obsidian search syntax)

  • context_length (default: 100): Number of characters to show around matches

  • max_results (default: 50): Maximum number of results to return (1-500)

Search Syntax:

  • Text search: "machine learning"

  • Tag search: tag:project or tag:#project

    • Hierarchical tags: tag:project/web (exact match)

    • Parent search: tag:project (finds project, project/web, project/mobile)

    • Child search: tag:web (finds project/web, design/web)

  • Path search: path:Daily/

  • Property search: property:status:active or property:priority:>2

  • Combined: tag:urgent TODO

Returns:

{
  "results": [...],        // Array of matched notes
  "total_count": 150,      // Total matches found
  "limit": 50,             // max_results used
  "truncated": true        // More results available
}

Property Search Examples:

  • property:status:active - Find notes where status = "active"

  • property:priority:>2 - Find notes where priority > 2

  • property:author:*john* - Find notes where author contains "john"

  • property:deadline:* - Find notes that have a deadline property

  • property:rating:>=4 - Find notes where rating >= 4

  • property:tags:project - Find notes with "project" in their tags array

  • property:due_date:<2024-12-31 - Find notes with due dates before Dec 31, 2024

search_by_date

Search for notes by creation or modification date.

Parameters:

  • date_type (default: "modified"): Either "created" or "modified"

  • days_ago (default: 7): Number of days to look back

  • operator (default: "within"): Either "within" (last N days) or "exactly" (exactly N days ago)

Returns:

{
  "query": "Notes modified within last 7 days",
  "count": 15,
  "results": [
    {
      "path": "Daily/2024-01-15.md",
      "date": "2024-01-15T10:30:00",
      "days_ago": 1
    }
  ]
}

Example usage:

  • "Show me all notes modified today" → search_by_date("modified", 0, "within")

  • "Show me all notes modified this week" → search_by_date("modified", 7, "within")

  • "Find notes created in the last 30 days" → search_by_date("created", 30, "within")

  • "What notes were modified exactly 2 days ago?" → search_by_date("modified", 2, "exactly")

search_by_regex

Search for notes using regular expressions for advanced pattern matching.

Parameters:

  • pattern: Regular expression pattern to search for

  • flags (optional): List of regex flags ("ignorecase", "multiline", "dotall")

  • context_length (default: 100): Characters to show around matches

  • max_results (default: 50): Maximum number of results

When to use:

  • Finding code patterns (functions, imports, syntax)

  • Searching for structured data

  • Complex text patterns that simple search can't handle

Common patterns:

# Find Python imports
"(import|from)\\s+fastmcp"

# Find function definitions
"def\\s+\\w+\\s*\\([^)]*\\):"

# Find TODO comments
"(TODO|FIXME)\\s*:?\\s*(.+)"

# Find URLs
"https?://[^\\s)>]+"

# Find code blocks
"```python([^`]+)```"

Returns:

{
  "pattern": "def\\s+search\\w*",
  "count": 2,
  "results": [
    {
      "path": "code/utils.py",
      "match_count": 3,
      "matches": [
        {
          "match": "def search_notes",
          "line": 42,
          "context": "...async def search_notes(query)..."
        }
      ]
    }
  ]
}

search_by_property

Search for notes by their frontmatter property values with advanced filtering.

Parameters:

  • property_name: Name of the property to search for

  • value (optional): Value to compare against

  • operator (default: "="): Comparison operator

  • context_length (default: 100): Characters of note content to include

Operators:

  • "=": Exact match (case-insensitive)

  • "!=": Not equal

  • ">", "<", ">=", "<=": Numeric/date comparisons

  • "contains": Property value contains the search value

  • "exists": Property exists (value parameter ignored)

Supported Property Types:

  • Text/String: Standard text comparison

  • Numbers: Automatic numeric comparison for operators

  • Dates: ISO format (YYYY-MM-DD) with intelligent date parsing

  • Arrays/Lists: Searches within array items, comparisons use array length

  • Legacy properties: Automatically handles tag→tags, alias→aliases migrations

Returns:

{
  "property": "status",
  "operator": "=",
  "value": "active",
  "count": 5,
  "results": [
    {
      "path": "Projects/Website.md",
      "matches": ["status = active"],
      "context": "status: active\n\n# Website Redesign Project...",
      "property_value": "active"
    }
  ]
}

Example usage:

  • Find all active projects: search_by_property("status", "active")

  • Find high priority items: search_by_property("priority", "2", ">")

  • Find notes with deadlines: search_by_property("deadline", operator="exists")

  • Find notes by partial author: search_by_property("author", "john", "contains")

list_notes

List notes in your vault with optional recursive traversal.

Parameters:

  • directory (optional): Specific directory to list (e.g., "Daily", "Projects")

  • recursive (default: true): List all notes recursively

Returns:

{
  "directory": "Daily",
  "recursive": true,
  "count": 365,
  "notes": [
    {"path": "Daily/2024-01-01.md", "name": "2024-01-01.md"},
    {"path": "Daily/2024-01-02.md", "name": "2024-01-02.md"}
  ]
}

list_folders

List folders in your vault with optional recursive traversal.

Parameters:

  • directory (optional): Specific directory to list from

  • recursive (default: true): Include all nested subfolders

Returns:

{
  "directory": "Projects",
  "recursive": true,
  "count": 12,
  "folders": [
    {"path": "Projects/Active", "name": "Active"},
    {"path": "Projects/Archive", "name": "Archive"},
    {"path": "Projects/Ideas", "name": "Ideas"}
  ]
}

Organization

create_folder

Create a new folder in the vault, including all parent folders in the path.

Parameters:

  • folder_path: Path of the folder to create (e.g., "Research/Studies/2024")

  • create_placeholder (default: true): Whether to create a placeholder file

Returns:

{
  "folder": "Research/Studies/2024",
  "created": true,
  "placeholder_file": "Research/Studies/2024/.gitkeep",
  "folders_created": ["Research", "Research/Studies", "Research/Studies/2024"]
}

Note: This tool will create all necessary parent folders. For example, if "Research" exists but "Studies" doesn't, it will create both "Studies" and "2024".

move_note

Move a note to a new location, optionally with a new name.

Parameters:

  • source_path: Current path of the note

  • destination_path: New path for the note (can include new filename)

  • update_links (default: true): Update links if filename changes

Features:

  • Can move to a different folder: move_note("Inbox/Note.md", "Archive/Note.md")

  • Can move AND rename: move_note("Inbox/Old.md", "Archive/New.md")

  • Automatically detects if filename changes and updates all wiki-style links

  • No link updates needed for simple folder moves (Obsidian links work by name)

  • Preserves link aliases when updating

Returns:

{
  "success": true,
  "source": "Inbox/Quick Note.md",
  "destination": "Projects/Project Plan.md",
  "renamed": true,
  "details": {
    "links_updated": 5,
    "notes_updated": 3
  }
}

rename_note

Rename a note and automatically update all references to it throughout your vault.

Parameters:

  • old_path: Current path of the note

  • new_path: New path for the note (must be in same directory)

  • update_links (default: true): Automatically update all wiki-style links

Returns:

{
  "success": true,
  "old_path": "Projects/Old Name.md",
  "new_path": "Projects/New Name.md",
  "operation": "renamed",
  "details": {
    "links_updated": 12,
    "notes_updated": 8,
    "link_update_details": [
      {"note": "Daily/2024-01-15.md", "updates": 2},
      {"note": "Ideas/Related.md", "updates": 1}
    ]
  }
}

Features:

  • Automatically finds and updates all [[wiki-style links]] to the renamed note

  • Preserves link aliases (e.g., [[Old Name|Display Text]] → [[New Name|Display Text]])

  • Handles various link formats: [[Note]], [[Note.md]], [[Note|Alias]]

  • Shows which notes were updated for transparency

  • Can only rename within the same directory (use move_note to change directories)

move_folder

Move an entire folder and all its contents to a new location.

Parameters:

  • source_folder: Current folder path (e.g., "Projects/Old")

  • destination_folder: New folder path (e.g., "Archive/Projects/Old")

  • update_links (default: true): Update links in other notes (future enhancement)

Returns:

{
  "source": "Projects/Completed",
  "destination": "Archive/2024/Projects",
  "moved": true,
  "notes_moved": 15,
  "folders_moved": 3,
  "links_updated": 0
}

add_tags

Add tags to a note's frontmatter.

Parameters:

  • path: Path to the note

  • tags: List of tags to add (without # prefix)

Supports hierarchical tags:

  • Simple tags: ["project", "urgent"]

  • Hierarchical tags: ["project/web", "work/meetings/standup"]

  • Mixed: ["urgent", "project/mobile", "status/active"]

update_tags

Update tags on a note - either replace all tags or merge with existing.

Parameters:

  • path: Path to the note

  • tags: New tags to set (without # prefix)

  • merge (default: false): If true, adds to existing tags. If false, replaces all tags

Perfect for AI workflows:

User: "Tell me what this note is about and add appropriate tags"
AI: [reads note] "This note is about machine learning research..."
AI: [uses update_tags to set tags: ["ai", "research", "neural-networks"]]

remove_tags

Remove tags from a note's frontmatter.

Parameters:

  • path: Path to the note

  • tags: List of tags to remove

batch_update_properties

Batch update properties across multiple notes.

Parameters:

  • search_criteria: How to find notes - must include one of:

    • query: Search query string (e.g., "tag:project status:active")

    • folder: Folder path with optional recursive flag

    • files: Explicit list of file paths

  • property_updates (optional): Properties to add/update in frontmatter

  • properties_to_remove (optional): List of property names to remove

  • add_tags (optional): Tags to add (additive)

  • remove_tags (optional): Tags to remove

  • remove_inline_tags (default: false): Also remove tags from note body

Examples:

# Archive completed projects
{
  "search_criteria": {"query": "tag:project status:completed"},
  "property_updates": {"archived": true, "year": 2024},
  "add_tags": ["archived"]
}

# Remove draft tags everywhere
{
  "search_criteria": {"query": "tag:draft"},
  "remove_tags": ["draft"],
  "remove_inline_tags": true
}

Returns:

{
  "total_notes": 10,
  "updated": 8,
  "failed": 2,
  "details": [...],
  "errors": [...]
}

get_note_info

Get metadata and statistics about a note without retrieving its full content.

Parameters:

  • path: Path to the note

Returns:

{
  "path": "Projects/AI Research.md",
  "exists": true,
  "metadata": {
    "tags": ["ai", "research"],
    "aliases": [],
    "frontmatter": {}
  },
  "stats": {
    "size_bytes": 4523,
    "word_count": 823,
    "link_count": 12
  }
}

Image Management

read_image

View an image from your vault. Images are automatically resized to a maximum width of 800px for optimal display in Claude Desktop.

Parameters:

  • path: Path to the image file (e.g., "Attachments/screenshot.png")

Returns:

  • A resized image object that can be viewed directly in Claude Desktop

Supported formats:

  • PNG, JPG/JPEG, GIF, BMP, WebP

view_note_images

Extract and view all images embedded in a note.

Parameters:

  • path: Path to the note containing images

Returns:

{
  "note_path": "Projects/Design Mockups.md",
  "image_count": 3,
  "images": [
    {
      "path": "Attachments/mockup1.png",
      "alt_text": "Homepage design",
      "image": "<FastMCP Image object>"
    }
  ]
}

Use cases:

  • Analyze screenshots and diagrams in your notes

  • Review design mockups and visual documentation

  • Extract visual information for AI analysis

list_tags

List all unique tags used across your vault with usage statistics.

Parameters:

  • include_counts (default: true): Include usage count for each tag

  • sort_by (default: "name"): Sort by "name" or "count"

  • include_files (default: false): Include list of file paths that contain each tag

Returns:

{
  "items": [
    {
      "name": "project", 
      "count": 42,
      "files": ["Projects/Web.md", "Projects/Mobile.md"]  // if include_files=true
    },
    {"name": "meeting", "count": 38},
    {"name": "idea", "count": 15}
  ],
  "total": 25,
  "scope": {"include_counts": true, "sort_by": "name", "include_files": false}
}

Note: Hierarchical tags are listed as separate entries, showing both parent and full paths.

Performance Notes:

  • Fast for small vaults (<1000 notes)

  • May take several seconds for large vaults

  • Uses concurrent batching for optimization

⚔ Performance Note: Link management tools have been heavily optimized in v1.1.5:

  • 84x faster link validity checking

  • 96x faster broken link detection

  • 2x faster backlink searches

  • Includes automatic caching and batch processing

find_orphaned_notes

Find notes that may need organization or cleanup based on various criteria.

Parameters:

  • orphan_type (default: "no_backlinks"): Criteria for identifying orphaned notes

    • "no_backlinks": Notes with no incoming links (most common)

    • "no_links": Notes with no incoming OR outgoing links

    • "no_tags": Notes without any tags

    • "no_metadata": Notes with minimal/no frontmatter properties

    • "isolated": Notes with no links AND no tags

  • exclude_folders (optional): List of folders to exclude (default: ["Templates", "Archive", "Daily"])

  • min_age_days (optional): Only include notes older than this many days

Returns:

{
  "count": 23,
  "orphaned_notes": [
    {
      "path": "Random Thoughts/Old Idea.md",
      "reason": "No incoming links",
      "modified": "2023-06-15T10:30:00Z",
      "size": 245,
      "word_count": 42
    }
  ],
  "stats": {
    "total_notes_scanned": 500,
    "excluded_folders": ["Templates", "Archive", "Daily"],
    "orphan_type": "no_backlinks"
  }
}

Use cases:

  • Regular vault maintenance and cleanup

  • Finding forgotten or disconnected notes

  • Identifying notes that need better organization

  • Preparing for vault reorganization

Find all notes that link to a specific note.

Parameters:

  • path: Path to the note to find backlinks for

  • include_context (default: true): Whether to include text context around links

  • context_length (default: 100): Number of characters of context to include

Returns:

{
  "target_note": "Projects/AI Research.md",
  "backlink_count": 5,
  "backlinks": [
    {
      "source_path": "Daily/2024-01-15.md",
      "link_text": "AI Research",
      "link_type": "wiki",
      "context": "...working on the [[AI Research]] project today..."
    }
  ]
}

Use cases:

  • Understanding which notes reference a concept or topic

  • Discovering relationships between notes

  • Building a mental map of note connections

List all links from a specific note.

Parameters:

  • path: Path to the note to extract links from

  • check_validity (default: false): Whether to check if linked notes exist

Returns:

{
  "source_note": "Projects/Overview.md",
  "link_count": 8,
  "links": [
    {
      "path": "Projects/AI Research.md",
      "display_text": "AI Research",
      "type": "wiki",
      "exists": true
    }
  ]
}

Use cases:

  • Understanding what a note references

  • Checking note dependencies before moving/deleting

  • Exploring the structure of index or hub notes

Find all broken links in the vault, a specific directory, or a single note.

Parameters:

  • directory (optional): Specific directory to check (defaults to entire vault)

  • single_note (optional): Check only this specific note for broken links

Returns:

{
  "directory": "/",
  "broken_link_count": 3,
  "affected_notes": 2,
  "broken_links": [
    {
      "source_path": "Projects/Overview.md",
      "broken_link": "Projects/Old Name.md",
      "link_text": "Old Project",
      "link_type": "wiki"
    }
  ]
}

Use cases:

  • After renaming or deleting notes

  • Regular vault maintenance

  • Before reorganizing folder structure

Testing

Running Tests

# Run all tests
python tests/run_tests.py

# Or with pytest directly
pytest tests/

Tests create temporary vaults for isolation and don't require a running Obsidian instance.

Testing with MCP Inspector

  1. Set your vault path:

    export OBSIDIAN_VAULT_PATH="/path/to/your/vault"
  2. Run the MCP Inspector:

    npx @modelcontextprotocol/inspector python -m obsidian_mcp.server
  3. Open the Inspector UI at http://localhost:5173

  4. Test the tools interactively with your actual vault

Integration with Claude Desktop

For development installations, see the Development Installation section above.

Enhanced Error Handling

The server provides detailed, actionable error messages to help AI systems recover from errors:

Example Error Messages

Invalid Path:

Invalid note path: '../../../etc/passwd'. 
Valid paths must: 1) End with .md or .markdown, 2) Use forward slashes (e.g., 'folder/note.md'), 
3) Not contain '..' or start with '/', 4) Not exceed 255 characters. 
Example: 'Daily/2024-01-15.md' or 'Projects/My Project.md'

Empty Search Query:

Search query cannot be empty. 
Valid queries: 1) Keywords: 'machine learning', 
2) Tags: 'tag:#project', 3) Paths: 'path:Daily/', 
4) Combined: 'tag:#urgent TODO'

Invalid Date Parameters:

Invalid date_type: 'invalid'. 
Must be either 'created' or 'modified'. 
Use 'created' to find notes by creation date, 'modified' for last edit date

Troubleshooting

"Vault not found" error

  • Ensure the OBSIDIAN_VAULT_PATH environment variable is set correctly

  • Verify the path points to an existing Obsidian vault directory

  • Check that you have read/write permissions for the vault directory

Tags not showing up

  • Ensure tags are properly formatted (with or without # prefix)

  • Tags in frontmatter should be in YAML array format: tags: [tag1, tag2]

  • Inline tags should use the # prefix: #project #urgent

  • Tags inside code blocks are automatically excluded

"File too large" error

  • The server has a 10MB limit for note files and 50MB for images

  • This prevents memory issues with very large files

  • Consider splitting large notes into smaller ones

"Module not found" error

  • Ensure your virtual environment is activated

  • Run from the project root: python -m obsidian_mcp.server

  • Verify all dependencies are installed: pip install -r requirements.txt

Empty results when listing notes

  • Specify a directory when using list_notes (e.g., "Daily", "Projects")

  • Root directory listing requires recursive implementation

  • Check if notes are in subdirectories

Tags not updating

  • Ensure notes have YAML frontmatter section for frontmatter tags

  • Frontmatter must include a tags: field (even if empty)

  • The server now properly reads both frontmatter tags and inline hashtags

Best Practices for AI Assistants

Preventing Data Loss

  1. Always read before updating: The update_note tool REPLACES content by default

  2. Use append mode for additions: When adding to existing notes, use merge_strategy="append"

  3. Check note existence: Use read_note to verify a note exists before modifying

  4. Be explicit about overwrites: Only use overwrite=true when intentionally replacing content

Safe note editing:

  1. Read the existing note first

  2. Modify the content as needed

  3. Update with the complete new content

Adding to daily notes:

  • Use merge_strategy="append" to add entries without losing existing content

  • Use edit_note_section to add content to specific sections (like "## Tasks" or "## Notes")

Creating new notes:

  • Use create_note with overwrite=false (default) to prevent accidental overwrites

  • Add relevant tags to maintain organization

  • Use list_tags to see existing tags and avoid creating duplicates

Organizing with tags:

  • Check existing tags with list_tags before creating new ones

  • Maintain consistent naming (e.g., use "project" not "projects")

  • Use tags to enable powerful search and filtering

Security Considerations

  • Vault path access - The server only accesses the specified vault directory

  • The server validates all paths to prevent directory traversal attacks

  • File operations are restricted to the vault directory

  • Large files are rejected to prevent memory exhaustion

  • Path validation prevents access to system files

Development

Code Style

  • Uses FastMCP framework for MCP implementation

  • Pydantic models for type safety and validation

  • Modular architecture with separated concerns

  • Comprehensive error handling and user-friendly messages

Adding New Tools

  1. Create tool function in appropriate module under src/tools/

  2. Add Pydantic models if needed in src/models/

  3. Register the tool in src/server.py with the @mcp.tool() decorator

  4. Include comprehensive docstrings

  5. Add tests in tests/

  6. Test with MCP Inspector before deploying

Changelog

v2.1.6 (2025-01-30)

  • šŸ” Find orphaned notes - New find_orphaned_notes tool for comprehensive vault maintenance

    • Multiple orphan criteria: no backlinks, no links, no tags, no metadata, or isolated notes

    • Configurable folder exclusions and age filtering

    • Returns detailed statistics including size and word count for each orphaned note

    • Helps identify forgotten or disconnected notes that need organization

  • šŸ› Bug fixes:

    • Fixed JSON string parsing for tag parameters in multiple tools

    • Fixed various errors in find_orphaned_notes implementation

v2.1.5 (2025-01-30)

  • šŸ” New find_orphaned_notes tool - Find notes that need organization

    • Multiple criteria: no backlinks, no links, no tags, no metadata, or isolated

    • Smart defaults exclude Templates, Archive, and Daily folders

    • Optional age filtering to exclude recent work-in-progress notes

    • Returns paths, reasons, and metadata for each orphaned note

v2.1.4 (2025-01-30)

  • šŸ” Enhanced default search - Search now automatically includes both filename AND content matches

    • Filename matches are ranked higher for intuitive "find note by name" behavior

    • No more need to use path: prefix for common searches

    • Added match_type field to distinguish filename vs content matches

  • šŸ› Fixed quote validation - Notes with quotes in filenames now work correctly

v2.1.3 (2025-01-30)

  • šŸ·ļø Enhanced list_tags - Added include_files option to get all files containing each tag

  • šŸ”§ Fixed update_tags - Properly handles bullet list YAML format without creating malformed frontmatter

  • šŸš€ Batch update properties - New batch_update_properties tool for bulk metadata operations

    • Update any frontmatter property across multiple notes

    • Add/remove tags with optional inline tag removal from note body

    • Search by query, folder, or explicit file list

    • Proper YAML structure preservation

  • 🧹 Code cleanup - Removed deprecated OBSIDIAN_REST_API_KEY references from codebase

  • šŸ“ Better error messages - More actionable feedback following MCP best practices

v2.0.3 (2025-01-24)

  • āœļø Section-based editing - New edit_note_section tool for precise content insertion and updates

  • šŸŽÆ Four edit operations - Insert before/after headings, replace sections, or append to section ends

  • šŸ“ Smart section detection - Case-insensitive markdown heading matching with hierarchy support

  • šŸ”§ Create missing sections - Optionally create sections if they don't exist

  • šŸ“ Preserve note structure - Edit specific parts without rewriting entire notes

v2.0.2 (2025-01-24)

  • šŸŽÆ Simplified architecture - Removed memory index, SQLite is now the only search method

  • šŸ” Search transparency - Added metadata to search results (total_count, truncated, limit)

  • āš™ļø Configurable search limits - Exposed max_results parameter (1-500, default 50)

  • 🧹 Reduced tool clutter - Removed unnecessary index management tools

  • šŸ“ Reasoning-friendly improvements - Enhanced all tools with proper Field annotations and comprehensive docstrings

  • šŸš€ Better AI reasoning - Added "When to use" and "When NOT to use" sections to all tools

  • ⚔ Performance notes - Added explicit performance guidance for expensive operations

  • šŸ”§ Cleaner codebase - Removed ~500 lines of memory index code, reducing maintenance burden

v2.0.0 (2025-01-24)

  • šŸš€ Complete architecture overhaul - Migrated from REST API to direct filesystem access

  • ⚔ 5x faster searches with persistent SQLite indexing that survives between sessions

  • šŸ–¼ļø Image support - View and analyze images from your vault with automatic resizing

  • šŸ” Regex power search - Find complex patterns with optimized streaming

  • šŸ—‚ļø Property search - Query notes by frontmatter properties with advanced operators

  • šŸŽÆ One-command setup - Auto-configure Claude Desktop with uvx --from obsidian-mcp obsidian-mcp-configure

  • šŸ“¦ 90% less memory usage - Efficient streaming architecture

  • šŸ”„ No plugins required - Works offline without needing Obsidian to be running

  • ✨ Incremental indexing - Only re-indexes changed files

  • šŸ”§ Migration support - Automatically detects and migrates old REST API configs

  • šŸ·ļø Enhanced hierarchical tag support - Full support for Obsidian's nested tag system

    • Search parent tags to find all children (e.g., tag:project finds project/web)

    • Search child tags across any hierarchy (e.g., tag:web finds project/web, design/web)

    • Exact hierarchical matching (e.g., tag:project/web)

  • šŸ” Improved metadata handling - Better alignment with Obsidian's property system

    • Automatic migration of legacy properties (tag→tags, alias→aliases)

    • Array/list property searching (find items within arrays)

    • Date property comparisons with ISO format support

    • Numeric comparisons for array lengths

  • šŸ“ AI-friendly tool definitions - Updated all tool descriptions for better LLM understanding

    • Added hierarchical tag examples to all tag-related tools

    • Enhanced property search documentation

    • Clearer parameter descriptions following MCP best practices

v1.1.8 (2025-01-15)

  • šŸ”§ Fixed FastMCP compatibility issue that prevented PyPI package from running

  • šŸ“¦ Updated to FastMCP 2.8.1 for better stability

  • šŸ› Fixed Pydantic V2 deprecation warnings (migrated to @field_validator)

  • ✨ Changed FastMCP initialization to use 'instructions' parameter

  • šŸš€ Improved compatibility with uvx and pipx installation methods

v1.1.7 (2025-01-10)

  • šŸ”„ Changed default API endpoint to HTTP (http://127.0.0.1:27123) for easier setup

  • šŸ“ Updated documentation to reflect HTTP as default, HTTPS as optional

  • šŸ”§ Added note about automatic trailing slash handling in URLs

  • ✨ Improved first-time user experience with zero-configuration setup

v1.1.6 (2025-01-10)

  • šŸ› Fixed timeout errors when creating or updating large notes

  • ⚔ Added graceful timeout handling for better reliability with large content

  • šŸ”§ Improved error reporting to prevent false failures on successful operations

v1.1.5 (2025-01-09)

  • ⚔ Massive performance optimization for link management:

    • 84x faster link validity checking

    • 96x faster broken link detection

    • 2x faster backlink searches

    • Added automatic caching and batch processing

  • šŸ”§ Optimized concurrent operations for large vaults

  • šŸ“ Enhanced documentation for performance considerations

v1.1.4 (2025-01-09)

  • šŸ”— Added link management tools for comprehensive vault analysis:

    • get_backlinks - Find all notes linking to a specific note

    • get_outgoing_links - List all links from a note with validity checking

    • find_broken_links - Identify broken links for vault maintenance

  • šŸ”§ Fixed URL construction to support both HTTPS (default) and HTTP endpoints

  • šŸ“ Enhanced link parsing to handle both wiki-style and markdown links

  • ⚔ Optimized backlink search to handle various path formats

v1.1.3 (2025-01-09)

  • šŸ› Fixed search_by_date to properly find notes modified today (days_ago=0)

  • ✨ Added list_folders tool for exploring vault folder structure

  • ✨ Added create_folder tool that creates full folder hierarchies

  • ✨ Added move_folder tool for bulk folder operations

  • ✨ Added update_tags tool for AI-driven tag management

  • šŸ› Fixed tag reading to properly handle both frontmatter and inline hashtags

  • ✨ Added list_tags tool to discover existing tags with usage statistics

  • ⚔ Optimized performance with concurrent batching for large vaults

  • šŸ“ Improved documentation and error messages following MCP best practices

  • šŸŽÆ Enhanced create_note to encourage tag usage for better organization

v1.1.2 (2025-01-09)

  • Fixed PyPI package documentation

v1.1.1 (2025-01-06)

  • Initial PyPI release

Publishing (for maintainers)

To publish a new version to PyPI:

# 1. Update version in pyproject.toml
# 2. Clean old builds
rm -rf dist/ build/ *.egg-info/

# 3. Build the package
python -m build

# 4. Check the package
twine check dist/*

# 5. Upload to PyPI
twine upload dist/* -u __token__ -p $PYPI_API_KEY

# 6. Create and push git tag
git tag -a v2.0.2 -m "Release version 2.0.2"
git push origin v2.0.2

Users can then install and run with:

# Using uvx (recommended - no installation needed)
uvx obsidian-mcp

# Or install globally with pipx
pipx install obsidian-mcp
obsidian-mcp

# Or with pip
pip install obsidian-mcp
obsidian-mcp

Configuration

Performance and Indexing

The server now includes a persistent search index using SQLite for dramatically improved performance:

Key Features:

  • Instant startup - No need to rebuild index on every server start

  • Incremental updates - Only re-indexes files that have changed

  • 60x faster searches - SQLite queries are much faster than scanning all files

  • Lower memory usage - Files are loaded on-demand rather than all at once

Configuration Options:

Set these environment variables to customize behavior:

# Set logging level (default: INFO, options: DEBUG, INFO, WARNING, ERROR)
export OBSIDIAN_LOG_LEVEL=DEBUG

The search index is stored in your vault at .obsidian/mcp-search-index.db.

Performance Notes

  • Search indexing - With persistent index, only changed files are re-indexed

  • Concurrent operations - File operations use async I/O for better performance

  • Large vaults - Incremental indexing makes large vaults (10,000+ notes) usable

  • Image handling - Images are automatically resized to prevent memory issues

Migration from REST API Version

If you were using a previous version that required the Local REST API plugin:

  1. You no longer need the Obsidian Local REST API plugin - This server now uses direct filesystem access

  2. Replace OBSIDIAN_REST_API_KEY with OBSIDIAN_VAULT_PATH in your configuration

  3. Remove any OBSIDIAN_API_URL settings

  4. The new version is significantly faster and more reliable

  5. All features work offline without requiring Obsidian to be running

Contributing

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/amazing-tool)

  3. Write tests for new functionality

  4. Ensure all tests pass

  5. Commit your changes (git commit -m 'Add amazing tool')

  6. Push to the branch (git push origin feature/amazing-tool)

  7. Open a Pull Request

License

MIT License - see LICENSE file for details

Acknowledgments

  • Anthropic for creating the Model Context Protocol

  • Obsidian team for the amazing note-taking app

  • coddingtonbear for the original Local REST API plugin (no longer required)

  • dsp-ant for the FastMCP framework

Available Tools

27 tools
add_tags_toolA

Add tags to a note's frontmatter.

When to use:

  • Organizing notes with tags

  • Creating hierarchical tag structures (e.g., project/web, work/meetings/standup)

  • Bulk tagging operations

  • Adding metadata for search

Tag format:

  • Simple tags: "project", "urgent"

  • Hierarchical tags: "project/web", "work/meetings/standup"

  • Tags are automatically added without duplicates

When NOT to use:

  • Adding tags in note content (use update_note)

  • Replacing all tags (use update_tags with merge=False)

Returns: Updated tag list for the note

Inputs: path (required), tags (required), ctx.

batch_update_properties_toolA

Batch update properties across multiple notes.

When to use:

  • Updating metadata across many notes (status, priority, etc.)

  • Bulk tag operations (add/remove tags from multiple notes)

  • Archiving projects (set archived=true, add year property)

  • Cleaning up properties (remove outdated fields)

  • Normalizing metadata across your vault

Search criteria options:

  • query: Use search syntax (tag:project, folder:Archive, property:status:active)

  • folder: Process all notes in a folder (with optional recursive flag)

  • files: Explicit list of file paths

Property operations:

  • Add/update any frontmatter property

  • Remove properties by name

  • Special handling for tags (add/remove with deduplication)

  • Remove inline #tags from note body (optional)

Examples:

  • Archive completed projects: query="tag:project status:completed", property_updates={"archived": true, "year": 2024}

  • Clean up draft tags: query="tag:draft", remove_tags=["draft"], remove_inline_tags=true

  • Update all notes in folder: folder="Projects/2023", property_updates={"year": 2023}

When NOT to use:

  • Single note updates (use update_note, add_tags, etc.)

  • Complex content changes (this only updates frontmatter)

Returns: { "total_notes": 10, # Total notes found matching criteria "updated": 8, # Successfully updated notes "failed": 2, # Failed updates "details": [...], # List of changes per note "errors": [...] # List of errors with paths and reasons }

Inputs: search_criteria (required), property_updates, properties_to_remove, add_tags, +3 more.

create_folder_toolA

Create a new folder in the vault, including all parent folders in the path.

When to use:

  • Setting up project structure in advance

  • Creating deep folder hierarchies (e.g., "Research/Studies/2024")

  • Creating archive folders before moving notes

  • Establishing organizational hierarchy

  • Preparing folders for future content

When NOT to use:

  • If you're about to create a note in that path (folders are created automatically)

  • For temporary organization (just create notes directly)

Note: Will create all necessary parent folders. For example, "Research/Studies/2024" will create Research, Research/Studies, and Research/Studies/2024 if they don't exist.

Returns: Creation status with list of folders created and placeholder file path

Inputs: folder_path (required), create_placeholder, ctx.

create_note_toolA

Create a new note or overwrite an existing one.

When to use:

  • Creating new notes with specific content

  • Setting up templates or structured notes

  • Programmatically generating documentation

When NOT to use:

  • Updating existing notes (use update_note unless you want to replace entirely)

  • Appending content (use update_note with merge_strategy="append")

Returns: Created note information with path and metadata

Inputs: path (required), content (required), overwrite, ctx.

delete_note_toolA

Delete a note from the vault permanently.

When to use:

  • Removing outdated or duplicate notes

  • Cleaning up temporary drafts

  • Part of a move operation (delete after successful copy)

When NOT to use:

  • Archiving (use move_note to Archive folder instead)

  • Temporary removal (no undo available)

āš ļø WARNING: This operation cannot be undone. The note will be permanently deleted.

Returns: Deletion confirmation with the path of the deleted note

Inputs: path (required), ctx.

edit_note_section_toolA

Edit a specific section of a note identified by a markdown heading.

When to use:

  • Adding content to a specific section without rewriting the whole note

  • Updating a particular section (like status updates, task lists)

  • Inserting content at precise locations in structured notes

  • Building up notes incrementally by section

When NOT to use:

  • Simple append to end of note (use update_note with merge_strategy='append')

  • Replacing entire note content (use update_note)

  • Creating a new note (use create_note)

Section identification:

  • Sections are identified by markdown headings (# ## ### etc.)

  • Match is case-insensitive

  • First matching heading is used if duplicates exist

  • Section includes content until next heading of same/higher level

Operations:

  • insert_after: Add content immediately after the section heading

  • insert_before: Add content immediately before the section heading

  • replace: Replace entire section including the heading

  • append_to_section: Add content at the end of the section

Returns: Edit status including whether section was found or created

Inputs: path (required), section_identifier (required), content (required), operation, +2 more.

find_orphaned_notes_toolA

Find orphaned notes that may need organization or cleanup.

When to use:

  • Regular vault maintenance and cleanup

  • Finding forgotten or disconnected notes

  • Identifying notes that need better organization

  • Preparing for vault reorganization

  • Finding candidates for archival or deletion

Orphan types explained:

  • no_backlinks: Notes with no incoming links (most common definition)

  • no_links: Notes with no incoming OR outgoing links (completely isolated)

  • no_tags: Notes without any tags (untagged content)

  • no_metadata: Notes with minimal/no frontmatter properties

  • isolated: Notes with no links AND no tags (truly disconnected)

Default exclusions:

  • Templates folder (usually contains reference notes)

  • Archive folder (already organized)

  • Daily folder (daily notes often standalone)

When NOT to use:

  • Finding specific notes (use search_notes)

  • Getting all notes in a folder (use list_notes)

  • Finding notes by content (use search tools)

Performance note:

  • Scans entire vault and checks links/metadata for each note

  • For vaults >1000 notes, this may take 10-30 seconds

Returns: List of orphaned notes with paths, reasons, and metadata. Results are sorted by modification date (oldest first).

Example response: { "count": 23, "orphaned_notes": [ { "path": "Random Thoughts/Old Idea.md", "reason": "No incoming links", "modified": "2023-06-15T10:30:00Z", "size": 245, "word_count": 42 } ], "stats": { "total_notes_scanned": 500, "excluded_folders": ["Templates", "Archive", "Daily"], "orphan_type": "no_backlinks" } }

Inputs: orphan_type, exclude_folders, min_age_days, ctx.

get_note_info_toolA

Get metadata and statistics about a note without reading its content.

When to use:

  • Checking note properties quickly (tags, dates, size)

  • Getting frontmatter without loading content

  • Gathering statistics (word count, link count)

  • Verifying note exists and getting basic info

  • Batch processing note metadata

When NOT to use:

  • Reading note content (use read_note)

  • Searching for notes (use search tools)

  • Modifying metadata (use specific update tools)

Returns: Note metadata including path, existence, dates, size, frontmatter properties, and statistics (word count, link count, tag count, image presence)

Inputs: path (required), ctx.

list_folders_toolA

List folders in the vault or a specific directory.

When to use:

  • Exploring vault organization structure

  • Verifying folder names before creating notes

  • Checking if a specific folder exists

  • Understanding the hierarchy of the vault

When NOT to use:

  • Listing notes (use list_notes instead)

  • Searching for content (use search_notes)

Returns: Folder structure with paths and names

Inputs: directory, recursive, ctx.

list_notes_toolA

List notes in the vault or a specific directory.

When to use:

  • Getting an overview of vault structure

  • Finding notes in a specific folder

  • Checking what notes exist before bulk operations

  • Understanding vault organization

When NOT to use:

  • Searching for specific content (use search_notes)

  • Finding notes by properties (use search_by_property)

  • Just counting notes (this loads full paths)

Performance notes:

  • Fast for directories with <100 notes

  • May be slower for large vaults (1000+ notes) with recursive=True

Returns: Hierarchical structure of notes with paths and folder organization

Inputs: directory, recursive, ctx.

list_tags_toolA

List all unique tags used across the vault with usage statistics.

When to use:

  • Before adding tags to maintain consistency

  • Getting an overview of your tagging taxonomy

  • Finding underused or overused tags

  • Discovering tag variations (e.g., 'project' vs 'projects')

  • Understanding hierarchical tag structures in your vault

  • Finding all files that use a specific tag (with include_files=true)

Hierarchical tags:

  • Lists both parent and full hierarchical paths (e.g., both "project" and "project/web")

  • Shows how nested tags are organized in your vault

  • Helps identify opportunities for better tag organization

File paths (with include_files=true):

  • Returns a list of all file paths that contain each tag

  • Useful for bulk operations on files with specific tags

  • Paths are relative to vault root

When NOT to use:

  • Getting tags for a specific note (use get_note_info)

  • Searching notes by tag (use search_notes with tag: prefix)

Performance note:

  • For vaults with <1000 notes: Fast (1-3 seconds)

  • For vaults with 1000-5000 notes: Moderate (3-10 seconds)

  • For vaults with >5000 notes: May be slow (10+ seconds)

  • Uses batched concurrent requests to optimize performance

  • include_files=true adds minimal overhead

Returns: All unique tags with optional usage counts and file paths

Inputs: include_counts, sort_by, include_files, ctx.

move_folder_toolA

Move an entire folder and all its contents to a new location.

When to use:

  • Reorganizing vault structure

  • Archiving completed projects

  • Consolidating related notes

  • Seasonal organization (e.g., moving to year-based archives)

When NOT to use:

  • Moving individual notes (use move_note instead)

  • Moving to a subfolder of the source (creates circular reference)

Returns: Move status with count of notes and folders moved

Inputs: source_folder (required), destination_folder (required), update_links, ctx.

move_note_toolA

Move a note to a new location, optionally with a new name.

When to use:

  • Reorganizing notes into different folders

  • Moving AND renaming in one operation

  • Archiving completed projects

  • Consolidating scattered notes

When NOT to use:

  • Just renaming within same folder (use rename_note for clarity)

  • Copying notes (use read_note + create_note instead)

  • Moving entire folders (use move_folder)

Link updating:

  • Automatically detects if filename changes during move

  • Updates all [[wiki-style links]] only when name changes

  • Preserves link aliases and formatting

  • No updates needed for simple folder moves (links work by name)

Returns: Move confirmation with path changes and link update details

Inputs: source_path (required), destination_path (required), update_links, ctx.

read_image_toolA

Read an image file from the Obsidian vault for analysis.

When to use:

  • Analyzing specific image files from the vault

  • Examining standalone images (not embedded in notes)

  • Processing images for detailed analysis

When NOT to use:

  • Getting images embedded in notes (use view_note_images instead)

  • Searching for images (use list_notes with appropriate filters)

Returns: Image object that Claude can analyze and describe

Inputs: path (required), include_metadata, ctx.

read_note_toolA

Read the content and metadata of a specific note.

When to use:

  • Displaying note contents to the user

  • Analyzing or processing existing note data

  • ALWAYS before updating a note to preserve existing content

  • Verifying a note exists before making changes

When NOT to use:

  • Searching multiple notes (use search_notes instead)

  • Getting only metadata (use get_note_info for efficiency)

  • Viewing images in a note (use view_note_images instead)

Returns: Note content and metadata including tags, aliases, and frontmatter. Image references (alt) are preserved in the content but images are not loaded.

IMPORTANT: If the note contains image references, proactively offer to analyze them: "I can see this note contains [N] images. Would you like me to analyze/examine them for you?" Then use view_note_images to load and analyze the images if requested.

Inputs: path (required), ctx.

remove_tags_toolA

Remove specific tags from a note's frontmatter.

When to use:

  • Cleaning up outdated tags

  • Removing temporary tags (like 'draft' or 'review')

  • Tag maintenance and reorganization

  • After completing tagged tasks

When NOT to use:

  • Removing all tags (use update_tags with empty list)

  • Replacing tags (use update_tags with merge=False)

Note: Only removes exact matches. To remove all subtags of a hierarchical tag, list them explicitly or use update_tags.

Returns: Updated tag list after removal, with count of removed tags

Inputs: path (required), tags (required), ctx.

rename_note_toolA

Rename a note and automatically update all references to it.

When to use:

  • Changing a note's title to better reflect its content

  • Fixing typos in note names

  • Standardizing naming conventions

  • Updating temporary names to permanent ones

When NOT to use:

  • Moving notes to different folders (use move_note)

  • Creating a copy with new name (use read_note + create_note)

Important:

  • Can only rename within the same directory

  • Automatically updates all [[wiki-style links]] throughout vault

  • Preserves link aliases like [[old name|display text]]

  • Shows which notes were updated for transparency

Returns: Rename confirmation with link update details

Inputs: old_path (required), new_path (required), update_links, ctx.

search_by_date_toolA

Search for notes by creation or modification date.

When to use:

  • Finding recently modified notes

  • Locating notes created in a specific time period

  • Reviewing activity from specific dates

When NOT to use:

  • Content-based search (use search_notes)

  • Finding notes by tags or path (use search_notes)

Returns: Notes matching the date criteria with paths and timestamps

Inputs: date_type, days_ago, operator, ctx.

search_by_property_toolA

Search for notes by their frontmatter property values.

When to use:

  • Finding notes with specific metadata (status, priority, etc.)

  • Filtering by numeric properties (rating > 4, priority <= 2)

  • Filtering by date properties (deadline < "2024-12-31")

  • Searching within array/list properties (tags, aliases, categories)

  • Checking which notes have certain properties defined

  • Building database-like queries on your notes

Property types supported:

  • Text/String: Exact match or contains

  • Numbers: Comparison operators work numerically

  • Dates: ISO format (YYYY-MM-DD) with intelligent comparison

  • Arrays/Lists: Searches within list items, comparisons use list length

  • Legacy properties: Automatically handles tag→tags, alias→aliases migrations

When NOT to use:

  • Content search (use search_notes instead)

  • Tag search (use search_notes with tag: prefix)

  • Path/filename search (use search_notes with path: prefix)

Examples:

  • Find active projects: property_name="status", value="active"

  • Find high priority: property_name="priority", operator=">", value="2"

  • Find notes with deadlines: property_name="deadline", operator="exists"

  • Find notes by author: property_name="author", operator="contains", value="john"

  • Find notes with tag in list: property_name="tags", value="project"

  • Find past deadlines: property_name="due_date", operator="<", value="2024-01-01"

Returns: Notes matching the property criteria with values displayed

Inputs: property_name (required), value, operator, context_length, +1 more.

search_by_regex_toolA

Search for notes using regular expressions for advanced pattern matching.

When to use:

  • Finding complex patterns (URLs, code syntax, structured data)

  • Searching with wildcards and special characters

  • Case-sensitive or multi-line pattern matching

  • Finding TODO/FIXME comments with context

When NOT to use:

  • Simple text search (use search_notes instead)

  • Searching by tags or properties (use dedicated tools)

Common patterns:

  • URLs: r"https?://[^\s]+"

  • Email: r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}"

  • TODO comments: r"(TODO|FIXME)\s*:.*"

  • Markdown headers: r"^#{1,6}\s+.*"

  • Code blocks: r"\w*\n[\s\S]*?"

Returns: Notes containing regex matches with match details and context

Inputs: pattern (required), flags, context_length, max_results, +1 more.

search_notes_toolA

Search for notes by filename or content, with smart ranking.

DEFAULT BEHAVIOR (NEW): Searches BOTH note filenames AND content automatically. Filename matches are ranked higher than content matches for better discovery.

When to use:

  • Finding a note when you know part of its name (just type the name)

  • Finding notes containing specific content

  • Locating notes with specific tags

  • Searching within specific folders

  • Finding notes by frontmatter properties

Search modes:

  • Default: searches BOTH filenames and content (filename matches ranked higher) Example: "tag refactor" finds "Obsidian Tag Refactor.md" AND notes mentioning "tag refactor"

  • "path:text" - searches ONLY in filenames/paths

  • "tag:tagname" - searches by tag (supports hierarchical tags)

  • "property:name:value" - searches by frontmatter properties

Examples:

  • Find a note by name: "Project Tracker" (will find "Project Tracker.md" first)

  • Search content only: Use explicit path: prefix to exclude: "path:Project"

  • Find by tag: "tag:important" or "tag:project/web"

  • Find by property: "property:status:active"

Tag search supports hierarchical tags:

  • "tag:project" finds all project-related tags including project/web, project/mobile

  • "tag:web" finds any tag ending with "web" like project/web, design/web

When NOT to use:

  • Searching by date (use search_by_date instead)

  • Listing all notes (use list_notes for better performance)

  • Reading a specific note when you know the exact path (use read_note directly)

Returns: Search results with matched notes, relevance scores, and context. Filename matches have higher scores than content matches. Response includes match_type field: "filename" or "content".

Inputs: query (required), context_length, max_results, ctx.

update_note_toolA

Update the content of an existing note.

āš ļø IMPORTANT: By default, this REPLACES the entire note content. Always read the note first if you need to preserve existing content.

When to use:

  • Updating a note with completely new content (replace)

  • Adding content to the end of a note (append)

  • Programmatically modifying notes

When NOT to use:

  • Making small edits (read first, then update with full content)

  • Creating new notes (use create_note instead)

Returns: Update status with path, metadata, and operation performed

Inputs: path (required), content (required), create_if_not_exists, merge_strategy, +1 more.

update_tags_toolA

Update tags on a note - either replace all tags or merge with existing.

When to use:

  • After analyzing a note's content to suggest relevant tags

  • Reorganizing tags across your vault

  • Setting consistent tags based on note types or projects

  • AI-driven tag suggestions ("What is this note about? Add appropriate tags")

When NOT to use:

  • Just adding a few tags (use add_tags)

  • Just removing specific tags (use remove_tags)

Returns: Previous tags, new tags, and operation performed

Inputs: path (required), tags (required), merge, ctx.

view_note_images_toolA

Extract and analyze images embedded in a note.

When to use:

  • Analyzing images referenced in a note's markdown content

  • Examining visual content within notes (screenshots, diagrams, etc.)

  • Extracting specific images from notes for analysis

When NOT to use:

  • Reading standalone image files (use read_image instead)

  • Getting note content without images (use read_note instead)

Returns: List of Image objects that Claude can analyze and describe

Inputs: path (required), image_index, max_width, ctx.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 27 tools

    Disambiguation4/5

    Most tools have distinct purposes with clear boundaries, such as read_note vs. get_note_info, or add_tags vs. update_tags. However, there is some overlap between search_notes and search_by_property/search_by_date, which could cause confusion about which to use for specific queries, though descriptions help clarify.

    Naming Consistency5/5

    Tool names follow a consistent snake_case pattern with clear verb_noun structures, such as create_note, delete_note, update_note, and search_notes. This predictability makes it easy to understand each tool's function at a glance across the entire set.

    Tool Count3/5

    With 27 tools, the count feels heavy for a note-taking server, though it covers a broad range of operations. While comprehensive, it may overwhelm users with too many specialized tools, such as separate search_by_date and search_by_property tools, where a more unified search could suffice.

    Completeness5/5

    The tool set provides complete CRUD and lifecycle coverage for Obsidian vault management, including note creation, reading, updating, deletion, moving, renaming, tagging, searching, and maintenance tasks like finding broken links or orphaned notes. No obvious gaps exist for the domain.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI assistants to interact with Obsidian vaults, providing tools for reading, creating, editing and managing notes and tags.
      3,585 npm
      750
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with Obsidian vaults through direct filesystem access, supporting note management, lightning-fast search with SQLite indexing, image analysis, tag/link management, and bulk operations.
      MIT
    • F
      license
      Not graded
      quality
      Not graded
      maintenance
      Enables AI assistants to read, write, search, and navigate Obsidian vault notes with support for CRUD operations, full-text search, graph navigation, daily notes, and frontmatter management.
      3,585 npm
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to interact with Obsidian vaults via direct filesystem access for managing notes, folders, and metadata. It features advanced search capabilities and multi-layer caching to provide efficient, real-time access to your personal knowledge base.
      3,585 npm
      MIT