Inspiration

We keep useful ideas everywhere: Markdown notes, PDFs, saved articles, code. When we want an AI's help with them, the options are bad. We can paste everything and blow through the context window, paste a few files and hope they're the right ones, or upload our notes to a service we don't control. We wanted a place where our knowledge stays as plain files on our own machine, and where an AI gets just the parts of it a question needs, with sources we can check.

What it does

Page is a local-first desktop knowledge workspace for macOS.

  • Write and connect. Notes are plain Markdown files in a folder you choose. Link them with [[wiki links]] and explore an interactive knowledge graph, with notes colored by folder and sized by how connected they are.
  • Bring everything in. PDFs, source code and text files dropped into the folder become searchable, read-only. Add website saves a readable copy of any page as a note.
  • Search by meaning. A local embedding model finds relevant passages even when the words don't match. Search runs entirely on your machine.
  • Ask your notes. Press ⌘K, ask a question, and Page:
    • finds the best-matching passages across notes, PDFs and code;
    • drops weak or duplicate passages and trims long ones to fit a token budget;
    • sends only that to Gemini;
    • shows an answer whose numbered citations jump to the exact lines in your notes or PDFs.
  • Shows what it saved. Each answer shows how many tokens were sent, compared with sending the matching passages whole.
  • Works with AI agents. An MCP server lets tools like Claude Code search your vault and pull budgeted, cited context from it.
  • Friendly to start. A sample vault teaches the basics, a short intro tour runs on first launch, Finder pickers replace typing paths, and a mascot thinks while Page works and dances when your answer arrives.

How we built it

  • Desktop: Tauri 2 with React and TypeScript. A Rust layer owns the backend process and validates every response before the UI sees it.
  • Page Core: Python 3.12. It serves a FastAPI API that only this computer can reach, protected by a per-session token.
    • SQLite gives each note a stable ID, so renaming or moving a note doesn't break its links.
    • Semantic search uses a pinned MiniLM model with FAISS, and caches embeddings so only changed files are re-processed.
    • A context optimizer selects passages within a token budget and keeps exact source lines.
  • Sources: text is extracted from each PDF page with pypdf. Saved web pages are converted to Markdown using only Python's standard library, and only public http(s) addresses are fetched.
  • AI: Gemini's REST API sits behind a small provider-neutral interface, plus an MCP server built on the official Python SDK.
  • Packaging: a pinned, relocatable Python runtime and the embedding model ship inside Page.app, so users don't need to install Python.
  • Quality:
    • over 1,000 Core tests, 100+ UI tests and 55 Rust tests;
    • CI on every pull request;
    • an evaluation benchmark of 40 held-out questions.

Challenges we ran into

  • Our "smart" ranker didn't hold up. We trained a small neural reranker, and it looked great on its own data. On held-out notes it was worse than plain similarity search (recall@1 fell from 0.78 to 0.70). We kept the honest result and shipped the simpler ranking.
  • Honest numbers. Our first savings badge compared against "your whole vault" and always showed about 99%, which mostly measured vault size. We switched to comparing against the passages we actually found. On our benchmark that saving is about 20%.
  • A hidden n² slowdown. Reading each note reloaded every other note's metadata, so a 2,000-note graph took 74 seconds and timed out. Fixing it brought that down to 2.8 seconds, and 5,000 notes now take 6.7 seconds.
  • Desktop details. Shipping Python inside a signed Mac app, macOS Keychain prompts on every rebuild, and slow PDF extraction blocking note saves all needed real engineering.

Accomplishments that we're proud of

  • A full pipeline running locally, from plain files to cited answers: storage, graph, semantic search, context optimization, answers, MCP, and a packaged app.
  • On our 40-question benchmark:
    • the optimizer used 90% fewer tokens than sending every note, and the answer was still in the context for all 40 questions;
    • a simple answer extractor was more accurate with the optimized context (75%) than with the full notes (62%).
  • Every answer cites exact sources, and the AI provider only ever sees the passages a question needs.
  • We published our failures (the reranker) and corrected an inflated metric instead of hiding them.

What we learned

  • Measure on data you didn't tune on. Our best-looking model was overfitting.
  • "Fewer tokens" only matters if the answer survives, and the baseline you compare against changes the story completely.
  • Local-first is a real design constraint: safe file writes, stable note identities, and keeping secrets out of logs all take deliberate work.

What's next for Page

  • Ask about this note: always include the open note in the context.
  • Better ranking: retrain the reranker on much more varied data, and re-evaluate on held-out vaults.
  • Better web saving: keep only a page's main article.
  • Distribution: signed and notarized macOS builds, then Windows support.
  • More providers: local models (like Ollama) through the same provider-neutral interface.

Built With

Share this project:

Updates

Submission history