This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
What I Built
The Problem: We all bookmark interesting articles with the best intentions. Two weeks later, we need that article about FastAPI (or was it Flask?) and face a graveyard of 200+ unsorted links. We click through five before giving up and just Googling it again.
The real problem isn't that we save too muchβit's that we never organize what we save. Manual tagging is tedious. Creating folder hierarchies is a chore we never get around to. So our bookmarks pile up, unread and unsearchable.
The Solution: Recall - A local-first reading assistant that automatically organizes your saved articles using open-source AI. One click saves an article, and while you move on with your life, a local LLM:
- β Generates a concise summary
- β Extracts key takeaways
- β Categorizes it automatically
- β Adds relevant tags
- β Estimates reading time
Everything happens locally on your machine. No cloud service, no API fees, complete privacy.
Who gets to be lazier? Anyone who reads technical articles, documentation, tutorials, or blog posts. Instead of spending 5 minutes per article organizing bookmarks (that you never do anyway), you spend 5 seconds. The AI handles the rest in 30-40 seconds while you keep browsing.
Demo
Saving an Article
I'm reading a React tutorial. One click on the Recall extension:
The extension extracts the article content and sends it to my local API. No cloud involvedβmy reading habits stay on my machine.
Processing in the Background
My local worker picks up the job and sends it to Ollama running Gemma 2B. The terminal shows the processing:
Finding It Later
Two weeks later, I need that React tutorial. I open my Recall dashboard and type "react":
Instant results with summaries visible. Click for full details:
Live Demo: (Local-only - no public deployment)
Repository: https://github.com/kannananil/recall
Code
https://github.com/kannananil/recall
Tech Stack
- Backend: FastAPI, SQLAlchemy, SQLite
- Worker: Ollama, Gemma 2B (open-weight model)
- Extension: TypeScript, Chrome Manifest V3
- Dashboard: React 18, TypeScript, Vite
Quick Start
# 1. Install Ollama and pull Gemma 2B
ollama pull gemma:2b
# 2. Backend
cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python -m uvicorn main:app --reload
# 3. Worker (separate terminal)
cd backend
source venv/bin/activate
python worker.py
# 4. Dashboard (separate terminal)
cd dashboard
npm install
npm run dev
# 5. Load extension in Chrome
# chrome://extensions/ β Load unpacked β select extension folder
Full setup instructions in the README.
How I Built It
Recall is built entirely around Ollama + Gemma 2B, an open-weight model from Google running completely locally.
Architecture
βββββββββββββββββββ
β Browser Ext ββββ
β (Chrome) β β
βββββββββββββββββββ β
ββββΊ ββββββββββββββββββββ
βββββββββββββββββββ β β FastAPI β
β Dashboard ββββ€ β Backend β
β (React+Vite) β β ββββββββββ¬ββββββββββ
βββββββββββββββββββ β β
β βββββββββΌβββββββ
β β SQLite DB β
β βββββββββ²βββββββ
β β
ββββββΊ βββββββ΄ββββββββββ
β Worker β
β (Ollama+Gemma)β
ββββββββββββββββββ
The Open-Source AI Stack
1. Ollama - Local model runtime that makes running LLMs as easy as ollama run gemma:2b. No Python version conflicts, no manual model downloads, no configuration headaches. It just works.
2. Gemma 2B - Google's open-weight model. I chose it because:
- Small enough to run on modest hardware (8GB RAM)
- Fast inference (~30-40s per article)
- Good at instruction following
- Free forever
3. Structured Output - I prompt the model to return JSON:
{
"summary": "2-3 sentence summary",
"key_points": ["point 1", "point 2", "point 3"],
"category": "Technology",
"tags": ["python", "fastapi", "api"],
"estimated_read_minutes": 5
}
The model generates this from article text, I validate it with Pydantic, and save it to SQLite.
Key Design: Async Processing
The critical decision: Decouple saving from processing.
When you save a bookmark:
- Extension sends article β API (200ms)
- API saves with
status=pendingβ Returns immediately - You're done! Move on to the next article
Meanwhile, in the background:
- Worker polls for pending jobs
- Sends to Ollama when available
- Saves generated metadata
- Updates status to
completed
This means you never wait for AI. The bookmark is saved instantly. Processing happens while you're reading something else.
Challenges Solved
1. Content Extraction: Websites are chaos. I use common article selectors (<article>, [role="main"], etc.) with graceful fallbacks.
2. LLM Validation: Even with explicit prompts, models sometimes return invalid JSON. Solution: Strict Pydantic validation + retry logic (max 2 attempts).
3. Local-First Security: API binds to 127.0.0.1 only. Extension has minimal permissions (activeTab, scripting). No broad host permissions, no tracking.
Why Does Open Innovation Matter?
Open-source AI isn't just a feature for Recallβit's the entire foundation. A closed, cloud-based version would be a fundamentally different (and worse) product. Here's why:
1. Privacy: Your Reading Habits Stay Private
When you use a cloud-based bookmark manager with AI, every article you save goes through their servers. They see what you read, when, and what interests you.
With Recall:
- Your bookmarks never leave your machine
- Your reading patterns aren't tracked
- No company profiles you based on interests
- Work docs, competitive research, personal content stays local
Open-source AI running locally isn't just a featureβit's a prerequisite for privacy.
2. Cost: No API Fees, Ever
Cloud AI services charge per request. At $0.002 per call, processing 50 articles/week = $5/month. Not huge, but it adds up. And prices can change.
With Recall:
- Ollama is free and open-source
- Gemma 2B is an open-weight model
- Process unlimited articles forever
- Zero subscription, zero usage limits
Open models mean this tool costs nothing to run, forever. That's not economicalβit's sustainable.
3. Control: Customize However You Want
Closed AI services give you what they give you. Don't like the summary style? Tough. Want specific categories? Not an option.
With Recall:
- Edit the prompt to change summary style
- Swap Gemma 2B for Qwen, Llama, or any model
- Fine-tune on your reading preferences
- Add custom fields (citations, difficulty, etc.)
I experimented with Qwen 2.5 7B (better quality, slower) and Gemma 2B (faster, good enough). I chose speed for MVP, but you can choose differently. Your tool, your rules.
4. Reliability: No Downtime, No Limits
Cloud services go down. They rate-limit during peak hours. Sometimes they shut down entirely.
With Recall:
- Works offlineβno internet after setup
- No rate limitsβprocess as many as you want
- No service shutdownsβyour tool, your machine
Open models don't disappear because a startup pivoted.
5. Transparency: Verify, Don't Trust
Proprietary AI is a black box. You don't know what data it keeps, how it trains models, who has access.
With Recall:
- Every line of code is readable
- Audit exactly what goes to the model
- No hidden data collection
- No training on your private documents
Open-source means you can verify trust instead of just granting it.
In short: Privacy, cost, control, reliability, and transparency aren't nice-to-havesβthey're why Recall works. A closed version would be a worse product solving a different problem.
The Lazy Payoff
Traditional bookmarking:
- Click bookmark button (5 seconds)
- Never organize it (β time wasted later searching)
- Can't find it when you need it
- Google it again
With Recall:
- Click Recall extension (5 seconds)
- Done. AI handles the rest (30-40s in background)
- Search by anythingβtitle, content, tags, summary
- Find it instantly
Real usage this week:
- Saved 10 articles about React, Python, and FastAPI
- Zero time spent categorizing or tagging
- Found 3 of them later using search in under 10 seconds each
- Estimated time saved: ~30 minutes of manual organization I'd never have done anyway
The time savings compound. Every article is automatically searchable. Over a month, that's hours of your life back. Over a year? Days.
Bonus lazy win: I can skim summaries instead of re-reading full articles. If the summary reminds me what I need, I'm done. If I need more, I click through. Either way, I'm not wasting time on irrelevant content.
Prize Categories
- Best Use of Gemma: local gemma3:4b summaries and suggested actions, with a documented failure and fix.
Future Enhancements
This is an MVP, but the local-first architecture enables exciting possibilities:
Weekly/Monthly Digests - "This month you read 12 React articles, 8 Python posts. Main themes: state management, async patterns."
Semantic Search - Embeddings + vector similarity for concept-based search: "show me articles about state management" surfaces Redux, Zustand, Jotai even without that exact phrase.
Related Article Discovery - "You read this FastAPI article. You might also like these 3 about async Python."
Fine-Tuned Models - Train on your reading history for better categorization and personalized summaries.
All of this runs locally because the foundation is open.
Try It Yourself
Repository: https://github.com/kannananil/recall
Prerequisites:
- Python 3.10+
- Node.js 18+
- Ollama + Gemma 2B
- Chrome/Chromium
Setup takes ~10 minutes - full instructions in README.
Final Thoughts
Building Recall reminded me why I love local-first software:
No permission needed. Don't like a feature? Change it. Fork it. Make it yours.
No surprises. No price increases, no features deprecated, no "we're pivoting."
No trust required. Don't trust a company with your dataβit never leaves your machine.
Open-source AI makes this possible. Without Ollama and Gemma, I'd be building a bookmark prettifier. With them, I built a genuine AI assistant running entirely on my hardware.
That's the future I want: powerful tools, running locally, under my control. Recall is one small step toward that future.
What would you automate if you could run AI locally? Drop a commentβI'd love to hear your ideas.
Built for Hacktoberfest 2026 Week 3: Slow and Steady. Because the best productivity tool is one that works while you sleep.






Top comments (0)