Gives Claude direct access to the Embassy of the Free Mind's collection of 22,000+ pre-modern texts through a MongoDB-backed search interface. You can query rare historical documents, pull AI-generated English translations powered by Google Gemini, and retrieve book metadata including summaries and themes. The server also exposes access to the 73,000+ page images stored in Vercel Blob, with three quality tiers for different use cases. Reach for this when you need Claude to reference obscure historical sources, compare translations across rare manuscripts, or surface specific passages from pre-modern literature that aren't in standard training data.
A digital library of historical primary sources with AI-aided OCR, translation, and scholarly curation.
Explore thousands of digitized historical texts with AI-enhanced translations and scholarly curation.
Source Library is an open digital library dedicated to making early printed books and primary sources readable and citable. We specialize in alchemy, Hermetica, Kabbalah, Rosicrucianism, and early modern science—texts that bridge historical scholarship with contemporary exploration.
The platform ingests ~15K pages monthly from Internet Archive, Gallica, Bodleian, Wellcome, and other digital heritage partners.
# 🍴 Clone and install
git clone https://github.com/Embassy-of-the-Free-Mind/sourcelibrary-v2.git
cd sourcelibrary-v2
npm install
# ⚙️ Configure environment (see .env.example for required variables)
# Must include: MongoDB Atlas connection, Google Gemini API key, Vercel Blob token
# ▶️ Start dev server
npm run dev
| 🎨 Frontend | Next.js 16, React 19, TailwindCSS, Lucide icons |
| ⚙️ Backend | Next.js API routes, AWS Lambda for async processing |
| 💾 Database | MongoDB Atlas (primary), Supabase (embeddings) |
| 🤖 AI/ML | Google Gemini 3.1 (OCR, translation, summarization) |
| 🗂️ Storage | Vercel Blob (images), AWS S3 (archive), Cloudflare R2 (archive) |
| 🔐 Auth | NextAuth v5 with MongoDB adapter |
| 🚀 DevOps | Vercel (hosting), GitHub (VCS), Playwright (E2E tests) |
| ✔️ Testing | Vitest (unit/integration), Playwright (E2E) |
| 🔎 Search | PostgreSQL FTS + semantic search via Supabase |
📦 Key Dependencies:
sharp — Image resizing and cropping@google/generative-ai — Gemini API integrationxml2js — USTC metadata parsing@modelcontextprotocol/sdk — MCP server for agent integrationstripe — Donation and subscription handlingbph.sourcelibrary.org)📚 Books contain structured metadata:
📄 Pages store individual page data:
🖼️ Gallery images are extracted illustrations:
All page images are resized on-demand via /api/image:
| Tier | Dimensions | Quality | 📱 Use Case |
|---|---|---|---|
| Thumbnail | 400px wide | 70% JPEG | Grids, navigation, social sharing |
| Display | 1200px wide | 80% JPEG | Main reading view, comfortable for annotation |
| Full | 2400px wide | 90% JPEG | Magnifier, fullscreen detail, printing |
Split pages are cropped non-destructively via coordinates; original images are always preserved.
📥 Import → ✂️ Split Detection → ✍️ OCR → 🗣️ Translation → 🎨 Enrichment → 🌍 Publishing
visible: true, mint DOI, push to search indexBatch endpoints process up to 5 pages/request using Gemini Batch API (50% cheaper).
Base URL: https://sourcelibrary.org (production) or http://localhost:3000 (local dev with .env.local configured).
Common 404 mistake: paths like
/api/bph/booksor/api/bph/books/[id]do not exist. BPH catalogue APIs live under/api/embed/bph/.... There is also no top-level/api/[tenant]/booksroute — tenant book listings use/api/books/libraryor the embed routes below.
| Endpoint | Method | Purpose |
|---|---|---|
/api/search?q=<query> | GET | Full-text search across books and page translations |
/api/books?limit=100&offset=0 | GET | Simple book list (global catalogue; visible: true, indexed only) |
/api/books/library?limit=100&skip=0 | GET | Rich browse API — search, sort, filters, collections |
/api/books/[id] | GET | Book metadata (accepts Mongo id or slug) |
/api/books/[id]/quote?page=<n> | GET | Citable quote + formatted citations (inline, footnote, BibTeX, DOI) |
/api/gallery?limit=24 | GET | Illustration / artwork search |
/api/image?url=<encoded-url>&w=400 | GET | On-demand image resize & crop |
/api/embed/bph/books?limit=24 | GET | BPH catalogue (paginated, searchable) |
/api/embed/bph/books/[slug] | GET | Single BPH book detail |
/api/embed/bph/featured | GET | Featured BPH books |
/api/embed/bph/collections | GET | BPH collection list |
/api/embed/bph/languages | GET | BPH language facets |
/api/embed/bph/suggest?q=alch | GET | BPH search autocomplete |
/api/embed/bph/stats | GET | BPH catalogue stats |
/api/bph/...)Use one of these patterns to filter by partner tenant (e.g. BPH):
| Approach | Example |
|---|---|
| Embed prefix (recommended for BPH) | GET /api/embed/bph/books?limit=24 |
| Library API + query param | GET /api/books/library?tenant_slug=bph&limit=24 |
| Host header (subdomain) | Call https://bph.sourcelibrary.org/api/books/library?limit=24 — the proxy injects tenant context |
| Manual header (advanced) | curl -H "x-tenant-slug: bph" https://sourcelibrary.org/api/books/library?limit=24 |
The /api/[tenant]/books/[id]/... paths that exist in the codebase are editor/processing routes (batch OCR, index rebuild, etc.) — not public catalogue listings.
These require a signed-in session cookie, editor role, or (for some dataset endpoints) a Bearer API key. Calling them without auth returns 401 or 403.
| Endpoint | Method | Purpose |
|---|---|---|
/api/books | POST | Create a new book (editor) |
/api/books/[id] | PATCH | Update book metadata (curator+) |
/api/books/[id]/batch-ocr-async | POST | Queue batch OCR job |
/api/books/[id]/batch-translate-async | POST | Queue batch translation job |
/api/pages/[id] | PATCH | Update page OCR/translation |
/api/jobs/[id]/process | POST | Async job processor (Lambda) |
Full narrative API walkthrough: docs/blog-source-library-api.md. MCP tools (search, quote, read): mcp-server/README.md.
All examples below hit production and need no API key. Replace the base URL with http://localhost:3000 when running locally (MongoDB + env vars required).
# Search translated text
curl -s "https://sourcelibrary.org/api/search?q=quintessence&limit=5" | jq .
# List books (global catalogue)
curl -s "https://sourcelibrary.org/api/books?limit=5" | jq .
# Browse with filters and sort
curl -s "https://sourcelibrary.org/api/books/library?limit=5&sort=recent-translation&has_translation=true" | jq .
# BPH catalogue — note /api/embed/bph/, NOT /api/bph/
curl -s "https://sourcelibrary.org/api/embed/bph/books?limit=5&translated=true" | jq .
# BPH via tenant_slug on the library endpoint
curl -s "https://sourcelibrary.org/api/books/library?tenant_slug=bph&limit=5" | jq .
# Book metadata (id or slug)
curl -s "https://sourcelibrary.org/api/books/know-thyself-reger-von-ehrenhart" | jq .
# Citable quote for a page
curl -s "https://sourcelibrary.org/api/books/6836f8ee811c8ab472a49e36/quote?page=57" | jq .
# Gallery search
curl -s "https://sourcelibrary.org/api/gallery?subject=alchemy&limit=5" | jq .
Pretty-printing with jq is optional; omit | jq . to see raw JSON.
https://sourcelibrary.org/api/embed/bph/bookslimit = 24, sort = title, translated = true200 with JSON body.
Public GET endpoints can be opened directly:
src/
├── app/ # 🎨 Next.js App Router
│ ├── book/[id]/ # 📖 Book detail, reading, processing
│ │ ├── page.tsx # Main book hub
│ │ ├── split/page.tsx # Split detection workflow
│ │ └── page/[pageId]/page.tsx # Individual page view
│ ├── api/ # 🔌 All API routes
│ │ ├── books/ # Book CRUD & batch ops
│ │ ├── pages/ # Page processing
│ │ ├── image/ # Image proxy & cropping
│ │ ├── jobs/ # Async job tracking
│ │ └── search/ # Full-text & semantic
│ ├── [tenant]/ # 🏢 Tenant subdomain routes
│ ├── gallery/ # 🖼️ Illustration browsing
│ ├── collections/ # 📑 Collection pages
│ └── admin/ # ⚙️ Admin dashboard
├── hooks/ # 🎣 Reusable React hooks
└── lib/ # 🛠️ Business logic & utilities
├── mongodb.ts # Database operations
├── image-extraction.ts # Illustration detection
└── auth-helpers.ts # Authentication utilities
scripts/
├── workers/ # ⚙️ Lambda worker functions
│ ├── pipeline-orchestrator.mjs # Main processing pipeline
│ ├── image-extract-worker.mjs # Gallery extraction
│ └── ...
├── maintenance/ # 🔧 One-off maintenance scripts
├── migrations/ # 📊 Database schema updates
└── audit-bph-leaks.mjs # 🔒 Tenant security verification
tests/
├── unit/ # ✔️ Vitest unit tests
└── integration/ # 🔗 Integration tests
prompts/ # 🤖 AI system prompts
├── ocr/
├── translation/
├── split-detection/
└── ...
.claude/ # 🧠 AI agent context
├── docs/ # 📚 Detailed architecture docs
├── skills/ # 🎯 Specialized agent skills
└── handoffs/ # 📋 Incident reports & lessons
// From the UI or via API
POST /api/books
{
"ia_id": "thehermetic00fludd",
"title": "The Hermetic and Alchemical Writings",
"author": "Arthur Edward Waite",
"language": "en",
"ustc_id": "123456"
}
The system:
/book/[id]/splitPOST /api/books/[id]/batch-ocr-async
{
"page_ids": ["page-1", "page-2", "page-3"],
"language": "la"
}
Returns a job ID; Gemini processes offline, saves results when complete. 50% cheaper than standard API.
POST /api/books/[id]/editions
{
"title": "The Emerald Tablet: First Complete English Translation",
"translator": "Jane Doe",
"language": "en",
"format": "epub"
}
System generates:
# Unit tests
npm run test:unit
# Integration tests
npm run test:integration
# End-to-end tests (Playwright)
npm run test:e2e
# Coverage report
npm run test:coverage
# Watch mode
npm run test:watch
Every pushed branch auto-deploys to Vercel preview:
git push origin feat/my-feature
# ↓ Vercel builds and deploys
# ↓ Preview URL in GitHub PR
Merge to main via PR → automatic Vercel deploy to sourcelibrary.org
✅ Pre-deployment checklist:
npm run test)npx tsc --noEmit)node scripts/audit-bph-leaks.mjs)Required (.env.local):
MONGODB_URI=mongodb+srv://...
NEXTAUTH_SECRET=<random-secret>
GOOGLE_API_KEY=<gemini-key>
VERCEL_BLOB_TOKEN=<vercel-blob-token>
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
Optional:
STRIPE_SECRET_KEY=<for-donations>
ZENODO_TOKEN=<for-doi-minting>
SUPABASE_URL=<for-embeddings>
We welcome contributions! Please follow our development workflow:
🌿 Create a feature branch (off main):
# Using git worktree for multi-session safety
git worktree add .claude/worktrees/feat-xyz feat/xyz
cd .claude/worktrees/feat-xyz
✏️ Make changes and test:
npm run lint
npm run test
npm run test:e2e
📤 Push and create a PR:
git push origin feat/xyz
gh pr create --base main
📋 PR guidelines:
grep -rn before deleting codenpx tsc --noEmit before submittingSee CLAUDE.md Security for detailed security policies.
As of July 2026 — these move weekly; live numbers at sourcelibrary.org/data.
📈 Active Corpus:
visible: true⚙️ Processing Capacity:
🏢 Platform Tenants:
Source Library is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). All contributions must respect this license.
See LICENSING.md for details on third-party licenses and attribution.
📖 Digitizing history. Making primary sources readable. Building open scholarship.
src/
├── app/ # All routes, pages, and API endpoints
│ ├── api/ # API routes
│ ├── book/ # Book pages (detail, read, pipeline)
│ └── page.tsx # Homepage
├── components/ # Reusable React components
├── hooks/ # Reusable React hooks for component logic
└── lib/ # Business Logic, Utilities (mongodb, ai, types), and Services
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp