CLI tool for organizing books and PDFs with AI-powered metadata
Project description
wst — Wan Shi Tong
"I am Wan Shi Tong, he who knows ten thousand things."
Character from Avatar: The Last Airbender. Avatar: The Last Airbender is a trademark of Viacom International Inc. Image used for illustrative purposes only.
CLI tool for organizing books and PDFs with AI-powered metadata generation.
Named after Wan Shi Tong, the ancient spirit who collected every piece of knowledge in the world and guarded the great library in the desert. This tool aspires to do the same for your PDFs — just with less hostility toward humans.
Features
- AI-powered metadata: Automatically extracts and completes metadata (title, author, type, year, summary, tags, etc.) using Claude CLI with web search for missing fields (year, ISBN, publisher)
- OCR support: Optionally OCR scanned PDFs before ingestion to extract text from image-based documents
- Metadata enrichment: Fill in missing fields (ISBN, table of contents, publisher, year) on existing documents using AI + web search, individually or in batch
- Organized library: Files sorted by type (
books/,papers/,notes/,exercises/,guides/) with consistent naming (Author - Title (Year).pdf) - SQLite search index: Full-text search across title, author, tags, subject, and summary via FTS5
- Coverage stats: See metadata completeness across your library, broken down by document type and field
- Interactive browser: Fuzzy-search your library, view and edit metadata interactively
- Cloud backup: Backup files to iCloud Drive or S3, with extensible provider system
- Extensible backends: Abstract layers for AI (Claude CLI, future API/SDK) and storage (local filesystem, S3)
Installation
pipx (recommended, all platforms)
pipx install wst-library
pip
pip install wst-library
Homebrew (macOS/Linux)
brew tap cnexans/tap
brew install wst
Chocolatey (Windows)
choco install wst
From source
git clone https://github.com/cnexans/wst.git
cd wst
make install
Quick Start
# Ingest PDFs from a folder
wst ingest ~/Documents/papers/
# Ingest from default inbox (~/wst/inbox/)
wst ingest
# Ingest with OCR for scanned PDFs
wst ingest --ocr
# Ingest with manual confirmation for each file
wst ingest --confirm
# Re-ingest files with fresh AI metadata
wst ingest --reprocess
# Search
wst search "machine learning"
wst search --author "Knuth"
wst search --type textbook
# List and show
wst list
wst list --type paper --sort year
wst show 1
# Edit metadata
wst edit 1
wst edit "Player's Handbook"
wst edit 42 --enrich # fill missing fields with AI + web search
# Enrich missing metadata in batch
wst fix --dry-run # preview what needs fixing
wst fix --type textbook # fix all textbooks
wst fix --field isbn --field toc # only fill ISBN and TOC
wst fix -y # auto-accept all changes
# Metadata coverage stats
wst stats
wst stats --type textbook
# Interactive browser
wst browse
# Backup
wst backup icloud
wst backup s3
Commands
| Command | Description |
|---|---|
wst ingest [PATH] |
Ingest PDFs, generate metadata with AI. Options: --ocr, --confirm, --reprocess, --verbose |
wst search <query> |
Full-text search. Options: --author, --type, --subject |
wst list |
List all documents. Options: --type, --sort |
wst show <id-or-title> |
Show complete metadata for a document |
wst edit <id-or-title> |
Edit metadata interactively, or --enrich to fill missing fields with AI |
wst fix |
Batch enrich documents with missing metadata. Options: --type, --field, --dry-run, -y |
wst stats |
Show metadata coverage statistics. Options: --type |
wst browse |
Interactive TUI for browsing and editing documents |
wst ocr <id-or-path> |
Run OCR on scanned PDFs |
wst backup [provider] |
Backup files to iCloud or S3 |
How Ingestion Works
PDF file → [OCR (optional)] → Extract text + PDF metadata → AI generates metadata → Store + Index
- OCR (optional,
--ocr): Scanned PDFs are processed withocrmypdfto extract text from images before metadata generation. - Text extraction: Reads existing PDF metadata and text from the first pages using PyMuPDF.
- AI metadata generation: Sends the text sample to Claude CLI, which analyzes the content and uses web search to find ISBN, publisher, year, and other fields.
- Storage: Files are moved to the library, organized by document type with consistent naming (
Author - Title (Year).pdf). - Indexing: Metadata is stored in SQLite with full-text search (FTS5).
After ingestion, use wst fix to batch-enrich documents that are missing fields (ISBN, table of contents, etc.) — this is especially useful for scanned books where the initial AI pass may not have found all metadata.
Library Structure
~/wst/
├── inbox/ # PDFs pending ingestion
└── library/
├── books/ # book, novel, textbook
├── papers/ # paper
├── notes/ # class-notes
├── exercises/ # exercises
├── guides/ # guide-theory, guide-practice
└── wst.db # SQLite index
Documentation
See docs/README.md for architecture details and diagrams.
Requirements
- Python 3.11+
- AI backend (at least one):
claudeCLI (authenticated) — default backendcodexCLI (authenticated) — use withwst -b codex
- macOS, Windows, or Linux
Releasing
To publish a new version to PyPI:
# 1. Bump version in pyproject.toml
# 2. Trigger the release workflow from GitHub Actions:
gh workflow run "Create Tag and Release" \
--field version="X.Y.Z" \
--field release_notes="Release notes here"
This creates a git tag, a GitHub Release, and publishes to PyPI automatically.
License
MIT with Commons Clause — free to use, modify, and distribute. Commercial sale rights reserved to the author. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wst_library-0.9.0.tar.gz.
File metadata
- Download URL: wst_library-0.9.0.tar.gz
- Upload date:
- Size: 55.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3d8e01181756600db566ddae0b8aa7ce91f3ecbb246235f740a6527348229e2
|
|
| MD5 |
49b33a0e79ea5ba3245dfe0365ef1e6e
|
|
| BLAKE2b-256 |
b9204a337c0333fd8385f661e98aad511c01f696479e3fe323d48f927e163adb
|
File details
Details for the file wst_library-0.9.0-py3-none-any.whl.
File metadata
- Download URL: wst_library-0.9.0-py3-none-any.whl
- Upload date:
- Size: 48.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
008991d3e08f9ec64098c02065c31d7da359cdc45236905e29eb00c20e540b22
|
|
| MD5 |
50bab25e7044b2df2725af42feda6342
|
|
| BLAKE2b-256 |
6417700a36c539df1f695012b368e5b9c85347a3b6994e6ab53c0079f134b1d0
|