obsidian-notes-rag 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,42 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Install uv
16
+ uses: astral-sh/setup-uv@v4
17
+
18
+ - name: Set up Python
19
+ run: uv python install 3.13
20
+
21
+ - name: Install dependencies
22
+ run: uv sync --dev
23
+
24
+ - name: Type check
25
+ run: uv run pyright
26
+
27
+ test:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@v4
34
+
35
+ - name: Set up Python
36
+ run: uv python install 3.13
37
+
38
+ - name: Install dependencies
39
+ run: uv sync --dev
40
+
41
+ - name: Run tests
42
+ run: uv run pytest -v
@@ -0,0 +1,20 @@
1
+ name: Release Please
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
11
+
12
+ jobs:
13
+ release-please:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: googleapis/release-please-action@v4
17
+ with:
18
+ release-type: python
19
+ config-file: release-please-config.json
20
+ manifest-file: .release-please-manifest.json
@@ -0,0 +1,50 @@
1
+ name: Release to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+ inputs:
8
+ tag:
9
+ description: 'Git tag to publish (e.g., v0.1.0)'
10
+ required: true
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ ref: ${{ inputs.tag || github.ref }}
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v4
22
+
23
+ - name: Set up Python
24
+ run: uv python install 3.11
25
+
26
+ - name: Build package
27
+ run: uv build
28
+
29
+ - name: Upload dist artifacts
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: dist
33
+ path: dist/
34
+
35
+ publish:
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ environment: pypi
39
+ permissions:
40
+ contents: write
41
+ id-token: write
42
+ steps:
43
+ - name: Download dist artifacts
44
+ uses: actions/download-artifact@v4
45
+ with:
46
+ name: dist
47
+ path: dist/
48
+
49
+ - name: Publish to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,40 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+
34
+ # Project specific
35
+ data/
36
+ .claude/
37
+
38
+ # OS
39
+ .DS_Store
40
+ Thumbs.db
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.2"
3
+ }
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ ## [0.1.2](https://github.com/ernestkoe/obsidian-rag/compare/v0.1.1...v0.1.2) (2026-01-04)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * disable attestations for token-based auth ([8d70f98](https://github.com/ernestkoe/obsidian-rag/commit/8d70f989f3e50c7d9f6a5f045d0cc767646c0686))
9
+ * use API token for PyPI publish ([51a2c09](https://github.com/ernestkoe/obsidian-rag/commit/51a2c0958e226b128a2a34c9ec0a8e2c75102a93))
10
+
11
+ ## [0.1.1](https://github.com/ernestkoe/obsidian-rag/compare/v0.1.0...v0.1.1) (2026-01-04)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * add manual trigger to release workflow ([130dfd0](https://github.com/ernestkoe/obsidian-rag/commit/130dfd0cfddce817863998042ee783791b8204a9))
17
+
18
+ ## 0.1.0 (2026-01-03)
19
+
20
+
21
+ ### ⚠ BREAKING CHANGES
22
+
23
+ * Project renamed from obsidian-memory to mcp-obsidianRAG
24
+
25
+ ### Features
26
+
27
+ * add file watcher daemon with launchd integration ([23d2429](https://github.com/ernestkoe/obsidian-rag/commit/23d2429c61d82e98610c0180f7044b807ad9cd60))
28
+ * add OpenAI embeddings and setup wizard ([e1e363e](https://github.com/ernestkoe/obsidian-rag/commit/e1e363ee26a70d82635d7c8bf2bec38afaf28383))
29
+ * consolidate CLI entry points for uvx workflow ([95eb546](https://github.com/ernestkoe/obsidian-rag/commit/95eb546b0a7d6d89d30da8d0dd4f7c4c64600657))
30
+
31
+
32
+ ### Documentation
33
+
34
+ * add TODOs for Linux/Windows service support ([569a830](https://github.com/ernestkoe/obsidian-rag/commit/569a830b5272c7fdd0c8ba826063b765706ecdcf))
35
+
36
+
37
+ ### Code Refactoring
38
+
39
+ * rename project to mcp-obsidianRAG ([16a83d9](https://github.com/ernestkoe/obsidian-rag/commit/16a83d9ebe142f25231a33824b7c27237f61da73))
@@ -0,0 +1,85 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ obsidian-rag is an MCP (Model Context Protocol) server that provides semantic search over Obsidian notes. It uses OpenAI embeddings by default (or Ollama for local processing) with ChromaDB for vector storage.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ uv sync --dev
14
+
15
+ # Run tests
16
+ .venv/bin/python -m pytest -v
17
+
18
+ # Type checking
19
+ .venv/bin/python -m pyright
20
+
21
+ # Interactive setup wizard
22
+ uv run obsidian-rag setup
23
+
24
+ # Index vault (manual refresh)
25
+ uv run obsidian-rag index
26
+
27
+ # Run the MCP server (stdio transport)
28
+ uv run obsidian-rag serve
29
+
30
+ # Watch vault for changes
31
+ uv run obsidian-rag watch
32
+
33
+ # Search from CLI
34
+ uv run obsidian-rag search "query"
35
+ ```
36
+
37
+ ## Architecture
38
+
39
+ ### Data Flow
40
+
41
+ ```
42
+ Obsidian Vault → VaultIndexer → Embedder (OpenAI/Ollama) → VectorStore (ChromaDB)
43
+
44
+ MCP Client ← FastMCP Server ← search_notes/get_similar/etc.
45
+ ```
46
+
47
+ ### Key Components (src/obsidian_rag/)
48
+
49
+ - **config.py**: `Config` dataclass, `load_config()`/`save_config()` for TOML config file, cross-platform paths via `platformdirs`
50
+ - **indexer.py**: `VaultIndexer` scans markdown files, `chunk_by_heading()` splits content by `##`/`###` headings, `OpenAIEmbedder` and `OllamaEmbedder` generate embeddings, `create_embedder()` factory selects provider
51
+ - **store.py**: `VectorStore` wraps ChromaDB with cosine similarity search, handles upsert/delete by file path
52
+ - **server.py**: FastMCP server exposing 5 tools: `search_notes`, `get_similar`, `get_note_context`, `get_stats`, `reindex`
53
+ - **watcher.py**: `VaultWatcher` uses watchdog with debouncing (default 2s) to incrementally re-index on file changes
54
+ - **cli.py**: Click-based CLI with `setup` wizard, `--provider` option, commands for indexing, searching, watching, and service management
55
+
56
+ ### Chunking Strategy
57
+
58
+ Files are split by `##` and `###` headings. Chunks smaller than `min_chunk_size` (default 100 chars) merge with the previous chunk. Files without headings become a single chunk.
59
+
60
+ ### Metadata
61
+
62
+ Each chunk stores: `file_path`, `heading`, `heading_level`, `type` ("daily" if path starts with "Daily Notes/", else "note"), and tags from YAML frontmatter.
63
+
64
+ ## Configuration
65
+
66
+ Config file location (created by `setup` command):
67
+ - macOS/Linux: `~/.config/obsidian-rag/config.toml`
68
+ - Windows: `%APPDATA%/obsidian-rag/config.toml`
69
+
70
+ Environment variables (override config file):
71
+ - `OPENAI_API_KEY` - OpenAI API key (required for default provider)
72
+ - `OBSIDIAN_RAG_PROVIDER` - `openai` (default) or `ollama`
73
+ - `OBSIDIAN_RAG_VAULT` - Path to Obsidian vault
74
+ - `OBSIDIAN_RAG_DATA` - ChromaDB storage path
75
+ - `OBSIDIAN_RAG_OLLAMA_URL` - Ollama API (default: `http://localhost:11434`)
76
+ - `OBSIDIAN_RAG_MODEL` - Override embedding model
77
+
78
+ ## Testing
79
+
80
+ Tests are in `tests/`. Current coverage focuses on `test_indexer.py` for frontmatter parsing and chunking logic.
81
+
82
+ ```bash
83
+ # Run a specific test
84
+ uv run pytest tests/test_indexer.py::TestChunkByHeading::test_multiple_headings -v
85
+ ```
@@ -0,0 +1,116 @@
1
+ # Contributing to obsidian-rag
2
+
3
+ ## Development Setup
4
+
5
+ ```bash
6
+ # Clone the repository
7
+ git clone https://github.com/ernestkoe/obsidian-rag.git
8
+ cd obsidian-rag
9
+
10
+ # Install with dev dependencies
11
+ uv sync --dev
12
+
13
+ # Pull the embedding model
14
+ ollama pull nomic-embed-text
15
+ ```
16
+
17
+ ## Project Structure
18
+
19
+ ```
20
+ src/obsidian_rag/
21
+ ├── __init__.py # Package version
22
+ ├── cli.py # Click CLI commands
23
+ ├── server.py # MCP server (FastMCP)
24
+ ├── indexer.py # Markdown parsing, chunking, Ollama embeddings
25
+ ├── store.py # ChromaDB vector store wrapper
26
+ └── watcher.py # File watcher daemon (watchdog)
27
+ ```
28
+
29
+ ## Architecture
30
+
31
+ ### Indexing Pipeline
32
+
33
+ 1. **VaultIndexer** scans markdown files, excludes patterns (`.obsidian/`, etc.)
34
+ 2. **parse_frontmatter()** extracts YAML frontmatter
35
+ 3. **chunk_by_heading()** splits content by `##` and `###` headings
36
+ 4. **OllamaEmbedder** generates embeddings via local Ollama API
37
+ 5. **VectorStore** persists chunks + embeddings to ChromaDB
38
+
39
+ ### MCP Server
40
+
41
+ The server exposes 5 tools via FastMCP:
42
+ - `search_notes` - Semantic search
43
+ - `get_similar` - Find similar notes
44
+ - `get_note_context` - Note + related context
45
+ - `get_stats` - Index statistics
46
+ - `reindex` - Re-index vault
47
+
48
+ ### File Watcher
49
+
50
+ Uses watchdog to monitor the vault directory:
51
+ - Debounces rapid file changes (default 2s)
52
+ - Handles create/modify/delete/move events
53
+ - Can run as macOS launchd service
54
+
55
+ ## Running Tests
56
+
57
+ ```bash
58
+ uv run pytest -v
59
+ ```
60
+
61
+ ## Type Checking
62
+
63
+ ```bash
64
+ uv run pyright
65
+ ```
66
+
67
+ ## Code Style
68
+
69
+ - Python 3.11+
70
+ - Type hints required
71
+ - Docstrings for public functions
72
+
73
+ ## Making Changes
74
+
75
+ 1. Create a feature branch
76
+ 2. Make changes with tests
77
+ 3. Ensure `pytest` and `pyright` pass
78
+ 4. Submit PR with conventional commit message
79
+
80
+ ### Commit Messages
81
+
82
+ Use [Conventional Commits](https://www.conventionalcommits.org/):
83
+
84
+ ```
85
+ feat: add new search filter
86
+ fix: handle empty vault gracefully
87
+ docs: update installation instructions
88
+ refactor: simplify chunking logic
89
+ ```
90
+
91
+ ## Release Process
92
+
93
+ Releases are automated via [release-please](https://github.com/googleapis/release-please). When PRs with conventional commits are merged to `main`, release-please creates a release PR that bumps the version and updates the changelog.
94
+
95
+ ## Environment Variables
96
+
97
+ For development, you can set these in your shell or a `.env` file:
98
+
99
+ | Variable | Default | Description |
100
+ |----------|---------|-------------|
101
+ | `OBSIDIAN_RAG_VAULT` | (hardcoded) | Path to Obsidian vault |
102
+ | `OBSIDIAN_RAG_DATA` | (hardcoded) | Path to ChromaDB data |
103
+ | `OBSIDIAN_RAG_OLLAMA_URL` | `http://localhost:11434` | Ollama API URL |
104
+ | `OBSIDIAN_RAG_MODEL` | `nomic-embed-text` | Embedding model |
105
+ | `OBSIDIAN_RAG_DEBOUNCE` | `2.0` | Watcher debounce seconds |
106
+
107
+ ## Key Dependencies
108
+
109
+ | Package | Purpose |
110
+ |---------|---------|
111
+ | chromadb | Vector store |
112
+ | watchdog | File system monitoring |
113
+ | mcp | MCP server framework |
114
+ | httpx | HTTP client for Ollama |
115
+ | click | CLI framework |
116
+ | pyyaml | Frontmatter parsing |
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ernest Koe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,171 @@
1
+ Metadata-Version: 2.4
2
+ Name: obsidian-notes-rag
3
+ Version: 0.1.2
4
+ Summary: MCP server for semantic search over Obsidian notes using local RAG
5
+ Project-URL: Homepage, https://github.com/ernestkoe/obsidian-rag
6
+ Project-URL: Repository, https://github.com/ernestkoe/obsidian-rag
7
+ Project-URL: Issues, https://github.com/ernestkoe/obsidian-rag/issues
8
+ Author: Ernest Koe
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: chromadb>=0.4.0
13
+ Requires-Dist: click>=8.0.0
14
+ Requires-Dist: httpx>=0.25.0
15
+ Requires-Dist: mcp>=1.0.0
16
+ Requires-Dist: openai>=1.0.0
17
+ Requires-Dist: platformdirs>=3.0.0
18
+ Requires-Dist: pyyaml>=6.0
19
+ Requires-Dist: tomli-w>=1.0.0
20
+ Requires-Dist: watchdog>=3.0.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # obsidian-rag
24
+
25
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
26
+
27
+ MCP server for semantic search over your Obsidian vault. Uses OpenAI embeddings by default (or Ollama for local processing) with ChromaDB for vector storage.
28
+
29
+ ## What it does
30
+
31
+ Ask natural language questions about your notes:
32
+ - "What did I write about project planning?"
33
+ - "Find notes similar to my meeting notes from last week"
34
+ - "What's in my daily notes about the API refactor?"
35
+
36
+ ## Requirements
37
+
38
+ - Python 3.11+
39
+ - `OPENAI_API_KEY` environment variable (or [Ollama](https://ollama.ai/) for local embeddings)
40
+
41
+ ## Quick Start
42
+
43
+ The easiest way to get started is with [uvx](https://docs.astral.sh/uv/guides/tools/) (no installation required):
44
+
45
+ ```bash
46
+ # Run the setup wizard
47
+ uvx obsidian-rag setup
48
+
49
+ # Add to Claude Code
50
+ claude mcp add obsidian-rag -- uvx obsidian-rag serve
51
+ ```
52
+
53
+ ### Alternative: Clone and install
54
+
55
+ ```bash
56
+ git clone https://github.com/ernestkoe/obsidian-rag.git
57
+ cd obsidian-rag
58
+ uv sync
59
+
60
+ uv run obsidian-rag setup
61
+ claude mcp add obsidian-rag -- uv run --directory /path/to/obsidian-rag obsidian-rag serve
62
+ ```
63
+
64
+ The setup wizard will:
65
+ 1. Ask for your embedding provider (OpenAI or Ollama)
66
+ 2. Configure your API key (for OpenAI)
67
+ 3. Set your Obsidian vault path
68
+ 4. Choose where to store the search index
69
+ 5. Optionally run the initial indexing
70
+
71
+ ### Manual Setup (alternative)
72
+
73
+ ```bash
74
+ # Set your API key and index directly
75
+ export OPENAI_API_KEY=sk-...
76
+ uv run obsidian-rag index --vault /path/to/your/vault
77
+ ```
78
+
79
+ ### Using Ollama (local, offline)
80
+
81
+ ```bash
82
+ # Install Ollama and pull the embedding model
83
+ ollama pull nomic-embed-text
84
+
85
+ # Run setup with Ollama, or index directly:
86
+ uv run obsidian-rag --provider ollama index --vault /path/to/your/vault
87
+ ```
88
+
89
+ ## MCP Tools
90
+
91
+ Once connected, these tools are available to Claude:
92
+
93
+ | Tool | What it does |
94
+ |------|--------------|
95
+ | `search_notes` | Find notes matching a query |
96
+ | `get_similar` | Find notes similar to a given note |
97
+ | `get_note_context` | Get a note with related context |
98
+ | `get_stats` | Show index statistics |
99
+ | `reindex` | Update the index |
100
+
101
+ ## Keeping the Index Fresh
102
+
103
+ ### Option 1: Manual reindex
104
+
105
+ ```bash
106
+ uv run obsidian-rag index
107
+ ```
108
+
109
+ ### Option 2: Watch for changes
110
+
111
+ ```bash
112
+ uv run obsidian-rag watch
113
+ ```
114
+
115
+ ### Option 3: Auto-start on login (macOS)
116
+
117
+ ```bash
118
+ uv run obsidian-rag install-service
119
+ ```
120
+
121
+ ## CLI Reference
122
+
123
+ ```bash
124
+ obsidian-rag setup # Interactive setup wizard
125
+ obsidian-rag serve # Start MCP server (for Claude Code)
126
+ obsidian-rag index [--clear] # Index vault (--clear to rebuild)
127
+ obsidian-rag search "query" # Search from command line
128
+ obsidian-rag watch # Watch for file changes
129
+ obsidian-rag stats # Show index stats
130
+ obsidian-rag install-service # Install macOS launchd service
131
+ obsidian-rag uninstall-service # Remove service
132
+ obsidian-rag service-status # Check service status
133
+ ```
134
+
135
+ ## Configuration
136
+
137
+ Set your vault path and provider via CLI options or environment variables:
138
+
139
+ ```bash
140
+ # CLI options
141
+ uv run obsidian-rag --vault /path/to/vault index
142
+ uv run obsidian-rag --provider ollama index
143
+
144
+ # Environment variables
145
+ export OBSIDIAN_RAG_VAULT=/path/to/vault
146
+ export OBSIDIAN_RAG_PROVIDER=ollama # or "openai" (default)
147
+ ```
148
+
149
+ | Variable | Description |
150
+ |----------|-------------|
151
+ | `OPENAI_API_KEY` | OpenAI API key (required for default provider) |
152
+ | `OBSIDIAN_RAG_PROVIDER` | Embedding provider: `openai` (default) or `ollama` |
153
+ | `OBSIDIAN_RAG_VAULT` | Path to Obsidian vault |
154
+ | `OBSIDIAN_RAG_DATA` | Where to store the index (default: `./data`) |
155
+ | `OBSIDIAN_RAG_OLLAMA_URL` | Ollama API URL (default: `http://localhost:11434`) |
156
+ | `OBSIDIAN_RAG_MODEL` | Override embedding model |
157
+
158
+ ## How it works
159
+
160
+ 1. Parses your markdown files and splits them by headings
161
+ 2. Generates embeddings using OpenAI API (or Ollama for local processing)
162
+ 3. Stores vectors in ChromaDB (local, persistent)
163
+ 4. MCP server provides semantic search to Claude
164
+
165
+ ## Contributing
166
+
167
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup.
168
+
169
+ ## License
170
+
171
+ MIT