web_read
Read a specified web page by URL and return its full text, including support for long documents with pagination.
Instructions
Read a web page by address and return its text.
HOW IT DIFFERS FROM web_search, WHICH ALSO READS. That one reads the top three links of its own results at 6000 characters each — enough for an answer. This one takes the addresses YOU name, up to five at a time, reads them in full with a cursor over a long document, can demand the browser and can check for a marker. If you need an answer, search is enough; if you need to work with a document, come here.
WHEN TO CALL. You need the text of a specific page whose address is already known — from web_search results or from the user. You need facts from an article rather than a snippet about it. Read a long page in parts: the same call with the offset named at the end of the truncated text.
WHEN NOT TO CALL. There is no address yet — use web_search first. You need an office document (DOCX, XLSX) — the tool does not parse those and will say so plainly; PDF, however, IS read. A search-engine result page must not be read: it merges neighbouring results into one text and hands you facts about a namesake.
WHAT IT RETURNS. results[] per address: content — the page text, status — what became of it, title, published, lang, final_url (where a redirect led), stub_check — whether this is a block; text_source — HOW the text was obtained.
HOW TO READ THE ANSWER — four things that are easy to get wrong.
EMPTY CONTENT IS A SUCCESS, not a failure: the page opened and has no text in it. Repeating is pointless, take another source. On a refusal or a failure to open, repeating does make sense.
okis about the TOOL, not about the pages: it stays true even if not one page was read. Look at count and failed, and at the status of each address:read,empty,stub,refused,unreachable,forbidden,not_reached. They mean different things and call for different next steps —emptyis not worth repeating,refusedandunreachableare;not_reachedis news about US (out of time, the per-domain rate limit, or beyond the batch ceiling) and says nothing about the page.text_source IS REQUIRED READING when it says the text was recognised. That is a scanned PDF with no text layer: the pages were rendered and read by a vision model, and such text MUST NOT be quoted as exact — a measurement recovered 94% of the reference numbers. The details are in the
recognitionfield, including the dpi and whether the model's answer was cut off. A text layer means "copied out of the file" and is quotable verbatim.A stub status means we met an anti-bot shield or a paywall: text arrived, but it is not from the page. Do not retell it as the content. A stub_check of "not checked" is NOT "clean".
PDF. It is read; pages and pages_read say how many pages the document has and how many were parsed. An empty result on a PDF means "there are pages and no text" — that is a scan, cured by recognition rather than by repeating. And remember: in a PDF the characters can be extracted correctly while the reading order falls apart, so labels come away from their values. Do not assemble "property: value" pairs out of adjacent PDF lines without checking that they really are adjacent.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | how to fetch. auto (default) and plain use an ordinary request. browser goes through a real browser, for pages with a script-based check; if that path is not wired up the call returns a did-not-get-through status — see paths_available in the answer | |
| urls | Yes | page addresses, from 1 to 5 per call. Take them verbatim from web_search results, do not guess at them. Addresses beyond the ceiling come back with a did-not-get-through status — they never vanish silently | |
| fresh | No | false by default. Do not take the result from the read cache (it lives 300 s). Use it when the page is known to be changing as you watch | |
| links | No | false by default. Return the page links as a list. links_total is ALWAYS returned: an empty list with links_total > 0 means "you did not ask", not "there are none" | |
| expect | No | markers that MUST occur in the text if this is the right page. Set them when the address was found by an organisation or person name: a status code and a title are forged by a stub, knowledge of the content is not. Not found gives expected_found=false | |
| format | No | markdown (default) — text with headings and links; text — text only, cheaper in characters; html — as it came, for parsing the markup | |
| offset | No | the character to continue reading from, counted from zero. The tool names the continuation number itself at the end of the truncated text — take it from there rather than computing it | |
| max_chars | No | how many characters of content to return per address, default 20000. The remainder is not lost — it is fetched by the next call with an offset |