obsidian-index-service
A service that monitors an Obsidian vault for file changes (new, modified, or deleted Markdown files) and indexes each note’s metadata and content into an SQLite database, exposing it for e.g. an MCP-server
Documentation
Obsidian Index Service
This service monitors an Obsidian vault directory and indexes Markdown files—metadata *and* full content—into an SQLite database. I built it to work with my `mcp-server` project, but switched to an implementation that uses the Obsidian plugin API instead. I still see use for this as an agnostic note indexer or sync tool (see note under "Future Steps"), so I'm putting it up here.
Functionality
It tracks file changes (create, modify, delete) in an Obsidian vault and stores everything in SQLite, accessible via a Docker volume. It captures:
- Path: File path (unique identifier)
- Title: From filename
- Parent Folders: Relative to vault root
- Tags: From YAML frontmatter
- Created Date: Filesystem timestamp
- Modified Date: Filesystem timestamp
- Content: Full text of the note
- Status: Processing outcome (success/error)
- Error Message: Details if processing fails
Setup and Usage
Prerequisites
- Python 3.12 or later
- Docker and Docker Compose (for containerized use)
- `uv` (optional, but recommended)
Installation
1. Clone the repo:
git clone https://github.com/pmmvr/obsidian-index-service.git
cd obsidian-index-service2. Set up a virtual environment:
uv venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windowspython -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windows3. Install dependencies:
uv sync # Installs from uv.lock
uv pip install pytest pytest-bdd pytest-mock # For testspip install -e .
pip install pytest pytest-bdd pytest-mock # For testsRunning Locally
Set environment variables:
export OBSIDIAN_VAULT_PATH=/path/to/vault
export DB_PATH=/path/to/notes.sqliteRun it:
python main.pyWith `uv`:
uv run python main.pyFor a one-time scan:
python main.py --scan-onlyOr with `uv`:
uv run python main.py --scan-onlyCommand-Line Options
- `--vault-path`: Path to vault directory
- `--db-path`: Path to SQLite database
- `--scan-only`: Scan without watching
Using Docker
1. Build and run:
docker-compose up -d2. It mounts your vault and exposes the SQLite database.
Read-Only Access for Other Services
To let another service read the database (e.g., for scanning changes):
1. Use the same volume as `obsidian-index-service` in your `docker-compose.yml`:
services:
your-service:
image: your-image
volumes:
- ${DB_VOLUME_PATH:-./data}:/data:ro # Read-only mount2. `Obsidian Index Service` writes to `/data/notes.sqlite` (mounted read-write), while other services (e.g. an mcp-server) read it. SQLite's WAL mode handles concurrent access.
How It Works
The Obsidian Index Service operates through the following process:
1. Startup (`ObsidianIndexService.__init__`)
2. Database Initialization (`DatabaseConnection.__init__`)
3. Initial Vault Scan (`NoteProcessor.scan_vault`)
4. Continuous Monitoring (`FileWatcher.watch`)
5. File Processing (`NoteProcessor.process_note`)
6. Graceful Shutdown (`ObsidianIndexService.shutdown`)
The service operates in the background, continuously keeping the SQLite database in sync with the Obsidian vault. Other applications can then use this database to access note metadata without having to parse Markdown files directly.
Development
Run tests:
pytestProject Status
- Done: Core indexing (metadata + content), Docker setup, file watching, database CRUD.
- Next: Planned an API, but went with the plugin approach instead.
Future Steps (Sync Tool Potential)
With some rework I can see this as a sync tool:
- Remote Backend: Add support for cloud storage (e.g., Dropbox) or a server.
- Sync Logic: Push local changes (content + metadata) to remote, pull remote updates, handle conflicts (e.g., last-write-wins).
- Database Tweaks: Add `sync_status` and `remote_id` columns.
- File Watcher Updates: Queue changes for sync, not just indexing.
- CLI Option: Add `--sync` to trigger it manually or continuously.
- Error Handling: Retry on network fails, log issues.
Frequently asked questions
What is obsidian-index-service?
obsidian-index-service is A service that monitors an Obsidian vault for file changes (new, modified, or deleted Markdown files) and indexes each note’s metadata and content into an SQLite database, exposing it for e.g. an MCP-server
How do I install obsidian-index-service?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is obsidian-index-service open source?
Yes — it is hosted on GitHub at https://github.com/pmmvr/obsidian-index-service and has 5 stars.
Related MCP tools
Damn Vulnerable MCP Server Python-based implementation. Trusted by 1200+ developers. Trusted by 1200+ developers. Trusted by 1200+ developers.
A Model Context Protocol (MCP) server that enables secure interaction with MySQL databases Python-based implementation. Trusted by 900+ developers.
Query MCP enables end-to-end management of Supabase via chat interface: read & write query executions, management API support, automatic migration versioning...
Model Context Protocol with Neo4j Python-based implementation. Trusted by 700+ developers. Trusted by 700+ developers. Trusted by 700+ developers.
An MCP server that provides control over Android devices via adb Python-based implementation. Trusted by 500+ developers.
A Model Context Protocol (MCP) server for PostgreSQL databases with enhanced capabilities for AI agents. Python-based implementation.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP