Source Library

io.github.Embassy-of-the-Free-Mind由 GitHub 账号 Embassy-of-the-Free-Mind 发布v4.13.0更新于 Nov 6, 2026

Search 15K rare pre-modern texts translated to English: philosophy, religion, science, literature.

发布方自己的服务:Source

已验证Streamable HTTP可网页运行知识与记忆媒体与设计

概览

AI 生成的概览

Source Library 的远程 MCP 服务器,让助手检索、阅读并引用带英译和页面图像的前现代珍本古籍。

可以做什么
  • 按主题、作者、语言、类别或年代检索书目,并确认馆内是否藏有某部作品
  • 按关键词或语义查找可引用的段落,也可在单本书内检索
  • 读取书籍元数据、章节目录与全文,再获取逐字引文及引用链接,支持单页或批量
  • 查看同一作品的不同版本,并把 Bekker、Stephanus 等经典编号定位到具体书页
  • 检索历史插图和艺术作品,并列出图像检索可用的筛选值
  • 向图书馆团队提交反馈、研究档案和专题书目提案,并参与志愿校对班次
适用场景
适合需要依据历史作者原话作答的场合:引文与出处、学习或教学用的一手史料、某一观念在前现代时期的面貌,或一幅旧插图。它不涵盖现代学术研究和时事。
运行要求
使用 sourcelibrary.org 上的远程 streamable HTTP 端点;无需安装软件包,也未声明 API 密钥或环境变量。公开读取接口据说明无需认证。
安装前请注意
校对班次和盲审会让助手阅读并评判书页,submit_page_review 与 propose_correction 会把评判结果和修改提交到馆藏内容。submit_feedback、share_findings 和 propose_collection 会把材料发送给图书馆团队。README 还记录了需登录会话或 API 密钥的编辑接口,可新建或修改书籍与页面,不属于公开读取工具。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Source Library,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.Embassy-of-the-Free-Mind%2Fsourcelibrary/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "source-library": {
      "type": "http",
      "url": "https://sourcelibrary.org/api/mcp"
    }
  }
}

README

[Source Library Logo]

Source Library

A digital library of historical primary sources with AI-aided OCR, translation, and scholarly curation.

[License: AGPL v3] [Next.js] [MongoDB] [Postgres Supabase] [Gemini API]

🌐 Visit Library • 📖 Docs • 🗺️ System Map • 🤝 Contribute


🎬 Experience Source Library

Your browser does not support the video tag.

Explore thousands of digitized historical texts with AI-enhanced translations and scholarly curation.


🎯 About Source Library

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.

🌟 Why Source Library?

  • ✨ Originals First — Read the original language text with AI-enhanced translations alongside
  • 🎓 Citable Scholarship — Every book gets a DOI and scholarly metadata (USTC alignment, edition tracking)
  • 🏛️ Partner Subdomains — Institutions like the Bibliotheca Philosophica Hermetica curate reading rooms on their own domains
  • 🔍 Discovery — Collections, galleries of illustrations, and semantic search surface overlooked texts
  • ✅ Rigorous QA — Manual verification, image quality scoring, and OCR validation before publication

The platform ingests ~15K pages monthly from Internet Archive, Gallica, Bodleian, Wellcome, and other digital heritage partners.


🚀 Quick Start

💻 Development Environment

bash
# 🍴 Clone and installgit clone https://github.com/Embassy-of-the-Free-Mind/sourcelibrary-v2.gitcd sourcelibrary-v2npm install
# ⚙️ Configure environment (see .env.example for required variables)# Must include: MongoDB Atlas connection, Google Gemini API key, Vercel Blob token
# ▶️ Start dev servernpm run dev

Open http://localhost:3000


📋 Tech Stack

🎨 FrontendNext.js 16, React 19, TailwindCSS, Lucide icons
⚙️ BackendNext.js API routes, AWS Lambda for async processing
💾 DatabaseMongoDB Atlas (primary), Supabase (embeddings)
🤖 AI/MLGoogle Gemini 3.1 (OCR, translation, summarization)
🗂️ StorageVercel Blob (images), AWS S3 (archive), Cloudflare R2 (archive)
🔐 AuthNextAuth v5 with MongoDB adapter
🚀 DevOpsVercel (hosting), GitHub (VCS), Playwright (E2E tests)
✔️ TestingVitest (unit/integration), Playwright (E2E)
🔎 SearchPostgreSQL FTS + semantic search via Supabase

📦 Key Dependencies:

  • sharp — Image resizing and cropping
  • @google/generative-ai — Gemini API integration
  • xml2js — USTC metadata parsing
  • @modelcontextprotocol/sdk — MCP server for agent integration
  • stripe — Donation and subscription handling

📚 Core Features

📖 Reading & Navigation

  • ⚡ Page pagination — Instant navigation between 100+ pages
  • 🔍 Full-text search — Query across OCR'd text and translations
  • 📌 Quote generation — Copy and cite passages with DOI links

🔄 Processing Pipeline

  • 🧩 Smart split detection — Automatic gutter detection for two-page spreads (Gemini AI or ML-based)
  • ✍️ High-accuracy OCR — Gemini Vision API with language-specific models (Latin, German, Greek, Arabic, etc.)
  • 🗣️ Context-aware translation — Maintains continuity across pages for scholarly accuracy
  • 🖼️ Gallery extraction — AI-powered detection and cataloging of illustrations

🎨 Curation & Discovery

  • 📑 Themed collections — Editorial collections (e.g., "Alchemy & Transmutation," "Kabbalah & Mysticism")
  • 🏛️ Gallery browsing — Curated images from all books (museum-quality metadata)
  • 📚 Related editions — Link across translations, reprints, and derivative works
  • 🔗 Authority linking — Connect to USTC, VIAF, and other scholarly databases

📤 Scholarly Export

  • 📱 EPUB generation — Multi-format ebook export
  • 📄 PDF with annotations — Preserve layout, add scholarly notes
  • 🆔 DOI minting — Version books via Zenodo integration for long-term citation

🏢 Tenant Subdomains

  • 🏛️ Isolated reading rooms — Partners host curated subsets on custom domains (e.g., bph.sourcelibrary.org)
  • 🎨 Branding & navigation — Full UI customization per tenant
  • 🔒 Access control — Public or members-only collections

🏗️ Architecture Overview

📊 Data Model

📚 Books contain structured metadata:

  • 🏛️ Bibliographic — Title, author, language, publication date, USTC ID
  • 🖼️ Images — Links to source (Internet Archive, Gallica, etc.), archival status
  • ⚙️ Processing — OCR status, translation language, extraction metadata
  • 🎨 Curation — Collections, tier (featured/standard), visibility flags

📄 Pages store individual page data:

  • 📸 Original image — Source photo or PDF page
  • ✂️ Split coordinates — Crop boundaries (0-1000 scale) for two-page spreads
  • ✍️ OCR output — Raw Gemini extraction + language metadata
  • 🗣️ Translation — English translation with scholarly notes
  • 🖼️ Illustrations — Detected images with quality scores and descriptions

🖼️ Gallery images are extracted illustrations:

  • 🏷️ Metadata — Subject, figures, symbols, style, techniques, period
  • ⭐ Quality score — 0–1.0 rating (filters below 0.5)
  • 🔗 Provenance — Source book and page, linked back

🎨 Image Tier System

All page images are resized on-demand via /api/image:

TierDimensionsQuality📱 Use Case
Thumbnail400px wide70% JPEGGrids, navigation, social sharing
Display1200px wide80% JPEGMain reading view, comfortable for annotation
Full2400px wide90% JPEGMagnifier, fullscreen detail, printing

Split pages are cropped non-destructively via coordinates; original images are always preserved.

🔄 Processing Pipeline

📥 Import → ✂️ Split Detection → ✍️ OCR → 🗣️ Translation → 🎨 Enrichment → 🌍 Publishing
  1. 📥 Import — Upload images, import from IA/Gallica via IIIF, or paste URLs
  2. ✂️ Split Detection — Detect two-page spreads; mark crop boundaries
  3. ✍️ OCR — Gemini Vision extracts text per page language
  4. 🗣️ Translation — Gemini translates to English with prior-page context for continuity
  5. 🎨 Enrichment — Extract illustrations, generate summaries, assign collections
  6. 🌍 Publishing — Set visible: true, mint DOI, push to search index

Batch endpoints process up to 5 pages/request using Gemini Batch API (50% cheaper).

🔌 API Routes (Key)

Base URL: https://sourcelibrary.org (production) or http://localhost:3000 (local dev with .env.local configured).

Common 404 mistake: paths like /api/bph/books or /api/bph/books/[id] do not exist. BPH catalogue APIs live under /api/embed/bph/.... There is also no top-level /api/[tenant]/books route — tenant book listings use /api/books/library or the embed routes below.

Public read APIs (no auth required today)
EndpointMethodPurpose
/api/search?q=<query>GETFull-text search across books and page translations
/api/books?limit=100&offset=0GETSimple book list (global catalogue; visible: true, indexed only)
/api/books/library?limit=100&skip=0GETRich browse API — search, sort, filters, collections
/api/books/[id]GETBook metadata (accepts Mongo id or slug)
/api/books/[id]/quote?page=<n>GETCitable quote + formatted citations (inline, footnote, BibTeX, DOI)
/api/gallery?limit=24GETIllustration / artwork search
/api/image?url=<encoded-url>&w=400GETOn-demand image resize & crop
/api/embed/bph/books?limit=24GETBPH catalogue (paginated, searchable)
/api/embed/bph/books/[slug]GETSingle BPH book detail
/api/embed/bph/featuredGETFeatured BPH books
/api/embed/bph/collectionsGETBPH collection list
/api/embed/bph/languagesGETBPH language facets
/api/embed/bph/suggest?q=alchGETBPH search autocomplete
/api/embed/bph/statsGETBPH catalogue stats
Tenant-scoped listing (not /api/bph/...)

