Graph RAG MCP Server for Obsidian vault with unified ChromaDB store and Gemini 2.5 Flash
Project description
Graph RAG MCP Server for Obsidian
A powerful local-first Graph-RAG system that combines ChromaDB unified store with metadata-based graph relationships and Gemini 2.5 Flash for intelligent Q&A over your Obsidian vault.
๐ Features
- ๐ Unified Database Architecture: ChromaDB with metadata-based graph relationships for both semantic search and graph traversal
- ๐ง Intelligent Semantic Chunking: Respects markdown structure (headers, sections, lists, code blocks)
- ๐ฏ PARA Taxonomy Classification: AI-powered organization using Projects, Areas, Resources, Archive system
- ๐ค RAG-Powered Q&A: Multi-hop retrieval with Gemini 2.5 Flash
- ๐ธ๏ธ Graph Navigation: Explore backlinks, tags, and semantic relationships
- ๐ Real-time Sync: File watcher for automatic indexing
- ๐ Local-First: All processing happens locally (except Gemini API calls)
- ๐ Multi-Client MCP Support: Works with Claude Desktop, Cursor, and Raycast
- โก Dual Transport Modes: stdio for Claude Desktop, HTTP for other clients
- ๐ ๏ธ Automated Installation: One-command setup with client detection
- ๐ Strongly Typed: Pydantic models throughout for reliability
๐ฏ Supported MCP Clients
- ๐ค Claude Desktop: Full stdio integration with automatic configuration
- ๐ Cursor: HTTP mode with MCP extension support
- โก Raycast: HTTP API with custom extension templates
- ๐ Any MCP Client: Standard MCP protocol support (stdio/HTTP)
๐๏ธ Architecture
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Obsidian โ โ ChromaDB โ
โ Vault โโโโโถโ (Unified Store) โ
โ โ โ Vector + Graph โ
โโโโโโโโโโโโโโโโโโโ โ Metadata โ
โ โโโโโโโโโโโโโโโโโโโ
โ โ
โ โผ
โ โโโโโโโโโโโโโโโโโโโ
โ โ DSPy โ
โโโโโโโโโโโโโโโถโ RAG Engine โ
โ + Gemini 2.5 โ
โ (Multi-hop โ
โ Retrieval) โ
โโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ MCP Server โ
โ (FastMCP) โ
โโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ Claude Desktop โ
โ Integration โ
โโโโโโโโโโโโโโโโโโโ
๐ Quick Start
Automated Installation (Recommended)
The easiest way to get started with Claude Desktop, Cursor, or Raycast:
# Interactive setup wizard
uv run install.py
# Or non-interactive with your settings
uv run install.py --vault "/path/to/your/vault" --api-key "your_key"
The installer will:
- โ Detect your installed MCP clients (Claude Desktop, Cursor, Raycast)
- โ๏ธ Configure each client automatically
- ๐ฆ Install all dependencies
- ๐งช Test the installation
- ๐ Create environment configuration
Manual Installation
If you prefer manual setup:
1. Install uv (if not installed)
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux
2. Install Dependencies
uv sync
3. Configure Environment
cp configs/.env.example .env
# Edit .env and add your GEMINI_API_KEY and vault paths
4. Index Your Vault
# Full indexing (unified ChromaDB store)
uv run scripts/reindex.py all
# Check indexing status
uv run scripts/reindex.py status
5. Configure Your MCP Client
Claude Desktop (stdio mode):
{
"mcpServers": {
"graph-rag-obsidian": {
"command": "uvx",
"args": ["--python", "3.13", "--from", ".", "graph-rag-mcp-stdio"],
"cwd": "/path/to/graph-rag-mcp-server",
"env": {
"GEMINI_API_KEY": "your_api_key_here",
"OBSIDIAN_RAG_VAULTS": "/path/to/your/vault"
}
}
}
}
Cursor (HTTP mode):
# Start HTTP server
uv run graph-rag-mcp-http
# Configure Cursor MCP extension to use http://localhost:8765
Raycast (HTTP mode):
# Start HTTP server
uv run graph-rag-mcp-http
# Install generated Raycast extension
For detailed configuration instructions, see SETUP.md.
๐ ๏ธ Available Commands
MCP Server Modes
# Interactive installer
uv run install.py
# Claude Desktop (stdio mode)
uvx --python 3.13 --from . graph-rag-mcp-stdio
# Cursor/Raycast (HTTP mode)
uv run graph-rag-mcp-http
# HTTP with custom port
uv run graph-rag-mcp-http --port 9000
# Direct stdio runs (alternative)
uv run main.py # stdio mode
uv run src/mcp_server.py # stdio mode
Indexing Scripts
# Full indexing
uv run scripts/reindex.py all
# ChromaDB unified store
uv run scripts/reindex.py unified
# Check status
uv run scripts/reindex.py status
Real-time Watching
# Start file watcher
uv run scripts/reindex_watch.py start
# Test file detection
uv run scripts/reindex_watch.py test
PARA Taxonomy Enrichment
Enhance your vault with intelligent PARA system classification using DSPy:
# Analyze current vault taxonomy state
uv run scripts/enrich_para_taxonomy.py analyze --sample 100
# Preview enrichment (dry run) on sample notes
uv run scripts/enrich_para_taxonomy.py enrich --limit 10 --dry-run
# Apply enrichment to specific notes
uv run scripts/enrich_para_taxonomy.py enrich "path/to/note.md" --apply
# Bulk enrichment with filters
uv run scripts/enrich_para_taxonomy.py enrich --limit 50 --folder "Projects" --apply
# FULL VAULT ENRICHMENT (new!)
# Preview entire vault enrichment
uv run scripts/enrich_para_taxonomy.py enrich-all --dry-run
# Apply to entire vault (skips already enriched by default)
uv run scripts/enrich_para_taxonomy.py enrich-all --apply
# Force re-enrichment of entire vault
uv run scripts/enrich_para_taxonomy.py enrich-all --apply --force-all
# Customize batch size for large vaults
uv run scripts/enrich_para_taxonomy.py enrich-all --apply --batch-size 25
PARA Classification Features:
- ๐ฏ Intelligent Classification: Uses Gemini 2.5 Flash to classify notes into Projects, Areas, Resources, Archive
- ๐ท๏ธ Hierarchical Tags: Suggests structured tags like
#para/project/ai/automation - ๐ Relationship Discovery: Finds potential links between related notes with validation
- ๐ก Concept Extraction: Identifies key concepts and themes
- ๐ก๏ธ Safe Updates: Only adds frontmatter, never modifies content
- ๐ Confidence Scoring: Provides reasoning and confidence for classifications
- โก Batch Processing: Process entire vaults efficiently with configurable batch sizes
- ๐ Smart Deduplication: Avoids reprocessing already enriched notes
๐ง MCP Tools
The server exposes these tools for Claude:
Search & Q&A
search_notes: Vector search across vaultanswer_question: RAG-powered Q&A with citationsgraph_neighbors: Find related notes via graphget_subgraph: Extract note subgraphs
Note Operations
create_note: Create new notes with auto-enriched frontmatterlist_notes: Browse vault contentsread_note: Get full note contentget_note_properties: Read frontmatterupdate_note_properties: Modify frontmatteradd_content_to_note: Append content
Graph Navigation
get_backlinks: Find notes linking to targetget_notes_by_tag: Find notes by tag
Management
archive_note: Move notes to archivecreate_folder: Create directoriesreindex_vault: Reindex unified ChromaDB storeenrich_notes: Apply PARA taxonomy enrichment to notes
โ๏ธ Configuration
Key settings in .env:
# Required
GEMINI_API_KEY=your_key_here
# ChromaDB configuration
OBSIDIAN_RAG_CHROMA_DIR=/custom/path/to/.chroma_db
OBSIDIAN_RAG_COLLECTION=vault_collection
# Optional customization
OBSIDIAN_RAG_EMBEDDING_MODEL=all-MiniLM-L6-v2
OBSIDIAN_RAG_GEMINI_MODEL=gemini-2.5-flash
# Semantic chunking configuration
OBSIDIAN_RAG_CHUNK_STRATEGY=semantic # or "character" for simple chunking
OBSIDIAN_RAG_SEMANTIC_MIN_CHUNK_SIZE=100
OBSIDIAN_RAG_SEMANTIC_MAX_CHUNK_SIZE=3000
OBSIDIAN_RAG_SEMANTIC_MERGE_THRESHOLD=200
๐โโ๏ธ Usage Examples
Search Your Vault
# Vector search
results = search_notes("machine learning algorithms", k=5)
# Q&A with context
answer = answer_question("What did I learn about transformers?")
Explore Relationships
# Find related notes
neighbors = graph_neighbors("Deep Learning", depth=2)
# Get backlinks
backlinks = get_backlinks("Neural Networks")
# Find by tag
tagged_notes = get_notes_by_tag("ai")
Manage Notes
# Create a new note with auto-enrichment
note = create_note(
title="Machine Learning Breakthrough",
content="# Key Findings\n\nDiscovered new optimization technique...",
folder="Research",
tags=["ml", "optimization"],
para_type="project", # Hint for PARA classification
enrich=True # Apply AI enrichment
)
# Read note
content = read_note("Research/AI Progress.md")
# Update properties
update_note_properties("Research/AI Progress.md", {
"status": "completed",
"tags": ["ai", "research", "finished"]
})
Creating Notes with Auto-Enrichment
The create_note tool creates properly formatted Obsidian notes with:
- Clean YAML frontmatter
- Automatic PARA classification (if content provided)
- Intelligent tag suggestions
- Potential link discovery
- Timestamps and metadata
Example created note:
---
created: '2025-08-23T20:30:00.000000'
modified: '2025-08-23T20:30:00.000000'
para_type: project
para_category: ai/research
para_confidence: 0.85
key_concepts:
- Machine Learning Optimization
- Gradient Descent Improvements
- Performance Benchmarking
tags:
- ml
- optimization
- para/project
- para/project/ai/research
- tech/ai/ml/optimization
potential_links:
- '[[Optimization Techniques]]'
- '[[Research Log 2025]]'
enrichment_version: '1.0'
last_enriched: '2025-08-23T20:30:00.000000'
enrichment_model: gemini-2.5-flash
---
# Machine Learning Breakthrough
Your content here...
PARA Enrichment Workflow
Step 1: Analyze your vault
uv run scripts/enrich_para_taxonomy.py analyze --sample 100
Shows current taxonomy state and enrichment potential.
Step 2: Test on subset (dry run)
uv run scripts/enrich_para_taxonomy.py enrich --limit 5 --dry-run
Preview classifications without making changes.
Step 3: Apply enrichment
# Start small
uv run scripts/enrich_para_taxonomy.py enrich --limit 20 --apply
# Scale up
uv run scripts/enrich_para_taxonomy.py enrich --limit 100 --apply
Example enriched note:
---
para_type: project
para_category: AI/Automation
para_confidence: 0.9
key_concepts:
- AI Agent Development
- Computer Use Automation
- Grounded AI Systems
tags:
- "#project/ai/automation"
- "#area/ai/development"
potential_links:
- "Related Project Name"
enrichment_version: "1.0"
last_enriched: "2025-08-23T17:59:32"
---
# Your original note content remains unchanged
๐ How It Works
- File Parsing: Extracts markdown content, frontmatter, wikilinks, and tags
- Semantic Chunking: Intelligent chunking based on markdown structure (headers, sections, lists)
- Vector Indexing: Stores semantic chunks with embeddings in ChromaDB
- Graph Metadata: Stores notes, links, tags, and chunk relationships as ChromaDB metadata
- PARA Classification: Uses DSPy + Gemini to classify notes into Projects, Areas, Resources, Archive
- RAG Pipeline: Multi-hop retrieval combining vector search with graph traversal
- MCP Interface: Exposes all capabilities via Model Context Protocol
๐ What's New
Unified ChromaDB Architecture (Latest Update!)
- โก Simplified Architecture: Single database for both vector search and graph relationships
- ๐๏ธ Metadata-based Graph: Efficient graph storage using ChromaDB's native metadata capabilities
- ๐ง Colocated Data: Vector embeddings and graph relationships stored together for optimal query performance
- ๐ฆ Reduced Dependencies: No need for separate RDF libraries or stores
- ๐ Performance: Streamlined queries with direct metadata access
- ๐พ Efficient Storage: Single store with optimized embedding and metadata storage
Enhanced PARA Taxonomy
- ๐ค AI-Powered Classification: Automatic categorization into Projects, Areas, Resources, Archive
- ๐ท๏ธ Smart Tagging: Hierarchical tags like
#para/project/ai/automation - ๐ Validated Wikilinks: Only suggests links to existing notes in your vault
- ๐ Batch Processing: Process entire vaults with configurable batch sizes
- ๐ฏ Obsidian-Native: Clean YAML frontmatter without markdown formatting
ChromaDB Metadata Schema
The system stores graph relationships as ChromaDB metadata:
# Note-level metadata
metadata = {
"note_id": "my_note",
"title": "My Note Title",
"path": "/path/to/note.md",
"tags": "important,ai,project",
"links_to": "other_note,related_note",
"backlinks_from": "source_note,another_note",
"vault": "my_vault"
}
# Chunk-level metadata (semantic chunking)
chunk_metadata = {
"chunk_id": "my_note#chunk_0",
"chunk_type": "section",
"header_text": "Introduction",
"header_level": 2,
"importance_score": 0.8,
"sequential_next": "my_note#chunk_1",
"sequential_prev": "",
"parent_chunk": "my_note#header_0",
"child_chunks": "my_note#chunk_1,my_note#chunk_2",
"sibling_chunks": "my_note#chunk_3",
"semantic_chunk": True
}
๐ก๏ธ Security & Privacy
- Local-First: All data processing happens on your machine
- API Calls: Only Gemini API for text generation (optional)
- No Data Leakage: Vault content never leaves your control
- Path Validation: Prevents directory traversal attacks
๐งช Testing
Test Suite (pytest)
Install test dependencies and run the suite:
# Using uv (recommended)
uv sync --extra test
uv run pytest -q
# Or using the local virtualenv
PYTHONPATH=. .venv/bin/pytest -q
Common invocations:
# Only unit / integration
PYTHONPATH=. .venv/bin/pytest tests/unit -q
PYTHONPATH=. .venv/bin/pytest tests/integration -q
# Coverage (threshold configured in pytest.ini)
PYTHONPATH=. .venv/bin/pytest --cov -q
# Markers
pytest -m unit
pytest -m integration
pytest -m "not slow"
Notes:
- If you see
ModuleNotFoundError: No module named 'tests', prefix commands withPYTHONPATH=.. - Integration tests run without network. Embeddings fall back to a builtโin default and DSPy caches write to
.cache/. Override withXDG_CACHE_HOMEorDSPY_CACHEDIRif needed.
Operational Smoke Checks
# Test indexing
uv run scripts/reindex.py status
# Test file watching
uv run scripts/reindex_watch.py test
# Test unified store
uv run python -c "
from src.unified_store import UnifiedStore
from src.config import settings
store = UnifiedStore(
client_dir=settings.chroma_dir,
collection_name=settings.collection,
embed_model=settings.embedding_model
)
stats = store.get_stats()
print(f'Store stats: {stats}')
"
๐ Smart Search Response Contract
The smart_search MCP tool now returns a typed SmartSearchResponse payload:
schema_version,status(ok/degraded/error), and compositeconfidence.diagnosticswith retrieval method, intent + confidence, mean distance, retry count, circuit-breaker state, and warnings.recommendations(up to three actionable suggestions) whenever the response is degraded or fails.- Legacy keys (
hits,total_results,strategy_used) remain for one release to ease migration.
Inspect responses locally with the updated CLI helper:
uv run scripts/dspy_mcp_client.py --vault /path/to/vault --query "My quarterly goals" --json
Additional MCP tools complement the contract:
health_checkโ runs registered probes, returning cache stats, rate limiter tokens, circuit-breaker state, and metrics counters.get_dspy_optimization_statusโ surfaces optimizer schedule/lock state and whether a background run is pending.force_dspy_optimizationโ triggers an optimization cycle (guarded by async/file locks, executed via a background thread).
Each smart-search invocation also emits a structured log line (SMART_SEARCH_RESULT { ... }) containing the query, status, confidence, retrieval method, retries, circuit-breaker state, warnings, and duration. Simple in-process counters (smart_search_ok/degraded/error, cb_open_events, embed_fallback_events) are exposed via health_check for quick instrumentation.
๐ง Troubleshooting
ChromaDB Issues
- ChromaDB stores data in
.chroma_db/directory - Check disk space and permissions
- Try full reindex:
uv run scripts/reindex.py unified --full - Database is automatically created on first run
Unified Store Issues
- Check disk space for
.chroma_db/ - Try full reindex:
uv run scripts/reindex.py unified --full - Ensure notes are properly deduplicated (fixed in latest version)
Gemini API Issues
- Verify API key:
uv run scripts/reindex.py status - Check rate limits and quotas
- For enrichment errors, try smaller batch sizes
Enrichment Issues
- Use
--dry-runto preview changes first - Check note has content (empty files are skipped)
- Reduce batch size if hitting API limits:
--batch-size 10
๐ Project Structure
graph-rag-mcp-server/
โโโ src/
โ โโโ config.py # Configuration management
โ โโโ fs_indexer.py # File parsing & metadata extraction
โ โโโ semantic_chunker.py # Intelligent markdown-aware chunking
โ โโโ chroma_store.py # Vector database operations
โ โโโ unified_store.py # ChromaDB unified operations (vectors + graph metadata)
โ โโโ dspy_rag.py # RAG engine with Gemini 2.5 Flash
โ โโโ mcp_server.py # FastMCP server & tool definitions
โโโ scripts/
โ โโโ reindex.py # Database indexing utilities
โ โโโ reindex_watch.py # Real-time file monitoring
โ โโโ enrich_para_taxonomy.py # PARA classification & enrichment
โ โโโ migrate_rdf_store.py # (removed)
โโโ configs/
โ โโโ claude-desktop.json # Claude Desktop MCP configuration template
โ โโโ cursor-mcp.json # Cursor MCP configuration template
โ โโโ raycast-config.json # Raycast extension configuration template
โ โโโ .env.example # Environment configuration template
โโโ install.py # Automated installer & configurator
โโโ main.py # Alternate MCP server entry point (stdio)
โโโ pyproject.toml # Dependencies & entry points (uv managed)
โโโ SETUP.md # Comprehensive setup guide
โโโ README.md # Project overview & quick start
๐ค Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
๐ License
MIT License - see LICENSE file for details.
Built with modern python stack: Pydantic, ChromaDB, DSPy, FastMCP, and the latest google-genai SDK.
Comprehensive Test Framework & Evaluation Suite
This repo includes a comprehensive test framework with structured fixtures at tests/fixtures/content/ and an evaluation runner that executes deterministic evals for the MCP tools. The evals use distinctive phrases and low-temperature LLM configs so results are stable across embedding and Gemini model choices.
Running Tests:
- Unit tests:
uv run python -m pytest tests/unit/ -v - All tests:
uv run python scripts/run_tests.py all - Evaluation suite:
uv run python tests/evals/runner.py
Test Categories:
- Unit Tests (
tests/unit/): Query intent detection, fuzzy matching, relationship weighting, URI generation - Integration Tests (
tests/integration/): Full MCP server component integration - Evaluation Suite (
tests/evals/): Performance metrics and quality assessment - Test Fixtures (
tests/fixtures/): Structured test content (planets, health, projects)
The evaluation framework creates temporary test environments, reinitializes app state, reindexes content, and validates:
search_notesandsmart_searchwith strategy routinggraph_neighbors,get_subgraph,get_backlinks,get_notes_by_tag- CRUD operations:
create_note,add_content_to_note,archive_note - Note management:
read_note,get_note_properties,update_note_properties,list_notes
Test environments are automatically created and cleaned up. All test content uses structured Pydantic models with proper type validation.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file iflow_mcp_ferparra_graph_rag_mcp_server-0.1.0.tar.gz.
File metadata
- Download URL: iflow_mcp_ferparra_graph_rag_mcp_server-0.1.0.tar.gz
- Upload date:
- Size: 126.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ddf6c45a4f0b504929df4d69cc80d27d455750bdbc6b592f9d2c37d0208c471
|
|
| MD5 |
052a0e841c46d11f3abd18f6cdc1ff3e
|
|
| BLAKE2b-256 |
03180f8f207e6b7701c91b6542e717f951df544861eec4a3c1f21ff170f385b6
|
File details
Details for the file iflow_mcp_ferparra_graph_rag_mcp_server-0.1.0-py3-none-any.whl.
File metadata
- Download URL: iflow_mcp_ferparra_graph_rag_mcp_server-0.1.0-py3-none-any.whl
- Upload date:
- Size: 123.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b3df2ed77e37623a53eba7725b39890701e06c364812e2af14cda9c4c2f6d51
|
|
| MD5 |
daf268650728bef0616e95458ba9c1a6
|
|
| BLAKE2b-256 |
3326f5bfd30bb5bd04799e9f60aedeae72e0ffee95ef28b25ca01d6eb58ad9ff
|