Photograph handwritten journal entries, OCR them, and save to Obsidian.
- Mobile-friendly PWA for capturing journal pages
- Multi-page batch capture
- OCR via HandwritingOCR.com (recommended) or Claude Vision
- Automatic date extraction from handwriting
- Multi-entry splitting (different dates on same page)
- Structured markdown output with frontmatter
- Direct save to Obsidian vault
Mobile Browser (PWA) → Local Python Server → Claude Vision → Obsidian Vault
cd server
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txtCreate server/.env:
# Path to your Obsidian vault
VAULT_PATH=~/Obsidian
# OCR provider: "handwriting-ocr" (recommended), "claude-code", or "api"
OCR_PROVIDER=handwriting-ocr
# For handwriting-ocr provider:
HANDWRITING_OCR_API_KEY=your-token
ANTHROPIC_API_KEY=your-api-key
# For claude-code provider: no keys needed (uses local Claude Code CLI)
# For api provider: only ANTHROPIC_API_KEY neededcd web
npm installMobile browsers require HTTPS to access the camera. Choose one option:
# Install mkcert
brew install mkcert # macOS
# or: choco install mkcert # Windows
# or: apt install mkcert # Linux
# Create local CA and certificates
mkcert -install
cd server
mkcert localhost 127.0.0.1 ::1 $(hostname).local
# This creates localhost+3.pem and localhost+3-key.pemIf you use Tailscale, you get automatic HTTPS:
# Your server will be available at:
# https://your-machine.tailnet-name.ts.net:8000cd server
source venv/bin/activate
# Without HTTPS (localhost only):
python main.py
# With HTTPS (for mobile access):
uvicorn main:app --host 0.0.0.0 --port 8000 \
--ssl-keyfile localhost+3-key.pem \
--ssl-certfile localhost+3.pemcd web
# Development:
npm run dev
# The frontend will be available at http://localhost:5173
# For mobile, set VITE_API_URL to your server's HTTPS URL
VITE_API_URL=https://your-mac.local:8000 npm run dev- Find your Mac's local IP:
ipconfig getifaddr en0 - On your phone, visit:
https://YOUR_IP:5173 - Accept the self-signed certificate warning
- Add to home screen for PWA experience
- Open the app on your phone
- Tap the capture button to photograph your journal page
- Add more pages if needed (multi-page entries)
- Tap "Transcribe" to send to Claude for OCR
- If no date is detected, you'll be prompted to enter one
- Review the transcription and tap "Save to Obsidian"
Each entry is saved as:
---
date: 2025-01-22
type: journal
source: handwritten-ocr
tags: [reflection, ideas]
---
# January 22, 2025
[Transcribed and cleaned text...]
---
*Transcribed from handwritten entry*
![[journal-2025-01-22-001.jpg]]Uses HandwritingOCR.com for transcription, then Claude Haiku for post-processing (date detection, entry splitting, cleanup). Best accuracy for handwritten text.
OCR_PROVIDER=handwriting-ocr
HANDWRITING_OCR_API_KEY=your-token # Get from handwritingocr.com/settings/api
ANTHROPIC_API_KEY=sk-ant-... # For Claude Haiku post-processingUses claude -p with vision - consumes your Claude Code subscription allowance. No API keys needed if you have Claude Code installed locally.
OCR_PROVIDER=claude-codeDirect Claude Vision API calls - pay per request.
OCR_PROVIDER=api
ANTHROPIC_API_KEY=sk-ant-...# Run backend with auto-reload
cd server && python main.py
# Run frontend with hot-reload
cd web && npm run dev- Ensure you're using HTTPS
- Check that camera permissions are granted
- Try refreshing the page
- Check that the server is running
- Verify the API URL is correct
- Ensure you're on the same network
- Check Claude Code is installed:
claude --version - Or set up API key in
.env