Use one of these patterns to filter by partner tenant (e.g. BPH):

ApproachExample
Embed prefix (recommended for BPH)GET /api/embed/bph/books?limit=24
Library API + query paramGET /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.

Authenticated / internal APIs

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.

EndpointMethodPurpose
/api/booksPOSTCreate a new book (editor)
/api/books/[id]PATCHUpdate book metadata (curator+)
/api/books/[id]/batch-ocr-asyncPOSTQueue batch OCR job
/api/books/[id]/batch-translate-asyncPOSTQueue batch translation job
/api/pages/[id]PATCHUpdate page OCR/translation
/api/jobs/[id]/processPOSTAsync job processor (Lambda)

Full narrative API walkthrough: docs/blog-source-library-api.md. MCP tools (search, quote, read): mcp-server/README.md.

🧪 Trying the API (curl, Postman, browser)

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).

curl
bash
# Search translated textcurl -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 sortcurl -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 endpointcurl -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 pagecurl -s "https://sourcelibrary.org/api/books/6836f8ee811c8ab472a49e36/quote?page=57" | jq .
# Gallery searchcurl -s "https://sourcelibrary.org/api/gallery?subject=alchemy&limit=5" | jq .

Pretty-printing with jq is optional; omit | jq . to see raw JSON.

Postman
  1. Create a new GET request.
  2. Set URL to e.g. https://sourcelibrary.org/api/embed/bph/books
  3. On the Params tab add query keys: limit = 24, sort = title, translated = true
  4. Leave Auth as No Auth for the public endpoints above.
  5. Send — expect 200 with JSON body.

[Get Books]

Browser

Public GET endpoints can be opened directly:

📁 Directory Structure

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

🔄 Common Workflows

📥 Importing Books from Internet Archive

typescript
// From the UI or via APIPOST /api/books{  "ia_id": "thehermetic00fludd",  "title": "The Hermetic and Alchemical Writings",  "author": "Arthur Edward Waite",  "language": "en",  "ustc_id": "123456"}

The system:

  1. 📥 Fetches page images from IA IIIF
  2. ✂️ Detects splits and generates crop coordinates
  3. 📤 Queues for OCR and translation
  4. 🌍 Publishes when processing completes

✂️ Processing a Split Book

  1. 🖥️ Visit /book/[id]/split
  2. 🖱️ Adjust split line visually (drag or Gemini AI auto-detection)
  3. ✅ Click "Apply Split" — creates two virtual pages with crop coordinates
  4. 📸 Original images preserved; OCR runs on cropped versions

✍️ Batch OCR with Gemini Batch API

typescript
POST /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.

🎓 Generating a Scholarly Edition

typescript
POST /api/books/[id]/editions{  "title": "The Emerald Tablet: First Complete English Translation",  "translator": "Jane Doe",  "language": "en",  "format": "epub"}

System generates:

  • 📝 Scholarly front matter (introduction, translator bio, etc.)
  • 📱 EPUB with TOC and metadata
  • 🆔 DOI via Zenodo integration
  • 📚 Citation metadata (BibTeX, RIS)

🧪 Testing

🚀 Run Tests

bash
# Unit testsnpm run test:unit
# Integration testsnpm run test:integration
# End-to-end tests (Playwright)npm run test:e2e
# Coverage reportnpm run test:coverage
# Watch modenpm run test:watch

✅ E2E Test Examples

  • 📥 Book import — Validate IA ingestion pipeline
  • ✂️ Split detection — Verify gutter detection accuracy
  • 🌐 Translation — Confirm source/translation alignment
  • 🔒 Tenant subdomain — Ensure content isolation (no leaks)
  • 🔍 Search — Test full-text and semantic indexing

🚀 Deployment

🔄 Staging (Preview)

Every pushed branch auto-deploys to Vercel preview:

bash
git push origin feat/my-feature# ↓ Vercel builds and deploys# ↓ Preview URL in GitHub PR

🌍 Production

Merge to main via PR → automatic Vercel deploy to sourcelibrary.org

✅ Pre-deployment checklist:

  • Tests pass (npm run test)
  • TypeScript check passes (npx tsc --noEmit)
  • No hardcoded secrets or credentials
  • Tenant subdomain leak audit passes (node scripts/audit-bph-leaks.mjs)
  • PR reviewed and approved

🔑 Environment Variables

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-1AWS_ACCESS_KEY_ID=...AWS_SECRET_ACCESS_KEY=...

Optional:

STRIPE_SECRET_KEY=<for-donations>ZENODO_TOKEN=<for-doi-minting>SUPABASE_URL=<for-embeddings>

📖 Documentation


🤝 Contributing

