# Calibre Library Curator

> Use this skill whenever the user wants to review, clean up, deduplicate, or standardize metadata in a Calibre ebook library via the calibredb CLI — merging duplicate/variant authors, publishers, or tags, enforcing Fiction/Nonfiction tagging, tidying series numbering, fixing malformed metadata, or doing a general "audit my library for inconsistencies" pass. Trigger on mentions of calibredb, "my calibre library", "duplicate authors/publishers/tags", "clean up my ebooks", or requests to standardize metadata across a book collection. This skill is opinionated. It encodes specific judgment calls (naming conventions, what counts as a real duplicate vs. a legitimate distinct tag, how to handle ambiguous classifications) learned from actual library-cleanup sessions — follow its heuristics rather than re-deriving policy from scratch each time.

- Skill: `jmhobbs/calibre-library-curator` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add jmhobbs/calibre-library-curator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jmhobbs/calibre-library-curator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: jmhobbs (https://skillmd.com/u/jmhobbs)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/jmhobbs/calibre-library-curator

---


# Calibre Library Curator

A workflow + opinionated policy set for auditing and cleaning a Calibre library
with the `calibredb` CLI. This is a **review-then-act** skill: Claude surfaces
candidates grouped for human judgment, only touches the library after explicit
per-group approval, and verifies afterward. Never do unattended bulk edits
that weren't approved for that specific group.

## 0. Locate the tool and library

Find `calibredb` first — it's commonly at
`/Applications/calibre.app/Contents/MacOS/calibredb` on macOS, or just
`calibredb` if it's on PATH. Confirm the library path (`--library-path` or
the tool's default) before doing anything else.

**Always use `--for-machine` for any listing/export command.** It returns
clean JSON instead of fragile human-formatted text, which matters a lot here
because author/publisher/tag strings routinely contain apostrophes, commas,
embedded quotes, and ampersands that break naive text parsing.

## 1. Duplicate/variant detection (authors, publishers, tags)

Pull full lists of authors, publishers, and tags with item counts
(`calibredb list_categories` or equivalent with `--for-machine`) and run
fuzzy matching to surface *candidate* duplicate clusters. Then apply these
filters before presenting anything to the user — a raw fuzzy match is very
noisy:

- **Check co-occurrence before flagging a pair as a duplicate.** If two
  similar-looking tags appear together on the same book, they are almost
  certainly a broad tag + a narrower/BISAC "sub" tag, not a typo pair (e.g.
  `African American & Black` + `African American & Black Studies` on the same
  book → leave both, don't merge).
- **Hierarchical tags are not duplicates.** `Fiction` vs `Historical Fiction`,
  `Science Fiction` vs `Hard Science Fiction`, `Development` vs
  `Developmental`, `Northwestern States` vs `Southwestern States` — these are
  genuinely distinct categories that fuzzy matching will false-positive on.
  Exclude them.
- **Punctuation/formatting variants are real duplicates**: trailing commas,
  curly vs straight quotes, missing hyphens, `Inc` vs `Inc.` vs `Incorporated`,
  credentials appended to a name (`Faith G. Harper` vs
  `Faith G. Harper, Phd, Lpc-S, Acs, Acn`), a BISAC code prefixed vs not
  (`COM046070 - COMPUTERS / ...` vs `COMPUTERS / ...` with the code just
  missing), `;` vs `&`/`,` as a separator artifact.
- **Use item counts to suggest — never silently pick — the canonical
  spelling.** Present the most-used variant as the recommendation, but always
  let the user confirm or override, especially for publisher names that might
  actually be distinct imprints (e.g. don't assume "Mango Media Inc" and
  "Mango Publishing Group" are the same company — ask).
- Present results grouped by category (Authors / Publishers / Tags) as a
  table or list with counts and a recommended canonical name, and flag
  open questions explicitly (which spelling to standardize on, whether two
  similar names are actually the same entity). Wait for the user's per-group
  decision before merging anything.

### Executing merges

- Merge by `calibredb search` to find affected books, then
  `calibredb set_metadata` per book. Run everything through subprocess with
  **argument lists, not shell strings** — these values routinely contain
  apostrophes and embedded quotes that break shell quoting.
  See `scripts/batch_set_metadata.py` for the pattern.
- **Test on 1–2 books first** before running a bulk batch, to confirm
  behavior for tricky fields (multi-value tags, publisher strings with
  commas) matches expectations.
- **After renaming/merging an author, always check and fix `author_sort`
  separately** — it does not auto-update via the CLI and will keep showing
  the old name in brackets in Calibre's UI otherwise. Match whatever
  `Last, First` (or other) convention the rest of the library already uses —
  check existing entries rather than assuming a format.
- After the batch completes, re-pull categories and confirm before/after
  counts and that no duplicate spellings remain.

### Malformed multi-author fields

Watch for author fields where multiple people got smashed into one bogus
"author" string because Calibre's separator (`&`) wasn't used — e.g. someone
entered `;` between names for a subset of authors on a book. This is a
**data-entry bug, not a duplicate-spelling issue**: flag it separately from
the merge review, and if approved, split it into proper individual author
entries joined with `&` on re-entry, then fix `author_sort` for each.

## 2. Tag hygiene beyond simple duplicates

Separately from duplicate detection, look for **raw BISAC/taxonomy path
strings living as tags** (e.g. `COMPUTERS / Security / Viruses & Malware`)
sitting alongside their already-split-out keyword tags. The default policy
(confirm with the user, but this is the right default):

- Remove the full `A / B / C` path-string tag.
- Ensure every component of that path ends up as its own individual tag.
- **Reuse existing tags where they already match** rather than creating new
  near-duplicates — including collapsing "and" vs "&" spelling so you don't
  end up with both "Software Development and Engineering" and the
  library's existing "Software Development & Engineering".
- Pull the *complete* list of path-string tags first (don't just fix the ones
  that happened to surface during the earlier duplicate scan) so the pass is
  exhaustive.

## 3. Format-driven tagging rules

Apply structural tagging rules across the whole library when asked, e.g.
"every `.cbz` should have `Comics & Graphic Novels`." Pull the full list of
matching books, note how many already have vs. need the tag, and **append**
to each book's existing tag list — never overwrite/replace it.

## 4. Fiction / Nonfiction coverage (or any universal-tag requirement)

When asked to ensure every book has exactly one of a pair of top-level tags:

- **Before introducing a new spelling, check what the library already uses.**
  If the user says `Non-Fiction` but the library already has `Nonfiction`
  (no hyphen) on other tags, point this out and recommend matching the
  existing convention rather than creating a second spelling — dedup effort
  is wasted if new near-duplicates get introduced in the same session.
- Triage books into confidence tiers rather than guessing uniformly:
  1. **Already compliant** — skip.
  2. **Parent-tag gaps** — book has `Juvenile Fiction`/`Young Adult
     Nonfiction`/etc. but not the plain parent tag. Trivial, high confidence.
  3. **High-confidence from other tags** — genre/subject tags that clearly
     imply Fiction or Nonfiction (Computers/Security/Cooking/Business →
     Nonfiction; Science Fiction/Media Tie-In/novel → Fiction). Spot-check
     the list for anything that looks misclassified before batch-applying.
  4. **No tag signal at all** — classify from title/author/genre knowledge,
     but split into "confident" vs. "genuinely unsure." For confident ones,
     proceed with the classification but tell the user what you did. For
     unsure ones, **export a CSV for the user to mark up and return** rather
     than guessing — include your proposed classification as a column so
     they can just confirm or correct it, and confirm explicitly whether
     "apply high-confidence automatically" also covers this whole tier or
     just the ones you're unsure about (this is an easy miscommunication —
     spell out the scope of what you're about to auto-apply).
- If there's a secondary tagging rule bundled in (e.g. "also make sure all
  cookbooks have `Cooking`"), fold it into the same batch pass rather than
  running two separate sets of `set_metadata` calls per book.
- One consolidated per-book update plan, then one batch execution, then
  verify — not per-rule passes that touch the same book multiple times.

## 5. Whole-library pattern sweep ("what are we doing more than one way")

When asked for this kind of audit, split findings into two buckets and
present both, don't just fix things silently:

**A. Inconsistent conventions** (multiple ways of doing the same thing) —
things like: series metadata (`series`/`series_index`) set for some
multi-volume works but not others despite "Volume 1"/"Series 2" being right
in the title; a tag re-introduced as a near-duplicate during a later pass
(catch tag redundancy that sneaks back in after later tagging work — always
re-check the full tag list, not just the tags touched in the current pass);
inconsistent author attribution (some multi-author comics have real credits,
others are lazily set to `Unknown` when the info is knowable); mixed file
formats where one book has redundant copies in two formats; a metadata field
that's essentially unused library-wide (worth flagging even if not "wrong").

**B. Likely mistakes** (wrong regardless of style) — true duplicate book
entries (same author/file/everything, accidental double-import); wrong-edition
metadata (e.g. language/publisher/ISBN belonging to a different translation
than the actual file — **search online to confirm and fix the correct
edition's metadata** rather than just flagging it); malformed identifier
fields (e.g. an ISBN landing in the identifier-*type* slot instead of the
value slot); broken or duplicate `series_index` values across volumes of the
same series (verify the correct reading/publication order before fixing);
orphaned `series_index` with no `series` name set.

Note: Calibre sets `series_index` to `1.0` as its universal default for
**every** book without a series — this is not a real stored value and
doesn't need to be "removed" from a standalone book; it's indistinguishable
from any other non-series book and only becomes meaningful once a `series`
name is set. Don't waste an operation trying to strip it.

Offer the user two paths: work through findings one at a time, or knock out
the clearly-mistaken/clear-cut items immediately while leaving genuine
judgment calls (ambiguous language/edition calls, whether an "Unknown" author
is fixable, imprint-vs-company questions) for explicit sign-off.

## 6. New-book intake (e.g. a fresh batch from Project Gutenberg or similar)

When the user adds a batch of same-source books and asks for tidy-up:

- Pull full current metadata for just the new batch first.
- Research anything uncertain (translation edition, anthology contents,
  which volume of a multi-volume work) **before** writing synopses/comments
  for all of them, not after — verify first, write once.
- Apply consistent publisher/tag conventions, and retroactively apply the
  same convention to any older books from the same source already in the
  library, so the whole source-group stays consistent (don't leave the old
  ones on a different convention just because they predate this pass).
- Link series membership the same way the rest of the library does it
  (numbered by publication order unless there's a clear canonical order).
- Do a spot-check pass after applying comments/descriptions in bulk —
  mismatched volume descriptions (e.g. swapping Volume 1 and Volume 2
  synopses) are an easy mistake when writing several similar comments at
  once.
- Flag genuine content overlaps (e.g. a story that's both a standalone entry
  and included in an anthology already in the library) as a note, not an
  automatic fix — that's a curation choice, not a metadata error.

## General execution principles

1. **Never touch the library before presenting findings and getting a
   per-group decision.** Batches should be scoped to what was actually
   approved.
2. **JSON in, argument-list subprocess out.** `--for-machine` for reads,
   Python subprocess with arg lists (never shell strings) for
   `set_metadata` writes.
3. **Test small, then batch, then verify.** Run 1–2 books, confirm behavior,
   run the full batch, then re-pull categories/counts to confirm the
   before/after state matches what was approved.
4. **Match existing conventions over introducing new ones** — naming
   (`Last, First`, tag spelling, hyphenation) should follow whatever the
   majority of the library already does, surfaced to the user as a
   recommendation rather than assumed.
5. **When confidence is low, export a CSV for markup** rather than guessing
   silently — include your proposed answer as a column so the user can
   confirm-in-bulk instead of typing from scratch.
6. **Re-verify after every batch**: category counts, spot-checks on a few
   affected books, and confirmation that no new near-duplicates were
   introduced by the fix itself.

See `scripts/batch_set_metadata.py` for a reusable, safe pattern for
batched `set_metadata` calls (arg-list subprocess, per-book error capture,
dry-run mode).

