Use when the user asks about a Calibre ebook library or book collection: find books, search metadata or full text in EPUB/AZW3 files, or locate book paths via Calibre databases.
98
98%
Does it follow best practices?
Impact
99%
1.80xAverage score across 4 eval scenarios
Passed
No known issues
Use this file when you need exact CLI syntax, expected output shape, or script-specific failure handling.
These conventions apply to all scripts in scripts/:
--help (all scripts expose usage text)."error": human-readable message"error_code": stable machine-readable code (e.g., BOOK_NOT_FOUND, DB_NOT_FOUND)0 for success, non-zero for failure.All scripts are in scripts/.
Set these first or substitute explicit paths in each command:
export CALIBRE_LIBRARY_ROOT="/path/to/Calibre Library"
export CALIBRE_METADATA_DB="$CALIBRE_LIBRARY_ROOT/metadata.db"
export CALIBRE_FTS_DB="$CALIBRE_LIBRARY_ROOT/full-text-search.db"If you need to discover the DB locations:
find "$HOME" -name metadata.db 2>/dev/null
find "$HOME" -name full-text-search.db 2>/dev/nullfind_books.pysearch_content.pyget_excerpt.pyquery-book.shresolve_book.pylist_books.pyinspect_calibre_metadata.pyfind_books.py - Search by title or authorFast path for title and author lookup. Typical runtime is under 0.1s.
python3 scripts/find_books.py \
--db-path "$CALIBRE_METADATA_DB" \
--query "The Problems of Philosophy" \
--limit 5Typical output:
[
{
"id": 4,
"title": "The Problems of Philosophy",
"authors": "Bertrand Russell"
}
]If there are no matches, it prints []. Retry with fewer words, an author surname, or list_books.py --limit 200.
Exact title matches are ranked ahead of looser substring matches.
search_content.py - Search book textSearches the Calibre full-text index. Prefer --book-id whenever possible.
Within a specific book:
python3 scripts/search_content.py \
--fts-db "$CALIBRE_FTS_DB" \
--metadata-db "$CALIBRE_METADATA_DB" \
--book-id 4 \
--query "knowledge" \
--context 400Optional: add --format EPUB to force a specific format.
Across all books:
python3 scripts/search_content.py \
--fts-db "$CALIBRE_FTS_DB" \
--metadata-db "$CALIBRE_METADATA_DB" \
--query "artificial intelligence" \
--limit 10When scoped to --book-id, the script searches one preferred text source and returns multiple occurrences from that book instead of one duplicate row per format.
If there are no matches, it prints []. Invalid --book-id values return {"error": "Book N not found", "error_code": "BOOK_NOT_FOUND"}.
get_excerpt.py - Pull a longer passageGet a larger excerpt around a keyword or absolute character position.
python3 scripts/get_excerpt.py \
--fts-db "$CALIBRE_FTS_DB" \
--metadata-db "$CALIBRE_METADATA_DB" \
--book-id 4 \
--around "knowledge" \
--chars 800Optional: add --format EPUB to keep the excerpt aligned with a specific content search result.
Options:
--around "keyword" centers the excerpt on the first occurrence--occurrence N uses the Nth occurrence instead of the first--position N centers on a character position--chars N sets excerpt length, default 800Common failures are JSON objects like:
{"error": "Book 4 not found", "error_code": "BOOK_NOT_FOUND"}{"error": "No text found for book 4", "error_code": "BOOK_TEXT_MISSING"}{"error": "Keyword 'X' not found in book", "error_code": "KEYWORD_NOT_FOUND", "book_id": 4, "title": "The Problems of Philosophy"}The successful response also includes the chosen format.
query-book.sh - One-liner wrapperWrapper that combines find plus content search.
./scripts/query-book.sh "The Problems of Philosophy" "knowledge"
./scripts/query-book.sh --id 4 "knowledge"Use this when the user names one book and wants a fast, single-command lookup.
The wrapper prefers an exact title match when one exists. If a partial title matches multiple books, it exits with an ambiguity list instead of silently picking the first result.
resolve_book.py - Resolve a filesystem pathResolve a Calibre book ID to a concrete file path.
python3 scripts/resolve_book.py \
--metadata-db "$CALIBRE_METADATA_DB" \
--library-root "$CALIBRE_LIBRARY_ROOT" \
--book-id 4 \
--format EPUBIf the preferred format is missing, the script falls back to the first available format and returns available_formats.
Format matching is case-insensitive, so --format epub works.
If exists is false, the Calibre metadata is stale or the file moved.
list_books.py - Browse titles alphabeticallyUseful when fuzzy title or author searches keep returning [].
python3 scripts/list_books.py \
--db-path "$CALIBRE_METADATA_DB" \
--limit 200inspect_calibre_metadata.py - Sanity-check metadata accessUse this to confirm that metadata.db is readable and inspect summary counts plus a small sample of books.
python3 scripts/inspect_calibre_metadata.py \
--db-path "$CALIBRE_METADATA_DB" \
--limit 20It returns counts such as book_count, author_count, format_counts, and sample_books.
find_books.py returns a JSON array. Empty results are [], not errors.search_content.py returns a JSON array for successful searches and a JSON error object for invalid --book-id, missing text, or empty queries.get_excerpt.py and resolve_book.py return JSON objects and use an "error" field for invalid book IDs, missing text, bad positions, or missing formats.book_id fails unexpectedly, rerun find_books.py first to confirm the title and author mapping before assuming the content index is wrong.--book-id searches whenever possible. Global content searches have to scan the full-text index and are much slower.evals
scenario-1
scenario-2
scenario-3
scenario-4
references
sample-library
Arthur C. Clarke
Warp Drive Studies (993)
Bertrand Russell
The Problems of Philosophy (4)
The Problems of Philosophy (997)
Jules Verne
Leviathan Under the Pacific (998)
Twenty Thousand Leagues under the Sea (1)
Twenty Thousand Leagues under the Sea (999)
Karl Marx
The Communist Manifesto (6)
The Communist Manifesto (995)
The Prince of the Workers (994)
scripts