We welcome contributions! Start with CONTRIBUTING.md — setup, the branch/PR workflow, how deploys work (and the Vercel setup you should NOT do), and the data-safety rules. Deeper doctrine lives in the development workflow. The short version:

  1. 🌿 Create a feature branch (off main):

    bash
    # Using git worktree for multi-session safetygit worktree add .claude/worktrees/feat-xyz feat/xyzcd .claude/worktrees/feat-xyz
  2. ✏️ Make changes and test:

    bash
    npm run lintnpm run testnpm run test:e2e
  3. 📤 Push and create a PR:

    bash
    git push origin feat/xyzgh pr create --base main
  4. 📋 PR guidelines:

    • One concern per PR — Don't bundle refactors with features
    • Verify deletions — Always grep -rn before deleting code
    • Run type check — npx tsc --noEmit before submitting
    • Describe scope — State what's in scope AND out of scope

🎯 What We're Looking For

  • 🐛 Bug fixes with test coverage
  • ✨ Feature implementations aligned with project mission
  • ⚡ Performance improvements with benchmarks
  • 📝 Documentation improvements
  • ♿ UX/accessibility enhancements
  • 🏢 Tenant integration examples

📢 Reporting Issues

  • 🐛 Bugs — Include reproduction steps, expected vs. actual behavior
  • 💡 Feature requests — Explain the use case and user impact
  • ❓ Questions — Open an issue

🛡️ Security & Data Protection

  • 🚫 No deletion without approval — All book/page deletions require explicit confirmation
  • 🔒 Tenant isolation — Tenant subdomains are closed systems (no cross-tenant leaks)
  • 🔐 Secret management — All secrets via environment variables, never hardcoded
  • ⚖️ AGPL licensing — Contributions must respect AGPL-3.0-or-later

See CLAUDE.md Security for detailed security policies.


📊 Current Status

As of July 2026 — these move weekly; live numbers at sourcelibrary.org/data.

📈 Active Corpus:

  • 📚 ~29K books with visible: true
  • ✅ ~15K fully processed (OCR'd and translated)
  • 🌍 ~14K with full English translations
  • 🖼️ 200K+ catalogued illustrations in the gallery

⚙️ Processing Capacity:

  • 📥 15K+ pages/month ingestion
  • 🗣️ Multi-language support (Latin, German, Greek, Arabic, Sanskrit, Chinese, etc.)
  • 💰 Batch API for 50% cost reduction

🏢 Platform Tenants:


📝 License

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.


📞 Support & Community


📖 Digitizing history. Making primary sources readable. Building open scholarship.

↑ Back to top

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

来源:README.md,提交 df6bf3f

工具

22

search_library

Search Library

RETURNS A LIST OF BOOKS (works on a topic) — NOT passages. PICK THIS to discover which works exist on a subject. → For quotable text use search_translations (exact words) or search_concept (by meaning); if the user already named an author/work, call get_book directly (or list_books to find the ID) — the AI summary + chapter outline is usually the right first answer. Searches titles, authors, subjects, and (as a secondary signal) translated text. Query tips: single distinctive words or short phrases work best ("memory palace", "ouroboros"); quoted phrases match exactly. Each result includes total_matches (full count) + returned (this page) + offset for pagination. To answer "do you hold X?" call check_duplicate, not this: a ranked list is not a holdings check.

输入参数sortlimitquery必填offsetyear_tolanguageyear_fromhas_translation

search_translations

Search Translations

RETURNS QUOTABLE PASSAGES (page-level snippets + citation URLs), matched by KEYWORD/term. PICK THIS to find a quote or textual evidence on a topic across the whole library. → If the modern word won't literally appear in historical texts, use search_concept (matches by meaning); to list which BOOKS cover a topic use search_library; to dig inside one known book use search_within_book; if the user named an author/work, get_book first (its AI summary is usually the right first read). Query tips: a distinctive term ("wax tablet") or the sentence you are looking for both work; matching is by word, and a page that prints your words together and in order ranks above one that scatters them. Each passage carries phrase_match (0-1, absolute, not relative to the other results): 1 means the page prints your whole query in order at one place, 0 means your words occur only apart; when every passage is under about 0.2 the library probably does not print that sentence, so try search_concept. It is absent for a one-word query and for a passage found by meaning alone. found_by says which lane found the page: "keyword", "semantic", or "both" (the strongest signal). Each snippet has a snippet_type — "translation"/"ocr" means it is a verbatim extract from the source text; "summary" means it is AI-generated description (do not quote those as the author's words). Response includes total_matches, returned, and offset for pagination. Cross-cultural tip: for pre-modern or non-Western topics, search source-tradition vocabulary rather than modern English terms — e.g. for seminal economy search "jing" or "bindu" or "istimnāʾ", not "semen retention"; for female homoeroticism search "tribade" or "sahq", not "lesbian". The corpus is indexed via period translations that use tradition-internal terminology.

