graph-rag-obsidian
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@graph-rag-obsidianwhat are key insights from my project notes?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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
Related MCP server: mcp-duckvault
π― 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/Linux2. Install Dependencies
uv sync3. Configure Environment
cp configs/.env.example .env
# Edit .env and add your GEMINI_API_KEY and vault paths4. Index Your Vault
# Full indexing (unified ChromaDB store)
uv run scripts/reindex.py all
# Check indexing status
uv run scripts/reindex.py status5. 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:8765Raycast (HTTP mode):
# Start HTTP server
uv run graph-rag-mcp-http
# Install generated Raycast extensionFor 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 statusReal-time Watching
# Start file watcher
uv run scripts/reindex_watch.py start
# Test file detection
uv run scripts/reindex_watch.py testPARA 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 25PARA 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 100Shows current taxonomy state and enrichment potential.
Step 2: Test on subset (dry run)
uv run scripts/enrich_para_taxonomy.py enrich --limit 5 --dry-runPreview 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 --applyExample 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 -qCommon 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" --jsonAdditional 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/directoryCheck disk space and permissions
Try full reindex:
uv run scripts/reindex.py unified --fullDatabase is automatically created on first run
Unified Store Issues
Check disk space for
.chroma_db/Try full reindex:
uv run scripts/reindex.py unified --fullEnsure notes are properly deduplicated (fixed in latest version)
Gemini API Issues
Verify API key:
uv run scripts/reindex.py statusCheck rate limits and quotas
For enrichment errors, try smaller batch sizes
Enrichment Issues
Use
--dry-runto preview changes firstCheck 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/ -vAll tests:
uv run python scripts/run_tests.py allEvaluation suite:
uv run python tests/evals/runner.py
Test Categories:
Unit Tests (
tests/unit/): Query intent detection, fuzzy matching, relationship weighting, URI generationIntegration Tests (
tests/integration/): Full MCP server component integrationEvaluation Suite (
tests/evals/): Performance metrics and quality assessmentTest 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_tagCRUD operations:
create_note,add_content_to_note,archive_noteNote 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.
This server cannot be deployed
Maintenance
Related MCP Connectors
- ContextaOAuthcc.contexta
Persistent memory and knowledge graph for AI assistants β keyword + vector + graph search.
Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analyβ¦
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceTransforms Obsidian vaults into AI-powered knowledge bases using multi-layer RAG with advanced knowledge graph integration, enabling semantic search, entity extraction, and relationship mapping across personal notes.8MIT
- AlicenseNot gradedqualityAmaintenanceProvides a RAG system for your Obsidian Vault using DuckDB and vector search, enabling semantic search and note retrieval through AI agents.2MIT
- AlicenseNot gradedqualityDmaintenanceA local-first Graph-RAG system combining ChromaDB with metadata-based graph relationships and Gemini 2.5 Flash for intelligent Q&A over Obsidian vaults, supporting MCP clients like Claude Desktop, Cursor, and Raycast.MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to navigate, search, and rank notes in an Obsidian vault using graph relationships, providing context-aware access to knowledge without exposing raw file contents.MIT