Linus Lee's Custom AI Tools
Table of content

Linus Lee is a researcher and engineer who has built over 100 side projects, including two programming languages. He worked as a research engineer at Notion on their AI team from 2023-2024, and now leads AI at Thrive Capital. His blog has half a million words on software, interfaces, and tools for thought.
Lee (@thesephist) builds personal tools to shape how he thinks. His approach: own your entire stack, use AI to extend cognition, and build what doesn’t exist.
The Philosophy
Tools shape thought. The tools you use determine what’s easy to think and what’s hard.
| Commodity Tool | Lee’s Custom Tool | Difference |
|---|---|---|
| Google Search | Monocle | Search your own data, not the web |
| Notes app | Notation | ML highlights important words |
| Browser bookmarks | Revery | Semantic search across saved pages |
| Task manager | Polyx | Bidirectional links to people and notes |
Monocle: Personal Search Engine
Monocle indexes Lee’s entire digital life. See Personal Search for how to build your own.
- Blog posts (all of them)
- Journal entries (10+ years)
- Private notes
- Contacts
- Tweets
- Bookmarks
Query: "that conversation about compilers with Alex"
Results:
1. Journal entry, March 2024: "Met with Alex, discussed..."
2. Note: "Compiler optimization ideas from Alex"
3. Tweet reply to @alex: "Good point about parsing..."
Architecture:
monocle/
├── indexer/
│ ├── markdown.ink # Index markdown files
│ ├── tweets.ink # Twitter archive
│ ├── bookmarks.ink # Pocket, browser
│ └── contacts.ink # People database
├── search/
│ ├── tokenizer.ink # Text processing
│ ├── stemmer.ink # English stemming
│ └── ranking.ink # Relevance scoring
└── web/
└── static/ # Search interface
Design:
- Written in Ink (Lee’s programming language)
- Index compiled at build time
- Client-side only (no data sent to servers)
- Live-as-you-type search
Building Your Own
# Simplified personal search concept
import sqlite3
from sentence_transformers import SentenceTransformer
class PersonalSearch:
def __init__(self, db_path):
self.db = sqlite3.connect(db_path)
self.model = SentenceTransformer('all-MiniLM-L6-v2')
def index_document(self, title, content, source):
embedding = self.model.encode(content)
self.db.execute("""
INSERT INTO documents (title, content, source, embedding)
VALUES (?, ?, ?, ?)
""", (title, content, source, embedding.tobytes()))
def search(self, query, limit=10):
query_embedding = self.model.encode(query)
# Vector similarity search
results = self.db.execute("""
SELECT title, content, source,
cosine_similarity(embedding, ?) as score
FROM documents
ORDER BY score DESC
LIMIT ?
""", (query_embedding.tobytes(), limit))
return results.fetchall()
Notation: ML-Enhanced Notes
Notation highlights important words in your notes:
Input:
"Meeting with Sarah about the Q3 roadmap.
She mentioned concerns about timeline and
suggested we might need to hire another engineer."
Output:
"Meeting with [Sarah] about the [Q3 roadmap].
She mentioned [concerns] about [timeline] and
suggested we might need to [hire] another [engineer]."
The model learns importance from your writing patterns, later searches, and cross-note references.
Benefit: scan notes 3x faster with key information highlighted.
Revery: Semantic Bookmark Search
Revery searches bookmarks by meaning, not tags.
Query: "remote work productivity"
Traditional bookmarks: Hope you tagged it correctly
Revery: Returns semantically similar articles
across all saved content
Indexes: browser bookmarks, Pocket saves, URLs in journal, external links in notes.
Tools for Reading
CoStructure
Visualizes information density in articles:
┌─────────────────────────────────────────┐
│ ████ Introduction (low) │
│ ████████████ Key argument (high) │
│ ██████ Evidence (medium) │
│ ████████████████ Conclusion (highest) │
└─────────────────────────────────────────┘
Click to expand any section. Hover to highlight related sentences.
Academic Paper Workflow
- Find via Elicit
- Dense sections via ExplainPaper
- Overview via CoStructure
- Take notes in Notation
The Ink Programming Language
Lee built his own programming language for these tools. He later created Oak, a successor with a broader standard library:
` Ink syntax example - simple HTTP server `
std := load('std')
http := load('http')
server := http.new()
server.route('/search', params => (
query := params.q
results := search(query)
http.json(results)
))
server.start(8080)
Why: custom thinking style, full stack control, understanding compilers, and learning.
The point: if a tool doesn’t exist, you can build it. You don’t need a custom language.
AI as Thought Calculator
AI isn’t replacement for thinking. It’s a calculator for thought: handles language manipulation so you focus on ideas.
Use cases:
- Vibe check: “Does this argument make sense? Point out weak spots.”
- Synthesis: “These 5 papers share what common thread?”
- Translation: “Rewrite this technical concept for general audience.”
- Expansion: “Develop this rough idea into a full outline.”
Personal CRM: Polyx
Polyx is Lee’s personal productivity suite, including a CRM, task manager, and notes app:
Person: Sarah Chen
Last contact: 2026-01-15
Context: Q3 roadmap discussion
- Concerned about hiring timeline
- Interested in AI tooling
- Prefers async communication
Connected:
- Project: Q3 Planning
- Note: "Roadmap meeting notes"
- Email: "Re: Engineering capacity"
Bidirectional links connect people to projects, notes, and emails.
The Custom Tool Mindset
When to Build Custom
| Build Custom When | Use Existing When |
|---|---|
| Commodity tools don’t fit your workflow | Good enough exists |
| You’ll use it daily for years | One-time need |
| Learning value is high | Time is more valuable |
| Privacy is critical | Collaboration is needed |
| You enjoy building | You don’t enjoy building |
4-Week Build
Week 1: Identify friction. What’s awkward? What do you look up repeatedly? What doesn’t exist?
Week 2: Prototype. Build the smallest version. Use any language. Don’t polish.
Week 3: Use daily. Note what’s missing. Add features only when needed.
Week 4: Decide. Worth maintaining? Rebuild properly? Or learning exercise?
Example: Daily Note Tool
#!/usr/bin/env python3
"""
Minimal daily notes tool.
Creates dated markdown file, opens in editor.
"""
import os
import subprocess
from datetime import date
NOTES_DIR = os.path.expanduser("~/notes/daily")
EDITOR = os.environ.get("EDITOR", "vim")
def main():
today = date.today().isoformat()
filepath = f"{NOTES_DIR}/{today}.md"
if not os.path.exists(filepath):
with open(filepath, "w") as f:
f.write(f"# {today}\n\n## Morning\n\n## Tasks\n\n## Notes\n")
subprocess.run([EDITOR, filepath])
if __name__ == "__main__":
main()
20 lines. One function. Build from there.
Getting Started
Start with: What’s hard to think about? What information is scattered? What cognitive work repeats?
Then build the smallest useful tool. Weekend project. Use for a month. Iterate or abandon.
Resources:
Next: Alex Albert’s Claude Prompting System
Get updates
New guides, workflows, and AI patterns. No spam.
Thank you! You're on the list.