输入参数langlimitquery必填authoroffsetbook_idyear_tolanguagediversitylanguagesyear_frommax_per_work另有 3 个

search_concept

Search by Concept

RETURNS QUOTABLE PASSAGES matched by MEANING (cosine similarity on Gemini embeddings, 768d) — paraphrases and adjacent phrasings match even with zero keyword overlap. PICK THIS when the modern term won't literally appear in historical texts — e.g. "distributed cognition" maps to passages about active intellect, art of memory, wax tablet metaphors; "social contract" maps to pre-Hobbesian discussions of consent and authority. → For exact words/distinctive terms use search_translations (cheaper, more precise); to list which BOOKS cover a topic use search_library; if the user named an author/work, get_book first (semantic search is expensive — reserve it for cross-corpus discovery). Similarity calibration: 0.70+ is a strong match, 0.55–0.70 is worth reading but verify, below 0.55 is mostly conceptual drift. Set max_per_book to diversify results across many books rather than cluster on one source. Each passage carries a snippet_type — quote only "translation" snippets, never "summary". Cross-cultural tip: for pre-modern or non-Western topics, also try source-tradition vocabulary — e.g. for seminal economy try "jing preservation" or "bindu yoga" or "istimnāʾ"; for masturbation try "mollities" (Latin) or "hastamaithuna" (Sanskrit) or "shouyin" (Chinese). The corpus is indexed via period translations that use tradition-internal terminology, so adjacent/euphemistic terms often surface material that modern English keywords miss.

输入参数langlimitquery必填authoryear_tolanguagediversitylanguagesyear_frommax_per_bookmax_per_workmax_per_author另有 2 个

search_within_book

Search Within Book

SEARCHES INSIDE ONE BOOK (requires book_id). PRIMARILY KEYWORD: it runs a lexical search over the book's pages plus a narrow scoped-semantic pass (top ~10), interleaved by relevance. PICK THIS when you know the wording you are looking for, or want every page of one book mentioning a term. → IF YOU ARE SEARCHING FROM A PARAPHRASE, a half-remembered line, or a modern restatement, USE search_concept INSTEAD — it is the meaning-matching tool and it searches the whole corpus, including translations whose vocabulary differs completely from yours (Thomas Taylor writes "energies" for energeia and "felicity" for eudaimonia, so a sensible modern paraphrase can miss his pages entirely while matching semantically). → To find the book first, use search_library or search_concept, then pass its book_id here. Results are ordered by relevance within this book. Each carries score (0-1, ABSOLUTE, not relative to the other results, so a query the book cannot answer scores low everywhere): the higher of similarity (raw cosine from the meaning pass, calibrated like search_concept: 0.70+ strong, 0.55–0.70 verify, below 0.55 drift) and phrase_match (how much of a multi-word query the page prints in order at one place; 1 is all of it; a one-word query the page prints scores 1). Each also carries found_by ("keyword", "semantic", or "both" — both is the strongest signal). Results flagged is_front_matter are the translator's or publisher's words rather than the author's, and are ordered last. Returns OCR and translation snippets with page numbers, ready to cite.

输入参数langquery必填offsetbook_id必填

list_books

List Books

BROWSES/FILTERS THE CATALOG by metadata (canonical author via author_id, title/author/summary words via search, language, category, year range, translation recency) — no page-text matching. PICK THIS to see WHAT EXISTS by an author or in a tradition, or to enumerate a date range. Returns books with title, author (string + canonical author_id + author_url), language, year, and translation progress. → For a relevance-ranked topic search use search_library; for passages on a theme use search_translations (exact words) or search_concept (by meaning). To answer "do you hold X?" call check_duplicate: a listing that misses a title is not evidence of absence.

输入参数sortlimitoffsetsearchwork_idyear_tocategorylanguageauthor_idyear_fromedition_keyhas_edition

get_book

Get Book

