Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Analyze PDF files by converting them into agent-readable text, OCR text, page render images, and extracted embedded images without polluting the working directory. Use when an agent needs to read, summarize, inspect, compare, quote, or reason about PDFs, especially when the foundation model cannot ingest PDFs directly or when tables, figures, scans, screenshots, or layout matter.
.claude/skills/hashgraph-online-pdf-monster/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 23% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 90% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -29% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 54% | 0% |
Treat PDF files as source artifacts that must be converted into model-readable evidence before analysis. Do not create output/, analysis/, pages/, or similar folders in the user's working directory unless the user explicitly asks to save extracted artifacts.
Use the bundled scripts/analyze_pdf.py first. Resolve this path from the skill root, not from the user's current working directory. It prints JSON to stdout, extracts text in-place, and writes only image artifacts to an OS temporary directory unless --save-to is provided.
Run from this skill directory or replace scripts/analyze_pdf.py with its absolute path:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --json
When the agent is running from another directory, use the absolute installed path. In Claude Code, ${CLAUDE_SKILL_DIR} points at this skill directory:
bashpython3 ${CLAUDE_SKILL_DIR}/scripts/analyze_pdf.py path/to/file.pdf --json
Python 3 is required. Before first use, check whether PyMuPDF is already available:
bashpython3 -c "import fitz"
If that fails and the agent is allowed to run pip/network installs, install the recommended dependency from this skill's requirements.txt. In Claude Code:
bashpython3 -m pip install -r "${CLAUDE_SKILL_DIR}/requirements.txt"
In other agents, use the absolute path to this skill's requirements.txt.
If dependency installation is not allowed, continue with the script anyway; it can use Poppler fallbacks when available. Optional system tools improve coverage when PyMuPDF is unavailable or OCR is needed, but do not install system packages automatically:
pdfinfo, pdftotext, pdftoppm, pdfimagestesseract plus any needed language data, such as eng or korFor visual-heavy or scanned documents:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --render-pages all --ocr auto --json
For Korean/English OCR, use Tesseract language data and pass:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --render-pages all --ocr auto --ocr-lang kor+eng --json
For text-only inspection with no temporary image artifacts:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --render-pages none --no-extract-images --ocr never --json
For slide decks or PDFs with repeated logos/icons, reduce embedded image noise while keeping page renders available:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --render-pages all --min-image-area 10000 --dedupe-images --json
For selected pages:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --pages 1,3-5 --render-pages all --json
Persist artifacts only when the user asks for reusable files:
bashpython3 scripts/analyze_pdf.py path/to/file.pdf --save-to ./pdf-monster-artifacts --json
analyze_pdf.py and capture stdout JSON.warnings, page_count, artifact_root, pages_needing_visual_review, and each page's text_chars, ocr_text_chars, render_path, embedded_images, needs_visual_review, and visual_review_reasons.text as the primary evidence when it is complete enough.ocr_text when a page has little extracted text or appears scanned.render_path for pages marked needs_visual_review, and for pages where layout, charts, handwriting, equations, tables, screenshots, or visual placement could change the answer.embedded_images[].path when the PDF contains standalone figures that may be clearer than the page render.artifact_policy is temporary.The JSON includes a cleanup_command such as:
bashrm -rf -- /tmp/pdf-monster-...
Run it only after the image paths are no longer needed. Never delete a --save-to directory unless the user asks.
Before answering, complete these checks:
pages_needing_visual_review is non-empty, inspect the relevant render_path or rerun selected pages with --render-pages all before making claims that depend on layout, diagrams, tables, or figures.artifact_policy: temporary, run cleanup_command after the visual evidence is no longer needed.analyze_pdf.py prefers PyMuPDF when available. It falls back to Poppler CLI tools where possible:
pdftotext for text extractionpdfinfo for page countpdftoppm for page renderspdfimages for embedded image extractiontesseract for OCR when installedOCR is optional. If tesseract is missing, report the missing OCR capability and continue with text extraction and rendered page images.
Install this folder where the agent discovers skills, or reference the absolute path in custom instructions:
~/.claude/skills/pdf-monster or .claude/skills/pdf-monster$CODEX_HOME/skills/pdf-monster or ~/.codex/skills/pdf-monster~/.pi/agent/skills/pdf-monster, ~/.agents/skills/pdf-monster, or a skills settings entry~/.openclaw/skills/pdf-monster, <workspace>/skills/pdf-monster, or skills.load.extraDirs~/.hermes/skills/pdf-monster or skills.external_dirsFor agents without a native skill loader, give them this folder and a short instruction:
textUse pdf-monster/SKILL.md. For PDF tasks, run: python3 /absolute/path/to/pdf-monster/scripts/analyze_pdf.py <pdf> --json Read the JSON from stdout. Use temporary image paths only while analyzing, then clean them up. Do not create output folders in the user's working directory unless explicitly asked.
For OpenCode or similar agents, keep the repository checked out somewhere stable and reference the absolute path to SKILL.md or scripts/analyze_pdf.py in the agent's custom instructions. The only hard requirement is Python 3. PyMuPDF is the recommended dependency; Poppler and Tesseract improve fallback and OCR coverage.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 30,474 | 10,722 | -65% | 1 | 1 | 0% | 933 | 2,054 | +120% | 0 | 0 | — |
case-02 | fail→fail | 16,716 | 18,892 | +13% | 1 | 1 | 0% | 461 | 2,149 | +366% | 0 | 0 | — |
case-03 | fail→fail | 15,605 | 11,459 | -27% | 1 | 1 | 0% | 273 | 1,973 | +623% | 0 | 0 | — |
case-04 | fail→pass | 10,835 | 4,053 | -63% | 1 | 1 | 0% | 1,840 | 2,268 | +23% | 0 | 0 | — |
case-05 | fail→pass | 13,639 | 4,525 | -67% | 1 | 1 | 0% | 2,809 | 2,553 | -9% | 0 | 0 | — |
case-06 | pass→pass | 8,980 | 7,429 | -17% | 1 | 1 | 0% | 566 | 1,990 | +252% | 0 | 0 | — |
case-07 | fail→pass | 11,630 | 2,723 | -77% | 1 | 1 | 0% | 1,090 | 2,073 | +90% | 0 | 0 | — |
case-08 | fail→pass | 16,115 | 2,827 | -82% | 1 | 1 | 0% | 3,085 | 2,195 | -29% | 0 | 0 | — |
case-09 | fail→fail | 9,641 | 8,093 | -16% | 1 | 1 | 0% | 725 | 2,210 | +205% | 0 | 0 | — |
case-10 | fail→fail | 23,138 | 15,581 | -33% | 1 | 1 | 0% | 964 | 2,029 | +110% | 0 | 0 | — |
case-11 | pass→fail | 14,817 | 10,911 | -26% | 1 | 1 | 0% | 1,432 | 2,066 | +44% | 0 | 0 | — |
case-12 | fail→pass | 15,374 | 4,736 | -69% | 1 | 1 | 0% | 1,671 | 2,573 | +54% | 0 | 0 | — |
case-13 | fail→pass | 14,168 | 10,924 | -23% | 1 | 1 | 0% | 2,007 | 2,674 | +33% | 0 | 0 | — |
case-14 | pass→pass | 12,247 | 3,569 | -71% | 1 | 1 | 0% | 956 | 2,164 | +126% | 0 | 0 | — |
case-15 | fail→pass | 9,678 | 16,856 | +74% | 1 | 1 | 0% | 1,581 | 2,947 | +86% | 0 | 0 | — |
case-16 | fail→fail | 8,931 | 7,365 | -18% | 1 | 1 | 0% | 1,156 | 1,976 | +71% | 0 | 0 | — |
case-17 | pass→pass | 14,809 | 12,859 | -13% | 1 | 1 | 0% | 1,539 | 2,706 | +76% | 0 | 0 | — |
case-18 | fail→pass | 17,974 | 8,342 | -54% | 1 | 1 | 0% | 2,445 | 2,111 | -14% | 0 | 0 | — |
case-19 | pass→pass | 17,897 | 4,100 | -77% | 1 | 1 | 0% | 1,998 | 2,469 | +24% | 0 | 0 | — |
case-20 | pass→fail | 12,544 | 10,437 | -17% | 1 | 1 | 0% | 2,529 | 1,979 | -22% | 0 | 0 | — |
case-21 | pass→pass | 14,476 | 10,912 | -25% | 1 | 1 | 0% | 1,739 | 2,766 | +59% | 0 | 0 | — |
case-22 | pass→pass | 7,983 | 12,935 | +62% | 1 | 1 | 0% | 1,650 | 3,285 | +99% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +27 percentage points is the difference between those two pass rates over the 16 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.