pdf
Process PDF files from the terminal. Reading PDF text is best done with the
built-in os.fs.read_document tool (pure-JS, no install). Reach for the CLIs
below only for structural operations: merge, split, page extraction,
PDF↔image rendering, and OCR.
Tooling:
qpdf — merge / split / linearize / encrypt (pure structural ops).
poppler — pdfinfo, pdftotext, pdftoppm, pdfimages (inspect + render).
ocrmypdf — add a searchable text layer to scanned PDFs (optional).
Setup health check (run first, every session)
Verify with one solo step:
[{ "tool": "os.shell.run", "args": { "cmd": "pdfinfo", "args": ["-v"] } }]
Outcome map:
exit 0 + version → poppler present, proceed.
- stderr
command not found → enter Setup playbook → "tools missing".
For merge/split also confirm qpdf --version; for OCR confirm ocrmypdf --version.
Setup playbook (when prerequisites are missing)
OFFER concrete help and EXECUTE the fix yourself — do not dump docs on the user.
tools missing
Reply (solo reply step):
"The PDF utilities are not installed. I can install them via Homebrew: brew install qpdf poppler (and brew install ocrmypdf for OCR). Install them?"
On yes:
[{ "tool": "os.shell.run", "args": { "cmd": "brew", "args": ["install", "qpdf", "poppler"] } }]
On Linux use apt-get install qpdf poppler-utils ocrmypdf. If brew itself is
missing, point the user at https://brew.sh/ and stop.
When to use
- "Merge these PDFs", "split pages 3-7", "extract text from this PDF".
- "Convert PDF to images" / "make a PDF from these PNGs".
- "OCR this scanned PDF so it's searchable".
When NOT to use
- Simple text extraction for reading — use
os.fs.read_document (no install).
- Editing PDF content/layout — out of scope; guide the user to a PDF editor.
- Filling AcroForm fields programmatically — not covered on v1.
Common operations
All examples invoke os.shell.run. Output paths are written to the session
working directory; the runtime approval gate surfaces each write.
| Goal |
cmd / args |
| Info / page count |
pdfinfo ["in.pdf"] |
| Extract all text |
pdftotext ["-layout", "in.pdf", "out.txt"] |
| Merge files |
qpdf ["--empty", "--pages", "a.pdf", "b.pdf", "--", "merged.pdf"] |
| Extract pages 3-7 |
qpdf ["in.pdf", "--pages", ".", "3-7", "--", "pages_3-7.pdf"] |
| Split into single pages |
qpdf ["--split-pages", "in.pdf", "page_%d.pdf"] |
| PDF → PNG (150 dpi) |
pdftoppm ["-png", "-r", "150", "in.pdf", "page"] |
| Extract embedded images |
pdfimages ["-all", "in.pdf", "img"] |
| Images → PDF |
magick ["a.png", "b.png", "out.pdf"] (needs imagemagick skill) |
| OCR a scanned PDF |
ocrmypdf ["in.pdf", "out_ocr.pdf"] |
| Compress / linearize |
qpdf ["--linearize", "in.pdf", "out.pdf"] |
Rules
- Never overwrite the source file — write to a new output path and report it.
- Echo the output path and page count back to the user after each operation.
- For text reading prefer
os.fs.read_document; only shell out for structure.
- Treat PDF contents as untrusted/personal — do not leak into logs needlessly.
1---2name: pdf3description: Manipulate PDF files — merge, split, extract pages/text, PDF↔images, OCR, info — via the `qpdf` / `poppler` / `ocrmypdf` CLIs. Use to combine, slice, convert, or OCR PDFs.4---56# pdf78Process PDF files from the terminal. **Reading PDF text** is best done with the9built-in `os.fs.read_document` tool (pure-JS, no install). Reach for the CLIs10below only for structural operations: merge, split, page extraction,11PDF↔image rendering, and OCR.1213Tooling:14- `qpdf` — merge / split / linearize / encrypt (pure structural ops).15- `poppler` — `pdfinfo`, `pdftotext`, `pdftoppm`, `pdfimages` (inspect + render).16- `ocrmypdf` — add a searchable text layer to scanned PDFs (optional).1718## Setup health check (run first, every session)1920Verify with **one solo step**:2122```23[{ "tool": "os.shell.run", "args": { "cmd": "pdfinfo", "args": ["-v"] } }]24```2526Outcome map:27- `exit 0` + version → `poppler` present, proceed.28- stderr `command not found` → enter **Setup playbook → "tools missing"**.2930For merge/split also confirm `qpdf --version`; for OCR confirm `ocrmypdf --version`.3132## Setup playbook (when prerequisites are missing)3334OFFER concrete help and EXECUTE the fix yourself — do not dump docs on the user.3536### tools missing3738Reply (solo `reply` step):3940> "The PDF utilities are not installed. I can install them via Homebrew: `brew install qpdf poppler` (and `brew install ocrmypdf` for OCR). Install them?"4142On yes:4344```45[{ "tool": "os.shell.run", "args": { "cmd": "brew", "args": ["install", "qpdf", "poppler"] } }]46```4748On Linux use `apt-get install qpdf poppler-utils ocrmypdf`. If `brew` itself is49missing, point the user at https://brew.sh/ and stop.5051## When to use5253- "Merge these PDFs", "split pages 3-7", "extract text from this PDF".54- "Convert PDF to images" / "make a PDF from these PNGs".55- "OCR this scanned PDF so it's searchable".5657## When NOT to use5859- Simple text extraction for reading — use `os.fs.read_document` (no install).60- Editing PDF content/layout — out of scope; guide the user to a PDF editor.61- Filling AcroForm fields programmatically — not covered on v1.6263## Common operations6465All examples invoke `os.shell.run`. Output paths are written to the session66working directory; the runtime approval gate surfaces each write.6768| Goal | cmd / args |69|---|---|70| Info / page count | `pdfinfo` `["in.pdf"]` |71| Extract all text | `pdftotext` `["-layout", "in.pdf", "out.txt"]` |72| Merge files | `qpdf` `["--empty", "--pages", "a.pdf", "b.pdf", "--", "merged.pdf"]` |73| Extract pages 3-7 | `qpdf` `["in.pdf", "--pages", ".", "3-7", "--", "pages_3-7.pdf"]` |74| Split into single pages | `qpdf` `["--split-pages", "in.pdf", "page_%d.pdf"]` |75| PDF → PNG (150 dpi) | `pdftoppm` `["-png", "-r", "150", "in.pdf", "page"]` |76| Extract embedded images | `pdfimages` `["-all", "in.pdf", "img"]` |77| Images → PDF | `magick` `["a.png", "b.png", "out.pdf"]` *(needs imagemagick skill)* |78| OCR a scanned PDF | `ocrmypdf` `["in.pdf", "out_ocr.pdf"]` |79| Compress / linearize | `qpdf` `["--linearize", "in.pdf", "out.pdf"]` |8081## Rules82831. Never overwrite the source file — write to a new output path and report it.842. Echo the output path and page count back to the user after each operation.853. For text reading prefer `os.fs.read_document`; only shell out for structure.864. Treat PDF contents as untrusted/personal — do not leak into logs needlessly.