Project 02
Notes Search & Q&A
About an hour. Your first multi-file project, with persistence. A CLI tool that indexes a folder of .md and .txt notes into SQLite full-text search, then lets you search them — and lets Claude Code answer questions across them using your existing login. No separate API key.
This is what an actual program looks like: a few files in a folder, a virtual environment, a CLI with subcommands, and a database file that holds your data between runs.
What you'll need
- A folder of notes —
.mdand.txtfiles. Don't have one? Make a few right now:mkdir -p ~/notes printf "# Coffee\nI like a single origin Ethiopian.\n" > ~/notes/coffee.md printf "# Books\nReread East of Eden.\n" > ~/notes/books.md - Python 3.10+. Check with
python3 --version.
Setup walkthrough
- Make and enter the project folder:
mkdir -p ~/projects/notes && cd ~/projects/notes git init - Start Claude Code and paste the prompt below. Claude will set up a virtual environment, write the code, and walk you through the first index.
- Point it at your notes:
notes index ~/notes notes search "coffee" - Ask questions about your notes from inside Claude Code. Still in the project folder, start a fresh session (
/clearor restartclaude) and ask:Use the
Claude will runnotesCLI in this folder to answer: what have I written about books?notes search "books", read the results, and answer in plain English.
The prompt
Paste into Claude Code
Build a small command-line tool called `notes` that indexes markdown and text
files into SQLite full-text search, and lets me search them.
Keep it simple. Use only:
- Python 3.10+ (standard library sqlite3, FTS5 is included)
- `click` for the CLI
- `watchdog` only if --watch is implemented
Project layout:
notes/
pyproject.toml (use a venv: python3 -m venv .venv && pip install -e .)
src/notes/
__init__.py
cli.py
index.py
search.py
README.md
.gitignore (ignore .venv, *.db)
CLI:
notes index <folder> Walk the folder, index every .md and .txt file.
Incremental by default: only re-index files whose
mtime is newer than what we have.
notes search "query" Print top 10 hits. Each hit is: path, then the
first matching line with a few words of context.
notes show <path> Print a note's content.
notes stats Number of notes, total words, when last indexed.
Storage:
- One SQLite file at ~/.local/share/notes/notes.db (configurable via $NOTES_DB).
- An FTS5 virtual table with columns: path, body. Rebuild as needed.
- A small `files` table to track (path, mtime, size) for incremental indexing.
Hard requirements:
- Read-only with respect to the notes folder. Never write to it.
- Follow symlinks but don't loop (track visited inodes).
- Skip files larger than 1 MB by default. Skip dotfiles.
- If FTS5 isn't available, print a clear error and exit — don't try to fall
back to LIKE queries.
README should explain:
- How to install (cd into folder, make venv, pip install -e .)
- The four commands above with an example
- How to ask Claude questions about your notes by running `claude` in this
folder and pointing it at `notes search`
Don't add a config file, don't add embeddings, don't add an MCP server. We'll
do those in a later project if I ask. Build the smallest thing that works.
Before you start, tell me in three sentences what you're about to build.
Then make a TODO list and work through it. Commit after each file.
When something goes wrong
notes: command not found— you didn't activate the venv, or the install didn't pick up the entry point. Trysource .venv/bin/activateand re-run. Or runpython3 -m notes.cli ....no such module: fts5— your Python's SQLite was built without FTS5. On macOS this is rare; on Linux, installsqlite3via your package manager.- Search returns nothing — did you index? Run
notes stats. If it says zero notes, the path you passed toindexwas wrong.
Tips
- The "ask Claude in the folder" trick is genuinely the point. Once the CLI works, your prompt becomes "use the
notestool to answer..." and Claude does the rest. This is the pattern for every project from here on. - Don't add embeddings yet. Lexical search is fast and explainable; you'll know when you need more.
Next up: Project 03 — Morning Briefing →