Navigation
Obsidian Index Service: Real-Time SQLite Sync & MCP Integration - MCP Implementation

Obsidian Index Service: Real-Time SQLite Sync & MCP Integration

Automate Obsidian vault monitoring – index Markdown changes (create/edit/delete) into SQLite for seamless MCP-server integration. Real-time, developer-friendly power.

Developer Tools
4.0(117 reviews)
175 saves
81 comments

37% of users reported increased productivity after just one week

About Obsidian Index Service

What is Obsidian Index Service: Real-Time SQLite Sync & MCP Integration?

Obsidian Index Service is a background utility that monitors an Obsidian vault in real-time, indexing metadata and full-text content from Markdown files into an SQLite database. Originally built to integrate with the mcp-server, it now serves as a versatile note indexer. Its core capabilities include file system event tracking, database synchronization, and compatibility with Docker environments. While currently focused on indexing, future enhancements aim to enable bidirectional sync with remote storage systems.

How to use Obsidian Index Service: Real-Time SQLite Sync & MCP Integration?

Deployment involves three primary methods:

  • Local execution: Clone the repository using git clone https://github.com/pmmvr/obsidian-index-service.git, configure virtual environments via uv or standard Python tools, then run python main.py with environment variables specifying vault and database paths.
  • Docker deployment: Use docker-compose up to containerize the service, automatically handling vault mounting and database persistence.
  • Integration mode: Expose the SQLite database volume to external services like mcp-server using read-only mounts, enabling concurrent access through SQLite's WAL mode.

Optional flags like --scan-only allow single-pass indexing, while command-line parameters override default paths.

Obsidian Index Service Features

Key Features of Obsidian Index Service: Real-Time SQLite Sync & MCP Integration?

Core functionalities include:

  • Real-time tracking of file operations (creation, modification, deletion, renaming)
  • Structured SQLite storage with columns for paths, tags, timestamps, and full content
  • Graceful shutdown handling with signal-based termination
  • Write-Ahead Logging (WAL) mode for multi-process database access
  • Support for both continuous monitoring and one-time indexing runs

Advanced error tracking captures processing failures with detailed messages, while the database schema supports future sync extensions through planned sync_status and remote_id fields.

Use cases of Obsidian Index Service: Real-Time SQLite Sync & MCP Integration?

  • Agile note exploration: Provides instant access to structured note metadata for search tools or external apps
  • MCP integration: Supplies real-time data to mcp-server instances for content processing workflows
  • Development scaffolding: Offers a pre-built SQLite backend for prototyping Obsidian vault-based applications
  • Sync experimentation: Serves as a foundation for developing bidirectional cloud sync systems using planned extensions

Obsidian Index Service FAQ

FAQ from Obsidian Index Service: Real-Time SQLite Sync & MCP Integration?

Does this support Windows systems?

Yes, but requires path syntax adjustments. Use backslashes or normalize paths via os.path functions.

How does concurrency work?

SQLite's WAL mode allows read/write operations. External services must use read-only mounts to prevent conflicts.

Can I use another database?

Currently SQLite-only, but future PRs could add PostgreSQL/MySQL support through database abstraction layers.

What triggers sync retries?

Retry logic is planned for future sync-focused versions. Current error handling logs failures without automatic retries.

Content

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-service

  2. Set up a virtual environment:

* With `uv` (recommended):
    
            uv venv
    source .venv/bin/activate # Linux/macOS
    .venv\Scripts\activate # Windows
    

* With `python` (standard):
    
            python -m venv .venv
    source .venv/bin/activate  # Linux/macOS
    .venv\Scripts\activate     # Windows
    
  1. Install dependencies:
* With `uv` (recommended):
    
            uv sync  # Installs from uv.lock
    uv pip install pytest pytest-bdd pytest-mock  # For tests
    

* With `pip`:
    
            pip install -e .
    pip install pytest pytest-bdd pytest-mock  # For tests
    

Running Locally

Set environment variables:

export OBSIDIAN_VAULT_PATH=/path/to/vault
export DB_PATH=/path/to/notes.sqlite

Run it:

python main.py

With uv:

uv run python main.py

For a one-time scan:

python main.py --scan-only

Or with uv:

uv run python main.py --scan-only

Command-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 -d

  2. 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 mount

  2. 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__)
* Loads configuration from environment variables or command-line arguments
* Initializes the database connection (`DatabaseConnection`)
* Sets up the note processor (`NoteProcessor`)
* Establishes signal handlers for graceful shutdown
  1. Database Initialization (DatabaseConnection.__init__)
* Creates/connects to an SQLite database
* Sets up the database in WAL (Write-Ahead Logging) mode for better concurrency
* Creates a 'notes' table if it doesn't exist with columns for path, title, tags, etc.
  1. Initial Vault Scan (NoteProcessor.scan_vault)
* Finds all Markdown files (*.md, *.markdown) in the vault directory
* For each file, extracts metadata
* Adds all extracted metadata to the database (`NoteOperations.insert_note`)
  1. Continuous Monitoring (FileWatcher.watch)
* Watches the vault directory for file system events
* Processes different types of events: 
  * File creation: Indexes new files
  * File modification: Updates index for changed files
  * File deletion: Removes entries from the index
  * File movement/renaming: Updates path information
  1. File Processing (NoteProcessor.process_note)
* Extracts metadata from Markdown files
* Includes path, title, parent folders, tags, created/modified dates
* Updates the database with this information (`NoteOperations.upsert_note`)
  1. Graceful Shutdown (ObsidianIndexService.shutdown)
* Properly closes file watchers and database connections when receiving termination signals

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:

pytest

Project 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.

Related MCP Servers & Clients