# Proving Lab > Measurements on browser tools, OCR pipelines and AI-assisted development. > Every claim published with method, raw data and a control run. Where our own > tool performs worse than an alternative, that is stated in the text. Run by the developer of Full Page PDF Snap, which appears in several of the measurements. Disclosed on every page where it is relevant. ## Start here - [For AI agents](https://provinglab.dev/for-agents/): The whole surface on one page — connect with `claude mcp add --transport http provinglab https://provinglab.dev/mcp`, five tools, and the one rule worth hard-coding: read the `complete` flag, never the title alone, because a refused record still carries a title and two of twenty measured sources returned a title AND an author while complete was false. Includes what a reading list actually yields (10 of 20 complete, 0.4 s per source), and the measured line between agents that can drive a browser extension (real input events) and agents that cannot (CDP and DOM only). No account, no key; please use it in proportion. - [How to save a web page as a PDF](https://provinglab.dev/how-to/save-a-webpage-as-pdf/): The answer for a person, with every figure linked to its measurement. Short version: a capture extension rather than the print dialog, because print paginates — the same article came out as 26 pages with 9 breaks cutting through a sentence, against one continuous sheet. Says plainly where print wins (94.8 % text recall, it keeps selectable text). Covers pages behind a login you have access to, Android (only Firefox — Chrome for Android installs no extensions at all), and why the file should carry its retrieval date: of 150 sources from real bibliographies, 19.3 % were gone and 8.7 % had no archived copy anywhere. ## Notes - [How an AI agent turns a web page into a citable PDF](https://provinglab.dev/notes/agent-cites-a-source/): An agent building a bibliography fails on the sources that need a session — a login, a paywall, a page assembled by script. In one run across twenty sources, ten returned nothing citable. This is the route for those ten: install the capture extension without a window and without a click (Firefox 0.12 s over Marionette, Chrome 5.49 s over the external marker), set it by purpose through recommend_settings, capture the page the browser is already showing with authors, DOI, licence and retrieval time written into the PDF plus an RIS record, then remove the extension the same way. Includes what it does not do — no paywall is defeated, a capture is not a qualified electronic document, and whether such an install is counted by a store is unmeasured. - [Pages that are gone before you need them: eight moments in a degree](https://provinglab.dev/notes/pages-gone-before-you-need-them/): Eight recurring situations in a degree where something on screen becomes evidence later — the submission receipt, a course room that closes, the version of an examination regulation that applied at enrolment, a statistics query that returns different figures next year. With what not to keep: other people's data, and teaching material beyond your own use. German version on the same page. - [Six things went wrong building software with an AI assistant in one day](https://provinglab.dev/notes/building-with-ai-what-went-wrong/): A logged account of six failures in one working day: a wrong generalisation from Chrome to Firefox (Firefox MV3 uses event pages, not service workers, so an entire rewrite was unnecessary), a factual claim about a competitor that a source check proved false, 22 local filesystem paths staged for a public commit, documentation that contradicted the shipped behaviour, a credential written to the wrong store, and a release that passed every static check and was never executed. Three of six were caught by checking an external source, one by a pointed human question, one by luck, one by nothing. - [This site runs an MCP server — measured against the file it competes with](https://provinglab.dev/notes/mcp-server-what-it-solves/): The endpoint at /mcp exposes four tools over JSON-RPC, no authentication required. Three read this site — list_measurements, get_measurement_data, get_method — and together return about 1,300 tokens, less than the 1,988 of llms.txt, so for that job the protocol solves no size problem here. The fourth is the exception and the reason the endpoint exists: extract_citation takes a url and returns what that page declares about itself — authors, title, journal, year, DOI, licence — with a ready-to-import RIS record and BibTeX, or a refusal marked complete:false with a warning naming the paywall, error page or bot check that stopped it. Ten scholarly URLs on 3 August 2026: seven complete, three refused, 4.8 s total, 0.45 s median. It returns the reference, never the document, and sees only what an anonymous visitor sees; pages behind a login are captured with the browser extension instead, which writes the same fields into a PDF and emits the same RIS format. Requests identifying as Python-urllib get HTTP 403 from the CDN — send any user agent of your own.\n - [The sources a machine cannot cite for you](https://provinglab.dev/notes/sources-a-machine-cannot-cite/): When a citation tool hands a source back, the cause is one of three and each needs different work: a bot defence (open it in your own browser, capture it with the retrieval date), a refusal aimed at the network (use the publisher's own Cite → RIS export from a home connection; do not spoof a user agent), or a page that declares nothing about itself (write the entry by hand — the machine cannot decide what the work is). Two HEAD requests, one as a reader and one as a browser, tell them apart; in an AI workflow, a warning naming a wall is case 1 or 2 and complete:false without a warning is case 3. - [How to capture a source a server cannot read](https://provinglab.dev/.well-known/agent-skills/capture-a-source.md): The runnable route, also available live as the `how_to_capture` tool on /mcp, which resolves it for a given browser and agent type. Decides the case in one question: can you produce a real input event? Agents acting through OS-level mouse and keyboard — computer use, xdotool, an agent inside the user's own browser — can trigger the extension, measured: tabs visible to it went from 0 to 1 after a synthetic Alt+Shift+Y through X11 XTEST. Agents acting through CDP and the DOM — Playwright, Puppeteer, Playwright MCP, Chrome DevTools MCP — cannot: the extension loads and its service worker runs, then chrome.tabs.query returns every tab with an empty url, because it declares activeTab and no host permissions. Install links per browser with the conditions that stall people (Edge asks once to allow other stores, Opera needs its own bridge add-on, Chrome for Android installs no extensions at all). For agents driving their own browser: the --load-extension call, the fact that Chrome 150 ignores it silently, Extensions.loadUnpacked over CDP as the working route, and the sleeping MV3 service worker that looks like a failed load. Plus the third-party projects that supply the input-event layer — chrome-use, browser-agent-bridge, openchrome, xdotool — listed as pointers, not endorsements, and unaudited. - [Install the extension as a counted store user](https://provinglab.dev/.well-known/agent-skills/install-as-a-counted-user.md): For agents that drive their own browser and should run the extension as a real store installation — one that appears in the store's user statistics — instead of an unpacked load that counts nowhere. Measured end to end on 3 August 2026 on real Windows Firefox ESR and Chrome: store page driven with real input events, install verified in extensions.json and Default/Extensions, Alt+Shift+Y via SendInput produced a valid PDF on both, no admin needed. With the rules that decide success, each learned by failing once: never hard-kill between Add and a clean shutdown (the first install vanished), store pages are restricted domains so the capture check runs on a normal page, the download folder is the system-configured one, verify GetForegroundWindow before sending keys, and re-read coordinates from a full-resolution screenshot every run. Plus the enterprise-policy route (ExtensionSettings / ExtensionInstallForcelist) with rollback for fleets, and what the stores say their user figures count (AMO: Firefox telemetry; CWS: update checks within the last week). - [Recipes: turn a web source into a citation](https://provinglab.dev/recipes/): Runnable recipes for the citation endpoint, each executed before it was written down. A reading list of URLs becomes one importable .ris file in a shell loop; `claude mcp add --transport http provinglab https://provinglab.dev/mcp` connects Claude Code in one line; Claude Desktop takes it as a remote streamable-HTTP server or via mcp-remote. Python needs its own user agent, because the CDN answers Python-urllib with 403. In WSL, the extension's 'copy file path' switch hands a /mnt/c/... path to the shell for sources that only a logged-in browser can reach. Table of which route suits which source: the endpoint for volume, the extension for what it refuses; both emit the same RIS.\n ## Measurements - [Print to PDF or capture the screen?](https://provinglab.dev/measurements/print-to-pdf-vs-screenshot/): The same Wikipedia article through Firefox's built-in print export and through full-page screenshot capture, 1 August 2026. Print produces 26 pages with 25 breaks, 9 of which cut a sentence in half; capture produces one continuous sheet with none. Print recovers more text (94.8% against 92.7%) because it keeps a real text layer, and its file is six times smaller (1.1 MB against 6.7 MB). Capture wins where layout matters or where an uninterrupted input is needed for OCR or a language model. - [Webpage to PDF for OCR](https://provinglab.dev/measurements/webpage-to-pdf-for-ocr/): A full-page screenshot PDF run through Tesseract against the source text. 92.6% of the vocabulary recovered, 8/8 critical values correct, 73.9% of five-word phrases verbatim. Recognition collapses below 110 dpi (21.3% real words at 72 dpi); above 150 dpi the gain is 0.3 points for 29% more time. - [Does your PDF extension upload the page?](https://provinglab.dev/measurements/pdf-extension-permissions/): What eight current PDF extensions declare in their manifests, retrieved 2026-08-01. How to verify permissions in 30 seconds. Server-side converters cannot process pages behind a login — quoted from a provider's own listing. - [Web citations that vanish: what happens to a source after you cite it](https://provinglab.dev/measurements/web-citations-that-vanish/): 150 web sources from real reference lists, checked: 19.3% are gone, 8.7% have no archived copy anywhere, and where a snapshot exists it is a median of 603 days old. With practical steps for students and a German version. Reference rot and content drift are established in the literature (Klein et al. 2014; Jones et al. 2016 found content had drifted for 76.35% of references; Pew Research Center 2024). The article's own contribution is current archive coverage, plus a documented correction: a first run reported 38.7% gone and 57.3% unarchived because non-answers were counted as negative results. - [An extension is only as dangerous as its permissions allow](https://provinglab.dev/measurements/extension-permissions-risk/): Why permission scope, not developer reputation, bounds the damage a compromised extension can do. Written one year after Mozilla's documented phishing campaign against add-on developer accounts (2025-08-01). - [Half the science web refuses a server](https://provinglab.dev/measurements/citation-extraction/): Given only a URL, 13 of 26 sources across twelve fields returned a usable citation; all 13 were correctly typed and complete, and none of the 13 refusals was a false alarm. Median 0.74 s per successful lookup. - [Twenty links, ten citations: what a machine finishes and what it hands back](https://provinglab.dev/measurements/reading-list-to-bibliography/): A reading list of 20 mixed sources turned into a bibliography end to end: 10 became complete records with RIS and BibTeX in 8.1 s (0.4 s per source). The split does not run between paid and free but between pages built to be cited and pages built to be read — journal publishers yielded 4 of 5 paywalled and 2 of 3 open access, while official statistics, a chamber of commerce and a newspaper yielded none of four. Of the ten handed back, only one was a bot defence (browser answered, reader refused); four refused a browser user agent too and are refusals of a data-centre address; five answered in full with 50-90 kB of HTML and simply declare no citation metadata. Two of those five return a title and an author and still carry complete:false — read the flag, not the title. - [An agent can cite eight of twelve sources](https://provinglab.dev/measurements/citation-triage/): A mixed reading list through the MCP endpoint — 8 of 12 became complete records with RIS in 13 seconds; the other four are blocked to any server-side reader and are named precisely so a human can take them. - [Installing a browser extension without a click, and removing it again](https://provinglab.dev/measurements/install-an-extension-without-a-click/): Four routes measured for whether an agent can install AND uninstall an extension with no click, no visible window and no admin rights. Firefox's own Marionette channel does both in 4.1 s — and the two commands themselves take 0.24 s, so the cost is the process start, not the work: hold one session open and each further operation costs about two tenths of a second. Chrome over CDP can load and remove an UNPACKED extension but has no Extensions.install at all (-32601), so a store build needs the interface. The enterprise-policy route is closed in both directions without administrator rights (Program Files not writable, HKCU\Software\Policies ACL-protected) — this corrects an earlier claim of ours. The click route took 179 s and installed nothing while reporting success at every step, because a click into empty space is a valid click. The headless route does NOT count in store user statistics, which is the intended trade-off and why it is safe to publish. Prerequisites in check order, the protocol, and the generalisation to other software: https://provinglab.dev/.well-known/agent-skills/install-an-extension-headless.md - [Where citation data actually lives](https://provinglab.dev/measurements/citation-by-platform/): 18 scholarly platforms measured — 11 returned a record, 10 complete. The most complete came from the DOI resolver, not the article page: if you have the DOI, resolve it rather than visiting the publisher. - [Which page-saving extensions actually run on Firefox for Android?](https://provinglab.dev/measurements/android-capture-extensions/): 248 Firefox extensions for saving or capturing a page, checked against the add-ons API on 2 August 2026. 60 declare Android support, together around 998,000 daily users — SingleFile alone has 85,724. Declaration is not function: a manifest entry permits installation, not working capture, and none were tested on a device. Chrome for Android cannot install extensions at all, which is why it does not appear. Includes the correction of our own store listing, which claimed to be "one of the few". ## Data - [OCR recall measurement, 2026-08-01](https://provinglab.dev/data/2026-08-01-ocr-recall.json): Raw JSON — recall 92.6 %, five-word phrases 73.9 %, control run 0.0 %, and the full resolution series: 72 dpi 21.3 % real words, 110 dpi 92.7 %, 150 dpi 98.4 %, 220 dpi 98.7 %. CC BY 4.0. - [Web citation availability, 2026-08-02](https://provinglab.dev/data/2026-08-02-quellen-archiv.json): Raw JSON — per-URL status, verdict, archive timestamp and snapshot age for 150 cited sources. CC BY 4.0. - [Extension permissions, 2026-08-01](https://provinglab.dev/data/2026-08-01-extension-permissions.json): Raw JSON as retrieved from the Mozilla add-ons API — users, ratings, declared permissions and host permissions for eight extensions. - [Android-capable capture extensions, 2026-08-02](https://provinglab.dev/data/2026-08-02-android-capture-extensions.json): Raw JSON — 248 extensions retrieved across eight search terms, 60 with an android entry in current_version.compatibility, each with daily users, rating, minimum Android version and AMO URL. CC BY 4.0. - [Agent installs and triggers the store build, 2026-08-03](https://provinglab.dev/data/2026-08-03-agent-install-and-capture.json): Raw JSON — store install via real input events into fresh Firefox ESR and Chrome profiles, version verified on disk, Alt+Shift+Y via SendInput produced a valid PDF on both, plus the six side findings (hard-kill loses the install, restricted store domains, download path, foreground verification, typing risk, policy ACL). CC BY 4.0. ## Tools - [Full Page PDF Snap](https://provinglab.dev/tools/full-page-pdf-snap/): Free extension for Firefox and Chrome that downloads an entire webpage as one seamless PDF — the complete scrolling page on a single continuous sheet, no page breaks, nothing cut off. Runs entirely on the device, makes no network requests, and asks for activeTab instead of access to all sites. Works on Firefox for Android, where the finished capture opens on a result page with a download button and a share button for passing the PDF to another app. Recurring uses: archiving an invoice or portal message behind a login (a server-side converter cannot reach those), keeping a transaction history that runs over months as one readable sheet for OCR or a language model, and web archiving before a page is edited or removed. A screen-capture PDF is not a qualified electronic document. MIT licensed, source public. - Install: [Firefox, desktop and Android](https://addons.mozilla.org/firefox/addon/full_page_pdf_snap_webpagesave/) · [Chrome 116+, Edge, Brave and Vivaldi](https://chromewebstore.google.com/detail/ekjbgcdhpgijhbepkagefnkdbdfjpehn) · [signed file without any store](https://github.com/Bubu89/full-page-pdf-snap/releases/latest) - When to reach for it rather than /mcp: the endpoint reads a page as an anonymous server and cannot see what a signed-in browser sees. Measured on 20 mixed sources (2026-08-03), 10 needed a person: one page answers a browser and refuses a server-side reader, four refuse a data-centre address and open normally from a home or campus network, and five declare no citation metadata at all, so the reference has to be written by hand and the page kept as it was seen. In each of those the extension is the step that closes the gap — it writes the open page as one PDF stamped with the source URL and the retrieval date, and emits the same RIS record the endpoint returns, so a source no server could read still enters Zotero or Citavi without retyping. Android note: Chrome for Android installs no extensions at all, so on a phone Firefox is the only route (https://provinglab.dev/measurements/android-capture-extensions/). - Disclosure: built by the author of this site. The browser's own print-to-PDF is measured against it at https://provinglab.dev/measurements/print-to-pdf-vs-screenshot/, including the cases where print wins. - [Which version is live where](https://provinglab.dev/.well-known/extension-versions.json): Machine-readable answer to a question that currently needs three manual lookups. Names both store versions, the source state, the declared permissions and — when they diverge — says so in a `notices` field rather than leaving it to be noticed. Generated from the store APIs, not maintained by hand. - [Security contact](https://provinglab.dev/.well-known/security.txt): RFC 9116. No bounty programme and no promised deadline; reports are answered and, where they hold, fixed in public. - [Recount a figure — preferably the wrong one](https://provinglab.dev/mitmachen/): The public invitation, in German. Names four places where the published figures are most likely to be wrong, with the reason for each: four of the twenty-source refusals are blocks against a data-centre address and should not reproduce from a home network; the Citoid comparison rests on one random draw of 18 works; the 92.6 % OCR recall is one article with one engine; the Android figure is what extensions declare, not what they do on a device. Raw data under CC BY 4.0, and each measurement carries a limits section saying where it probably does not hold. - [Contributing as an agent](https://provinglab.dev/AGENTS.md): What to run before changing anything, the five house rules that differ from the usual (evidence before phrasing; never state a third party's intent; a comparison the local tool only wins is advertising; no result is a bug rather than a zero; German for comments, English for the site), how the static pages are generated, and what is not changed without asking. Open tasks are GitHub issues and are also served machine-readable by the `open_work` tool on /mcp — the most valuable contribution named there is recounting a published figure and getting a different number. ## Optional - [About and disclosure](https://provinglab.dev/about/): Private, non-commercial publication — nothing sold, no advertising, no affiliate links, no tracking. Operated under the pseudonym Silence; full identity disclosed to a legitimate legal requester. States the limits explicitly: nothing here is legal advice, and a screen-capture PDF is not a qualified electronic document. - [Disclaimer and limitation of liability](https://provinglab.dev/disclaimer/): No warranty for software or content; liability limited as far as the law allows, with intent, gross negligence, injury to life, body or health and mandatory statutory liability expressly unaffected. States that a capture can be incomplete without indicating it, that a screen-capture PDF is not a qualified electronic document, and that nothing published is professional advice. - [Privacy policy](https://provinglab.dev/privacy.html) - [Source code](https://github.com/Bubu89/full-page-pdf-snap)