Calibre Metadata Apply
v1.0.4Primary skill for Calibre metadata edits (write operations) over a running Content server. Use ONLY when the user explicitly requests changing/editing/fixing...
Security Scan
OpenClaw
Suspicious
medium confidencePurpose & Capability
Name/description align with required binaries and behavior: it legitimately requires `calibredb` and Node, and the main declared credential is CALIBRE_PASSWORD. The included scripts implement metadata lookups, dry-run/apply flow, and run-state management consistent with an edit/apply skill.
Instruction Scope
SKILL.md and scripts stick to metadata-edit workflows, but the skill explicitly supports using a subagent for heavy analysis and notes that 'text/metadata sent to subagent can reach model endpoints configured by runtime profile.' That means metadata (and possibly other text) can be forwarded to external model endpoints unless the caller disables subagent processing. The scripts also read local dotfiles (.env in cwd and ~/.openclaw/.env) automatically to hydrate env vars, which may pull unrelated secrets into the process if present. The README/policy allow saving auth and even saving plain passwords if the user requests it—this broadens the data surface beyond the simple 'apply metadata' claim.
Install Mechanism
No external installer or remote download is declared; this is instruction+scripts only. That keeps install risk low because nothing is fetched from arbitrary URLs during install.
Credentials
The registry lists only CALIBRE_PASSWORD as required, which is appropriate, but the code automatically hydrates .env files (process.cwd()/.env and ~/.openclaw/.env) and will set any variables found there. That can unexpectedly import unrelated secrets into the skill's environment. The script also can accept/insert a plaintext password onto calibredb command lines (it builds commands with `--password <value>` if `auth.password` is present) and the README documents optional saving of auth (including a --save-plain-password option). These behaviors increase the chance credentials are exposed (process lists, logs, or config files).
Persistence & Privilege
The skill writes local state at skills/.../state/runs.json (declared) and documents an auth cache at ~/.config/calibre-metadata-apply/auth.json; README explicitly allows saving auth and even plain passwords via `--save-plain-password`. 'always' is false, and the skill does not request system-wide privileges, but the optional persistent storage of credentials (including plaintext) and retained run state are notable persistence/privacy concerns.
What to consider before installing
This skill is functionally coherent for editing Calibre metadata, but review and limit sensitive behaviors before use:
- Avoid storing credentials in plaintext. Do not use `--save-plain-password`. Prefer exporting CALIBRE_PASSWORD in the environment and pass via `--password-env CALIBRE_PASSWORD` rather than inline `--password` on the command line.
- Be aware the scripts automatically load .env files from the current directory and ~/.openclaw/.env. Remove unrelated secrets from those files (e.g., AWS keys) or run the skill from a clean working directory.
- The skill can delegate heavy analysis to a subagent/model. If metadata or book-related text is sensitive, disable subagent orchestration or ensure the configured model endpoints are trusted; otherwise metadata may be sent to external model endpoints.
- Inspect or audit the included scripts (calibredb_apply.mjs, run_state.mjs, handle_completion.mjs) in your environment before running. Confirm that you’re comfortable with the local state file location (skills/.../state/runs.json) and the documented auth cache (~/.config/calibre-metadata-apply/auth.json).
- Prefer dry-run and explicit user approval before any `--apply`. The skill’s required flow includes a dry-run first; follow that.
What would raise confidence to High: a) the author/owner is known and trusted, b) removal or hardening of plaintext password saving and explicit disabling of inline `--password` usage in code, and c) a configurable opt-out that prevents automatic .env hydration and disables subagent/model delegation by default.scripts/calibredb_apply.mjs:97
Shell command execution detected (child_process).
scripts/handle_completion.mjs:35
Shell command execution detected (child_process).
Patterns worth reviewing
These patterns may indicate risky behavior. Check the VirusTotal and OpenClaw results above for context-aware analysis before installing.Like a lobster shell, security has layers — review code before you run it.
Runtime requirements
Binsnode, calibredb
EnvCALIBRE_PASSWORD
Primary envCALIBRE_PASSWORD
latest
calibre-metadata-apply
A skill for updating metadata of existing Calibre books.
Skill selection contract (strict)
- If the user intent is metadata edit/fix/update, this skill is mandatory.
- If the request mentions an ID together with edit/fix/update intent (e.g.
ID1011 タイトル修正,ID1011 のタイトルを直して), this skill is mandatory. - If the request mentions an ID but only for viewing/checking/confirming (e.g.
ID1021 を確認して,ID1021 の詳細), do NOT use this skill — route tocalibre-catalog-read. calibre-catalog-readmust not be used for those edit intents.
Use this skill when the user asks any of:
- "ID指定でタイトル修正"
- "メタデータ編集"
title/authors/series/series_index/tags/publisher/pubdate/languagesupdates
Do NOT use this skill for:
- Read-only lookups (e.g. "ID 1021 を確認して", "ID 1021 の情報を見せて", "show me book 1021")
- Checking what metadata a book currently has without intent to change it
- Those must use
calibre-catalog-read
Requirements
calibredbmust be available on PATH in the runtime environmentsubagent-spawn-command-builderinstalled (for spawn payload generation)pdffontsis optional/recommended for PDF evidence checks- Reachable Calibre Content server URL
http://HOST:PORT/#LIBRARY_ID- If
LIBRARY_IDis unknown, use#-once to list available IDs on the server.
--with-librarycan be omitted only when one of these is configured:- env:
CALIBRE_WITH_LIBRARYorCALIBRE_LIBRARY_URLorCALIBRE_CONTENT_SERVER_URL - optional library id completion:
CALIBRE_LIBRARY_ID
- env:
- Read the "Calibre Content Server" section of TOOLS.md for the correct
--with-libraryURL. - Host failover (IP change resilience):
- Optional env:
CALIBRE_SERVER_HOSTS=host1,host2,... - Script auto-tries candidates, including WSL host-side
nameserverfrom/etc/resolv.conf.
- Optional env:
- If authentication is enabled, prefer
/home/altair/.openclaw/.env:CALIBRE_USERNAME=<user>CALIBRE_PASSWORD=<password>
- Auth scheme policy for this workflow:
- Non-SSL deployment assumes Digest authentication.
- Do not pass auth mode arguments such as
--auth-mode/--auth-scheme.
- Pass
--password-env CALIBRE_PASSWORD(username auto-loads from env) - You can still override explicitly with
--username <user>.
Supported fields
Direct fields (set_metadata --field)
titletitle_sortauthors(string with&or array)author_sortseriesseries_indextags(string or array)publisherpubdate(YYYY-MM-DD)languagescomments
Helper fields
comments_html(OC marker block upsert)analysis(auto-generates analysis HTML for comments)analysis_tags(adds tags)tags_merge(defaulttrue)tags_remove(remove specific tags after merge)
Required execution flow
A. Target confirmation (mandatory)
- Run read-only lookup to narrow candidates
- Show
id,title,authors,series,series_index - Get user confirmation for final target IDs
- Build JSONL using only confirmed IDs
B. Proposal synthesis (when metadata is missing)
- Collect evidence from file extraction + web sources
- Show one merged proposal table with:
candidate,source,confidence (high|medium|low)title_sort_candidate,author_sort_candidate
- Get user decision:
approve allapprove only: <fields>reject: <fields>edit: <field>=<value>
- Apply only approved/finalized fields
- If confidence is low or sources conflict, keep fields empty
C. Apply
- Run dry-run first (mandatory)
- Run
--applyonly after explicit user approval - Re-read and report final values
Analysis worker policy
- Use
subagent-spawn-command-builderto generatesessions_spawnpayload for heavy candidate generationtaskis required.- Profile should include model/thinking/timeout/cleanup for this workflow.
- Use lightweight subagent model for analysis (avoid main heavy model)
- Keep final decisions + dry-run/apply in main
Data flow disclosure
- Local execution:
- Build
calibredb set_metadatacommands from JSONL. - Read/write local state files (
state/runs.json).
- Build
- Subagent execution (optional for heavy candidate generation):
- Uses
sessions_spawnviasubagent-spawn-command-builder. - Text/metadata sent to subagent can reach model endpoints configured by runtime profile.
- Uses
- Remote write:
calibredb set_metadataupdates metadata on the target Calibre Content server.
Security rules:
- Prefer env-based password (
--password-env CALIBRE_PASSWORD) over inline--password. - If user does not want external model/subagent processing, keep flow local and skip subagent orchestration.
- In agent/chat execution, do not call
calibredbdirectly for edit operations.- Always execute
node skills/calibre-metadata-apply/scripts/calibredb_apply.mjs.
- Always execute
- Never run
calibre-serverfrom this skill.- This workflow always targets an already-running Calibre Content server.
Connection bootstrap (mandatory)
- Do not ask the user for
--with-libraryfirst. - First, execute using saved defaults (env) with no explicit
--with-library.- Scripts auto-load
.envand resolveCALIBRE_WITH_LIBRARY/CALIBRE_CONTENT_SERVER_URL.
- Scripts auto-load
- Ask user for URL only when command output shows unresolved connection, such as:
missing --with-libraryunable to resolve usable --with-library- repeated connection failures for all candidates
Long-run turn-split policy (library-wide)
For library-wide heavy processing, always use turn-split execution.
Unknown-document recovery flow (M3)
Batch sizing rule:
- Keep each unknown-document batch small enough to show full row-by-row results in chat (no representative sampling).
- If unresolved items remain, stop and wait for explicit user instruction to start the next batch.
User intervention checkpoints (fixed)
-
Light pass (metadata-only)
- Always run this stage by default (no extra user instruction required)
- Analyze existing metadata only (no file content read)
- Present a table to user:
- current file/title
- recommended title/metadata
- confidence/evidence summary
- Stop and wait for user instruction before any deeper stage
-
On user request: page-1 pass
- Read only the first page and refine proposals
- Report delta from light pass
-
If still uncertain: deep pass
- Read first 5 pages + last 5 pages
- Add web evidence search
- Produce finalized proposal with confidence + rationale
-
Approval gate
- Show detailed findings and request explicit approval before apply
Pending and unsupported handling
- Use
pending-reviewtag for unresolved/hold items. - If document is unresolved in current flow, do not force metadata guesses.
- Tag with
pending-reviewand keep for follow-up investigation.
- Tag with
Diff report format (for unknown batch runs)
Return full results (not samples):
- execution summary (target/changed/pending/skipped/error)
- full changed list with
id+ key before/after fields - full pending list with
id+ reason - full error list with
id+ error summary - confidence must be expressed as
high|medium|low
Runtime artifact policy
- Keep run-state and temporary artifacts only while a run is active.
- On successful completion, remove per-run state/artifacts.
- On failure, keep minimal artifacts only for retry/debug, then clean up after resolution.
Internal orchestration (recommended)
- Use lightweight subagent for all analysis stages
- Keep apply decisions in main session
- Persist run state for each stage in
state/runs.json
Turn 1 (start)
- Main defines scope
- Main generates spawn payload via
subagent-spawn-command-builder(profile example:calibre-meta), then callssessions_spawn - Save
run_id/session_key/taskviascripts/run_state.mjs upsert - Immediately tell the user this is a subagent job and state the execution model used for analysis
- Reply with "analysis started" and keep normal chat responsive
Turn 2 (completion)
- Receive subagent completion notice
- Save result JSON
- Complete state handling via
scripts/handle_completion.mjs --run-id ... --result-json ... - Return summarized proposal (apply only when needed)
Run state file:
state/runs.json
PDF extraction policy
- Try
ebook-convertfirst - If empty/failed, fallback to
pdftotext - If both fail, switch to web-evidence-first mode
Sort reading policy
- Use user-configured
reading_scriptfor Japanese/non-Latin sort fieldskatakana/hiragana/latin
- Ask once on first use, then reuse for the session
- Default policy is full reading (no truncation)
- Read the "Calibre Content Server" section of TOOLS.md for the configured
reading_scriptvalue; pass it as a CLI argument when needed.
Usage
Dry-run:
cat changes.jsonl | node skills/calibre-metadata-apply/scripts/calibredb_apply.mjs \
--with-library "http://127.0.0.1:8080/#MyLibrary" \
--password-env CALIBRE_PASSWORD \
--lang ja
Dry-run (when default library is preconfigured via env/config):
cat changes.jsonl | node skills/calibre-metadata-apply/scripts/calibredb_apply.mjs \
--password-env CALIBRE_PASSWORD \
--lang ja
Apply:
cat changes.jsonl | node skills/calibre-metadata-apply/scripts/calibredb_apply.mjs \
--with-library "http://127.0.0.1:8080/#MyLibrary" \
--password-env CALIBRE_PASSWORD \
--apply
Do not
- Do not run direct
--applyusing ambiguous title matches only - Do not include unconfirmed IDs in apply payload
- Do not auto-fill low-confidence candidates without explicit confirmation
- Do not start a local server with guessed path like
~/Calibre Library
Comments
Loading comments...