READ PIPELINE step 1 — DISCOVER. START HERE for any named work or author. Returns the book's AI-generated summary, chapter list, edition metadata, DOI, page counts, IIIF manifest, and the cover image (inline, so you and the user can see the book). LANGUAGE: `language` is what is printed on THIS EDITION's leaves, which is frequently not the language the work was written in. Where the record knows they differ the response also carries `work_language` and a `translation_note`, and `text_role` (original / period-translation / modern-translation / unclassified) says what kind of witness this is — read them before describing a passage as the author's own words, because an edition can be a translation of a translation (de Slane's 1863 French Muqaddimah, read in English, is English←French←Arabic). Absent `work_language` means the work's language is NOT RECORDED on this record. It is not a statement that the edition is in the work's own language (most records have never been checked; Risner's 1572 Latin Alhazen carries none, and the work is Arabic). Only `text_role: "original"` asserts that these are the author's own words in the author's language; `text_role: "unclassified"` means nobody has examined it, so do not infer the work's language from `language`, and do not conclude the library lacks a tradition because a `language` filter came back empty. Use list_editions to find an original-language witness. The summary is typically a multi-paragraph orientation covering the book's argument, structure, and significance — often answering the question without further searching. Then: get_book_text to read a chapter or page range (step 2), get_quote / get_quotes to lock specific pages with full citation apparatus (step 3). search_within_book locates passages inside this book. MULTI-WORK VOLUMES: where the scans carry running heads, contains_works lists the works the volume ACTUALLY holds with their page spans, taken from the heads the printer put on each leaf. Trust it over the ti

输入参数book_id必填

get_book_text

Read Book Text

READ PIPELINE step 2 — READ. Read a book's text. Call get_book first (step 1) for the chapter list, then come here. Preferred: use the chapter param to read one chapter at a time (includes [Page N] markers for citation). Alternatively, use from/to for explicit page ranges (e.g. from=1 to=50). When you find passages worth quoting, hand the page numbers to get_quote / get_quotes (step 3) for verbatim text + a citation link. TRUNCATION: the response always includes truncated: true/false. When truncated=true, the truncation_note field gives the exact next from/to values to call — this means content was cut short by a page-budget limit, NOT that the book ended. An AI agent MUST NOT infer end-of-book from pages_returned alone; check truncated first. Daily page budgets apply across get_book_text/get_quote/get_quotes: anonymous 500 pages/24h, signed-in 1,000, free Explorer keys 2,000, paid keys uncapped — sign in at sourcelibrary.org/auth/signin or get a key at sourcelibrary.org/developers. Corpus-scale text belongs on the dataset API (sourcelibrary.org/dataset), not on this tool.

输入参数tofromlangpartformatbook_id必填chaptercontent

get_quote

Get Quote

READ PIPELINE step 3 — CITE. Get the exact verbatim text of a single page plus its citation apparatus. ALWAYS use before putting text in quotation marks. The response headline is citation_link (the stable sourcelibrary.org/q/… shortlink) — present it to the user alongside the quote. Render as: > [exact translation text, verbatim] > — [Author], [citation.locator]. [citation_link] PAGE BREAKS: this corpus is paginated from physical leaves, and nearly one prose page-boundary in five has a sentence running across it — sometimes a word split by a hyphen ("…our move-" / "movements…"). A page that opens or breaks off mid-sentence still reads as complete prose and still carries a perfectly valid citation, so check the continuity field on every response BEFORE quoting: if continues_on_next or continues_from_previous is true, call again with context: true and quote the whole sentence. Quoting a fragment as though it were the author's complete thought is a misattribution even when the page number is right. NON-LATIN SCRIPTS: where the page is Greek, Hebrew, Arabic, Sanskrit, Cyrillic and so on, the response also carries romanized — the romanization of the original — so the citation can be shown in three layers: original → romanized → translation → citation_link. It is AI-generated reading apparatus, not a transcription; quote the source from original or translation, never from romanized. Absent on Latin-script pages and on non-Latin pages not yet romanized. ENGLISH ORIGINALS: where the leaf is already English there is no translation and none is needed — the response omits `translation`, sets `text_source: "ocr_original"`, and the verbatim text is `original` (with a `transcription_note`). Quote it as the source's own words, never as a translation, and expect period spelling and long-s (ſ) — it is an uncorrected transcription of the scan. `text_source` is on every response (`translation` otherwise), so branch on it rather than guessing from pages_translated, which is 0 for an En

输入参数langpage必填book_id必填contextinclude_image

list_editions

List Editions of a Work

Every edition of one work that the library holds — the other witnesses to the same text, across languages and centuries. Give it a book_id (easiest: the id of any edition you already found) or a work_id. USE THIS when a quotation needs checking against more than one witness, when you want the original-language text behind a translation, or when comparing how a passage reads across editions — differences between witnesses are often the finding. Returns language, date, page count and translation coverage per edition, so you can pick the right one to read. Note: for multi-volume collected works the identifier names the SET rather than a single text, and the response says so explicitly when that applies.

输入参数book_idwork_id

check_duplicate

Check Holdings

DOES THE LIBRARY HOLD THIS WORK? Call this BEFORE telling the user the library lacks a book, and before proposing one for acquisition. A miss from list_books or search_library is NOT evidence of absence: list_books matches words and search_library ranks by relevance, so a held book can sit behind dozens of better-ranked hits. Give a title + author (+ year if known), or a library URL (Internet Archive, Gallica, e-rara, BSB, a IIIF manifest). Matches the same scan, the same edition, other editions and the same work, plus near and cross-lingual titles (title in any language). Returns a verdict (same_object / same_edition / possible_same_edition / other_edition / related_title / new), confidence, matches with reasons, ids and URLs, held_not_public (copies held but not yet published: counted, not described), and limits (what the check could not search). A "new" verdict from a URL alone has not searched other editions; pass the title and author too.

输入参数urlyearia_idtitleauthorlanguage

get_quotes

Get Quotes (batch)

READ PIPELINE step 3 — CITE, in batch. Get verbatim text + citation_link for SEVERAL pages of a single book in one round-trip, to assemble a multi-passage dossier. Specify either pages (an explicit array, e.g. [12, 40, 41]) or an inclusive from/to range. Max 25 pages per call. Each entry carries its own citation_link to present alongside the quote, and — on non-Latin-script pages that have one — a romanized layer to show between the original and the translation (AI apparatus, not a transcription). Every entry also carries `text_source`: `translation` normally, or `ocr_original` on a leaf that is already English, where the verbatim text is `original` and must be attributed as the source's own words rather than as a translation. One batch can mix both — a Latin volume can hold an English preface. Batch pages count toward the shared daily page budget (see get_book_text); this is a citation tool, and corpus-scale extraction belongs on the dataset API (sourcelibrary.org/dataset).

输入参数tofromlangpagesbook_id必填include_image

search_images

Search Images

Search 200,000+ historical illustrations, emblems, engravings, diagrams, AND 24,000+ artworks (paintings, prints, sculptures). Filter by type, subject, figure, symbol, year. Results interleave two collections: illustrations extracted from book pages (each with a page number and book link) and standalone museum artworks (type: "artwork"). The first few results also return as inline images YOU can see. Hosts that support MCP Apps render an in-chat image gallery for this tool automatically; on other clients images may sit inside the collapsed tool-result view, so never tell the user images are "rendered above" unless the gallery appeared — describe what you see and give each image's url link instead. Every image_url is public and stable — an HTML page that references them directly works in any online browser. If images.length is 0, read the note field — an empty result under a book_id filter means that book has no EXTRACTED images yet, not that the physical book has no plates. A broad query can match tens of thousands (read total): narrow with type/subject/symbol (exact tag strings; look them up with list_image_facets) or page with offset instead of raising limit. On museum-artwork results, a title_is_descriptive flag means the title is an AI description of the picture rather than a title the work was published under — cite such a record by its source_record_title, never by the descriptive one (#4288).

输入参数typelimitqueryfigureoffsetsymbolbook_idsubjectyear_toyear_frominclude_thumbnail_base64

list_image_facets

List Image Facets

List the legal values of search_images' type, subject, figure and symbol filters, with how many images carry each. Those filters are EXACT string matches on tags an AI extractor wrote, and each vocabulary runs to thousands of strings (e.g. "musical notes", "Jesus Christ", "medicinal plants"), so a guessed value usually matches nothing. Look it up here first. Call with no facet for the top values of all four; with facet + contains to find the exact spelling of a term ("ouro" → "ouroboros"). Counts cover book illustrations of visible books only (the museum-artwork collection is not counted), and only strings on 3 or more images are listed; the list is refreshed weekly. If contains finds nothing, the tag is absent or rare: use it as free text in search_images' query instead. No URL in this result is a browse page; link images from search_images results.

输入参数facetlimitcontains

submit_feedback

Submit Feedback

Submit feedback, bug reports, or feature requests to the Source Library team. Before proposing NEW functionality, read https://sourcelibrary.org/llms.txt and https://sourcelibrary.org/developers — several past submissions proposed building things that already exist (IIIF manifests, Content Search, DTS), which wastes reviewer time. State in the report which docs you checked. Bug reports with record IDs and reproducing queries are the most actionable kind.

输入参数nameemailmessage必填

share_findings

Share Findings

Share a research dossier back to the Source Library team — a title, an optional summary, and an ordered list of citations (the passages your thesis rests on). Each citation is a reference { book_id, page, note }, NOT copied text: the library re-renders the canonical quote from the reference, so links stay authoritative. Use this when the user has assembled a thesis backed by passages across one or more books and wants to contribute it back. Like submit_feedback, this goes to the team for review (not an instant public page).

输入参数nameemailtitle必填summarycitations必填

propose_collection

Propose a Collection

Propose a themed collection of books to the Source Library team — a title, a rationale (why these books belong together and what thread connects them), and an ordered list of book ids. Get book ids from search_library / list_books / get_book. Like submit_feedback and share_findings, this goes to the team for REVIEW — it does NOT create a public collection instantly; a curator reviews and approves it. Use this when the user has identified a coherent set of books worth grouping and wants to contribute that curation back.

输入参数nameemailtitle必填book_ids必填rationale必填suggested_slug

start_review_shift

Start a Review Shift

Start a volunteer REVIEW SHIFT: the user lends their Claude (you) to Source Library to check one book, page by page, against its scans. Use when the user wants to help Source Library, says "start a shift" or "review pages", or asks how they can contribute. The user does NOT need to read the book's language: YOU do the checking (scan against transcription, transcription against English) and the user starts the shift, chooses how many pages, watches and asks questions. Returns ONE page: its scan (inline image), our transcription, our English, the last lines of the previous page, and next (pass to continue_review_shift). Follow first_time once, then how_to_run on every page, working through the stretch of pages without stopping between them. With no book, it resumes the user's last run (pass volunteer_code) or picks a book that needs checking; book takes an id, slug or reader URL if the user names one; new_book true skips the resume. Run shifts only while the user is in this conversation; never set one up to run on a schedule or from a script.

输入参数booklanguagenew_bookvolunteer_code

continue_review_shift

Continue a Review Shift

Next page of the book being reviewed. Call it straight after finishing a page until the stretch the user chose is done, and again when they ask for more. Pass next.book and next.after from the previous page, and volunteer_code. Returns the same shape as start_review_shift; follow how_to_run again. When page is null the book is finished: say so and offer start_review_shift with new_book true.

输入参数book必填after必填volunteer_code必填

start_blind_check

Start a Blind Check (for readers of the language)

OPTIONAL lane, only for a user who reads the original language and asks to judge pages themselves: up to five random pages from different books, each with scan, transcription and English. Here the USER is the reviewer: ask for THEIR verdict first, before any opinion of yours, then give your reading with exact quotes, let them accept or reject each point, and call submit_page_review with mode "blind" and their final verdict. Never choose the verdict for them. For everyone else use start_review_shift.

输入参数pageslanguagevolunteer_code

submit_page_review

Submit a Page Review

Record the verdict on one page of a shift. mode "book-run" (start_review_shift / continue_review_shift): the verdict and findings are YOURS, from reading the scan and both texts; set user_looked true if the user checked anything on the page themselves. mode "blind" (start_blind_check): the verdict is the USER'S, given before your reading; put yours in assistant_verdict. Verdicts: both_sound (transcription matches the scan and the English matches the original), translation_drift (transcription right, English departs from it), transcription_off (the text does not match the scan), both_off, unclear (the scan or the text cannot be judged). Quote exact words in every finding. A review is evidence about the page; it does not change it.

输入参数modenamenotebook_iditem_id必填verdict必填shift_idpage_numberuser_lookedtext_versionfirst_verdictvolunteer_code必填另有 5 个

propose_correction

Propose a Correction

During a review shift, propose a correction to a page's transcription (field "ocr") or English (field "translation"). A correction is a list of exact span edits: each "find" must be copied exactly from the text the shift returned and occur once on the page (add surrounding words if it repeats); "replace" is the corrected text ("" deletes). Fix only what the scan or the original shows is wrong: misread letters, dropped or added words, a sentence the English skips. Do not restyle or modernise. Propose transcription fixes before translation fixes, as separate calls. Pass base_hash = page.text_version for that field. A proposal does NOT change the page: it is applied only after a second reader agrees, and the volunteer is credited. If the call says the page changed since it was loaded, say so and move on. drafted_by: "assistant" if you found and worded it in a book run, "volunteer" if the user supplied the wording, "assistant_accepted" if you drafted it and the user approved it specifically, "mixed" otherwise.

输入参数namenoteedits必填field必填item_id必填shift_idbase_hash必填drafted_by必填volunteer_code必填assistant_model必填

get_locus

Find a Canonical Reference (Bekker / Stephanus)

Turn a CANONICAL CITATION into the actual leaves that carry it. Aristotle is cited by Bekker number (1094a8, 1447a) and Plato by Stephanus number (Rep. 328b) — the references scholarship has used for centuries, which survive re-typesetting and are shareable in a way a scan page never is. USE THIS FIRST whenever a passage arrives as a canonical reference rather than a page: do not try to derive the page yourself from a book's pagination, which is what produced a wrong guess before this tool existed. Bekker numbers are unique across the whole Aristotelian corpus, so the number alone is enough and it also tells you WHICH WORK you are citing. Stephanus numbers restart in each of the three 1578 volumes, so pass work ("Republic", "Timaeus") — without it the response lists the candidate dialogues instead of choosing one. Returns every witness the library holds: the Greek reference edition and, where we have one, an English translation of the same lines, each with its scan page, a reader URL and a quote_api link — so you can compare the original against a translation at one reference. Then call get_quote with the returned book_id + page for the verbatim text and a citable shortlink. LIMITS, stated plainly: a witness is only returned where the reference is PRINTED on that leaf (or, in the two root editions, where a verified constant offset brackets it) — nothing is interpolated, so an empty result means this library holds no anchored leaf there, NOT that the citation is wrong; editions_searched shows what was consulted and the range each covers. Line numbers (the "8" of 1094a8) are not resolved — you get the right leaf and read the line off it. Two works can share a page where one ends and the next begins (Bekker 184 and 1447 are both such joins), and each leaf is filed by the running head printed on it, so a reference at the very start of a work may come back under its predecessor — always read other_works_at_this_reference before concluding a passage is absent. A bare numb

输入参数worksystemreference必填

版本历史

2
  1. v4.13.0最新Nov 6, 2026
  2. v4.3.4Sep 16, 2026

评分

已满足适用检查项的 100%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

其他 Source 集成