# xbl2602/obsidian-rag architecture

> Architecture diagram of the GitHub repository xbl2602/obsidian-rag, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/xbl2602/obsidian-rag
- Repository: https://github.com/xbl2602/obsidian-rag

## Overview

Obsidian RAG is a local-first search and knowledge-management application for Obsidian vaults. The main workflow registers a vault, applies its inclusion rules, extracts and indexes supported files, then answers a meaning-based query with fused keyword and vector retrieval. Users can inspect indexing outcomes, follow note links, and optionally search PDF pages visually. The graph includes both desktop interfaces and MCP access. Some feature wiring is documented in the README but not shown in sampled source; those links are included only where the documentation supports them.

Main entry points: [`index.py`](https://github.com/xbl2602/obsidian-rag/blob/main/index.py) (Indexer), [`guiweb/bridge.py`](https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/bridge.py) (Webview bridge), [`server.py`](https://github.com/xbl2602/obsidian-rag/blob/main/server.py) (MCP tools), [`retriever.py`](https://github.com/xbl2602/obsidian-rag/blob/main/retriever.py) (Hybrid retrieval)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_indexing["Vault indexing"]
  node_index["Indexer<br/>[index.py]"]
  node_extract["Document extraction<br/>[extractors.py]"]
  node_textstore[("Text index<br/>[index.py]")]
  node_mineru["MinerU OCR<br/>[mineru_server.py]"]
  node_gpu["GPU arbitration<br/>[gpu_arbiter.py]"]
end

subgraph group_search["Search and navigation"]
  node_retriever["Hybrid retrieval<br/>[retriever.py]"]
  node_advice["Result guidance<br/>[advice.py]"]
  node_windex["Page indexer<br/>[wemm_indexer.py]"]
  node_wstore[("Page vector store<br/>[wemm_indexer.py]")]
  node_wretriever["Visual page search<br/>[wemm_retriever.py]"]
  node_wservice["WEMM service<br/>[wemm_server.py]"]
end

subgraph group_management["Knowledge management"]
  node_library[("Library registry<br/>[library.py]")]
  node_config[("Shared settings<br/>[config.py]")]
  node_relations["Note relations<br/>[index.py]"]
  node_duplicates["Duplicate suggestions<br/>[dedup.py]"]
  node_transfer["Vault transfer<br/>[export.py]"]
  node_summary["Library summaries<br/>[library_summary.py]"]
end

subgraph group_interfaces["User interfaces"]
  node_mcp["MCP tools<br/>[server.py]"]
  node_worker["Index worker<br/>[worker.py]"]
  node_classic["Classic desktop<br/>[app.py]"]
  node_bridge["Webview bridge<br/>[bridge.py]"]
  node_webapp["Webview desktop<br/>[app.py]"]
  node_webui["Webview interface<br/>[app.js]"]
end

node_user(("Vault owner"))
node_vault[("Obsidian vault")]
node_ai(("AI client"))

node_user -->|"maintains notes"| node_vault
node_user -->|"registers vault"| node_library
node_user -->|"uses"| node_classic
node_user -->|"uses"| node_webapp
node_user -->|"configures"| node_mcp
node_vault -->|"scanned by"| node_index
node_library -->|"provides scope"| node_index
node_config -->|"configures"| node_index
node_index -->|"extracts files"| node_extract
node_index -->|"writes chunks"| node_textstore
node_index -.->|"updates pages"| node_windex
node_index -.->|"requests OCR"| node_mineru
node_index -->|"coordinates GPU"| node_gpu
node_config -->|"configures"| node_retriever
node_textstore -->|"provides indexed text"| node_retriever
node_retriever -->|"formats guidance"| node_advice
node_index -->|"records wiki links"| node_relations
node_library -->|"supplies library"| node_summary
node_index -->|"provides note corpus"| node_duplicates
node_user -->|"exports or imports"| node_transfer
node_windex -->|"writes page vectors"| node_wstore
node_wretriever -->|"queries pages"| node_wstore
node_wretriever -->|"encodes query"| node_wservice
node_config -->|"configures backend"| node_wretriever
node_gpu -.->|"manages availability"| node_wservice
node_ai -->|"invokes tools"| node_mcp
node_mcp -->|"searches knowledge"| node_retriever
node_mcp -->|"requests reindex"| node_index
node_mcp -->|"reads links"| node_relations
node_mcp -->|"navigates pages"| node_wretriever
node_mcp -->|"lists libraries"| node_library
node_classic -->|"starts indexing"| node_worker
node_worker -->|"spawns process"| node_index
node_classic -->|"searches"| node_retriever
node_webapp -->|"creates bridge"| node_bridge
node_webui -->|"calls API"| node_bridge
node_bridge -->|"starts indexing"| node_worker
node_bridge -->|"searches"| node_retriever
node_bridge -->|"updates selection"| node_library
node_bridge -->|"generates summaries"| node_summary
node_bridge -->|"reads note links"| node_relations
node_bridge -->|"finds duplicates"| node_duplicates
node_bridge -->|"navigates pages"| node_wretriever

click node_library "https://github.com/xbl2602/obsidian-rag/blob/main/library.py"
click node_config "https://github.com/xbl2602/obsidian-rag/blob/main/config.py"
click node_index "https://github.com/xbl2602/obsidian-rag/blob/main/index.py"
click node_extract "https://github.com/xbl2602/obsidian-rag/blob/main/extractors.py"
click node_textstore "https://github.com/xbl2602/obsidian-rag/blob/main/index.py"
click node_retriever "https://github.com/xbl2602/obsidian-rag/blob/main/retriever.py"
click node_advice "https://github.com/xbl2602/obsidian-rag/blob/main/advice.py"
click node_relations "https://github.com/xbl2602/obsidian-rag/blob/main/index.py"
click node_duplicates "https://github.com/xbl2602/obsidian-rag/blob/main/dedup.py"
click node_transfer "https://github.com/xbl2602/obsidian-rag/blob/main/export.py"
click node_summary "https://github.com/xbl2602/obsidian-rag/blob/main/library_summary.py"
click node_windex "https://github.com/xbl2602/obsidian-rag/blob/main/wemm_indexer.py"
click node_wstore "https://github.com/xbl2602/obsidian-rag/blob/main/wemm_indexer.py"
click node_wretriever "https://github.com/xbl2602/obsidian-rag/blob/main/wemm_retriever.py"
click node_wservice "https://github.com/xbl2602/obsidian-rag/blob/main/wemm_server.py"
click node_mineru "https://github.com/xbl2602/obsidian-rag/blob/main/mineru_server.py"
click node_gpu "https://github.com/xbl2602/obsidian-rag/blob/main/gpu_arbiter.py"
click node_mcp "https://github.com/xbl2602/obsidian-rag/blob/main/server.py"
click node_worker "https://github.com/xbl2602/obsidian-rag/blob/main/gui/worker.py"
click node_classic "https://github.com/xbl2602/obsidian-rag/blob/main/gui/app.py"
click node_bridge "https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/bridge.py"
click node_webapp "https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/app.py"
click node_webui "https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/ui/app.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_index,node_extract,node_textstore,node_mineru,node_gpu,node_ai toneBlue
class node_retriever,node_advice,node_windex,node_wstore,node_wretriever,node_wservice,node_vault toneAmber
class node_library,node_config,node_relations,node_duplicates,node_transfer,node_summary toneMint
class node_mcp,node_worker,node_classic,node_bridge,node_webapp,node_webui toneRose
class node_user toneIndigo
```

## Components

### Vault indexing

- [Indexer](https://github.com/xbl2602/obsidian-rag/blob/main/index.py): `index.py`
- [Document extraction](https://github.com/xbl2602/obsidian-rag/blob/main/extractors.py): `extractors.py`
- [Text index](https://github.com/xbl2602/obsidian-rag/blob/main/index.py): `index.py`
- [MinerU OCR](https://github.com/xbl2602/obsidian-rag/blob/main/mineru_server.py): `mineru_server.py`
- [GPU arbitration](https://github.com/xbl2602/obsidian-rag/blob/main/gpu_arbiter.py): `gpu_arbiter.py`

### Search and navigation

- [Hybrid retrieval](https://github.com/xbl2602/obsidian-rag/blob/main/retriever.py): `retriever.py`
- [Result guidance](https://github.com/xbl2602/obsidian-rag/blob/main/advice.py): `advice.py`
- [Page indexer](https://github.com/xbl2602/obsidian-rag/blob/main/wemm_indexer.py): `wemm_indexer.py`
- [Page vector store](https://github.com/xbl2602/obsidian-rag/blob/main/wemm_indexer.py): `wemm_indexer.py`
- [Visual page search](https://github.com/xbl2602/obsidian-rag/blob/main/wemm_retriever.py): `wemm_retriever.py`
- [WEMM service](https://github.com/xbl2602/obsidian-rag/blob/main/wemm_server.py): `wemm_server.py`

### Knowledge management

- [Library registry](https://github.com/xbl2602/obsidian-rag/blob/main/library.py): `library.py`
- [Shared settings](https://github.com/xbl2602/obsidian-rag/blob/main/config.py): `config.py`
- [Note relations](https://github.com/xbl2602/obsidian-rag/blob/main/index.py): `index.py`
- [Duplicate suggestions](https://github.com/xbl2602/obsidian-rag/blob/main/dedup.py): `dedup.py`
- [Vault transfer](https://github.com/xbl2602/obsidian-rag/blob/main/export.py): `export.py`
- [Library summaries](https://github.com/xbl2602/obsidian-rag/blob/main/library_summary.py): `library_summary.py`

### User interfaces

- [MCP tools](https://github.com/xbl2602/obsidian-rag/blob/main/server.py): `server.py`
- [Index worker](https://github.com/xbl2602/obsidian-rag/blob/main/gui/worker.py): `gui/worker.py`
- [Classic desktop](https://github.com/xbl2602/obsidian-rag/blob/main/gui/app.py): `gui/app.py`
- [Webview bridge](https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/bridge.py): `guiweb/bridge.py`
- [Webview desktop](https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/app.py): `guiweb/app.py`
- [Webview interface](https://github.com/xbl2602/obsidian-rag/blob/main/guiweb/ui/app.js): `guiweb/ui/app.js`

### Other components

- **Vault owner**
- **Obsidian vault**
- **AI client**

## Connections

- Vault owner → Obsidian vault: maintains notes
- Vault owner → Library registry: registers vault
- Vault owner → Classic desktop: uses
- Vault owner → Webview desktop: uses
- Vault owner → MCP tools: configures
- Obsidian vault → Indexer: scanned by
- Library registry → Indexer: provides scope
- Shared settings → Indexer: configures
- Indexer → Document extraction: extracts files
- Indexer → Text index: writes chunks
- Indexer → Page indexer: updates pages
- Indexer → MinerU OCR: requests OCR
- Indexer → GPU arbitration: coordinates GPU
- Shared settings → Hybrid retrieval: configures
- Text index → Hybrid retrieval: provides indexed text
- Hybrid retrieval → Result guidance: formats guidance
- Indexer → Note relations: records wiki links
- Library registry → Library summaries: supplies library
- Indexer → Duplicate suggestions: provides note corpus
- Vault owner → Vault transfer: exports or imports
- Page indexer → Page vector store: writes page vectors
- Visual page search → Page vector store: queries pages
- Visual page search → WEMM service: encodes query
- Shared settings → Visual page search: configures backend
- GPU arbitration → WEMM service: manages availability
- AI client → MCP tools: invokes tools
- MCP tools → Hybrid retrieval: searches knowledge
- MCP tools → Indexer: requests reindex
- MCP tools → Note relations: reads links
- MCP tools → Visual page search: navigates pages
- MCP tools → Library registry: lists libraries
- Classic desktop → Index worker: starts indexing
- Index worker → Indexer: spawns process
- Classic desktop → Hybrid retrieval: searches
- Webview desktop → Webview bridge: creates bridge
- Webview interface → Webview bridge: calls API
- Webview bridge → Index worker: starts indexing
- Webview bridge → Hybrid retrieval: searches
- Webview bridge → Library registry: updates selection
- Webview bridge → Library summaries: generates summaries
- Webview bridge → Note relations: reads note links
- Webview bridge → Duplicate suggestions: finds duplicates
- Webview bridge → Visual page search: navigates pages
