# extract_pdf: the text of a PDF, page by page

**Input:** one `.pdf`, not password-protected. Limits: 500 pages per job, 20 MB. The price is per page extracted (`mcpbytes.py tools`, `pricing`), so `max_pages` also limits the cost.
There is no OCR: scanned pages come back empty (the result says how many, and adds a note when all are).

**Options**

| Option | Values | Meaning |
|---|---|---|
| `start_page` | integer ≥ 1 (default 1) | First page to extract. |
| `max_pages` | integer ≥ 1 | Extract at most this many pages (capped by the plan). |

Over MCP there is also `max_length` (bytes, default 20000): how much of `text.txt` comes back inline with the result.

**Result summary:** `pages` (in the document), `first_page`, `last_page` (extracted range), `empty_pages`, `chars`,
`notes` (for example "pages 501-812 were not extracted: run again with start_page 501").

**Output files**

- `text.txt`: for every extracted page a line `--- Page N ---`, the page's text, a blank line. UTF-8.
- `pages.json`: `pages`, `metadata` (title, author, dates, when present), and `extracted`: for each page its
  `offset` and `bytes` in `text.txt` and its `chars`.

**How to read it well**

- Read `text.txt` in chunks (`read_job_file`, or `mcpbytes.py read`): pass `next_offset` as the next `offset` until
  `eof`. Stop when you have what the task needs.
- To go straight to page N, read `pages.json` first and use that page's `offset` and `bytes` as `offset` and `limit`.
- A long document: extract it in ranges (`start_page`, `max_pages`) rather than all at once if only a part matters.
- Text order follows the page layout; tables and multi-column pages may need care when quoting.

**Errors:** `invalid_pdf` (not a PDF, or too damaged to open), `encrypted_pdf` (needs a password: ask the user for an
unprotected copy), `invalid_options` (`start_page` beyond the last page).
