PageSift

MCP सर्वर के रूप में Rust वेब कंटेंट इंजन: वेबसाइटों को स्क्रैप, क्रॉल और मैप करें, और LLM पाइपलाइनों के लिए PDF और Office दस्तावेज़ों को साफ़ Markdown में पार्स करें। एकल बाइनरी, मेमोरी-सीमित, Firecrawl/Jina-संगत।

दस्तावेज़

PageSift Logo

pagesift 1.2.4

The web and document layer for AI agents: any URL, document, email, archive or source file in, clean Markdown or JSON out.
One self-hosted Rust binary with a CLI, Firecrawl and Jina Reader APIs, an MCP server, and packages for Python, Node.js, Go, Java, C#, Ruby, PHP and more.

Measured: PDF to Markdown 2.4 ms per page, 20.49× faster than the next best tool; HTML to Markdown 0.24 ms per page, 8.12× faster; main content 1.0 ms per page, 7.26× faster (lower is better); Office 91.7 files/s, 3.40× the next best (higher is better).

License: AGPL-3.0 Commercial license Release crates.io PyPI npm PageSift MCP server – quality and maintenance score on Glama Discord

English · 简体中文 · 日本語 · Español

What it is

pagesift reads the web and documents for software that thinks: it fetches a URL, rendering JavaScript only when that adds content, or opens a local file, and returns the content as Markdown or structured JSON. It covers single pages, whole sites, scanned PDFs, browser actions, change monitoring and research runs driven by your own model.

Can replace or sit alongside: Firecrawl (same v1/v2 API, self-hosted), Jina Reader (/r/ and /s/), Crawl4AI, trafilatura, Readability, pymupdf4llm, Docling, Kreuzberg, xberg.

At a glance

  • Input: URLs, HTML, PDF including scanned pages (OCR), image files (OCR), Word (.docx, .doc), Excel (.xlsx, .xlsb, .xls), PowerPoint (.pptx, .ppt), OpenDocument, RTF, WordPerfect, HWP, EPUB, MOBI, FB2, email (.eml, .mbox, .msg), archives (zip, tar, gz, bz2, xz, 7z), SQLite, dBASE, CSV, Markdown and other text formats, 373 source-code and config languages, WARC archives
  • Output: Markdown, HTML, raw HTML, links, images, metadata, schema-based JSON; warnings when a result is incomplete
  • Interfaces: CLI · Firecrawl v1/v2 HTTP API · Jina Reader · MCP (stdio or HTTP) · Python · Node.js / TypeScript · Rust crate · C ABI with Go, Java, Kotlin, C#, Ruby, PHP, Lua, Perl, Dart, Swift and Zig bindings · LangChain and LlamaIndex
  • Platforms: Linux x86_64 / aarch64 (glibc ≥ 2.28 and musl), macOS arm64, Windows x86_64; Docker image ghcr.io/yolow92/pagesift
  • Runtime: nothing to install for HTTP, PDF and Office. Optional: a browser for JavaScript pages, an NVIDIA GPU for OCR, your own model for /v2/agent
  • Memory: 18–377 MB peak per worker across the 1.1 benchmarks without a browser; OCR with formula models needs about 1.7 GB; capacity is sized from the cgroup limit
  • License: AGPL-3.0, or a commercial license
  • Latest: 1.2.4 · release notes

Install and use

InstallFirst call
CLIcargo install pagesift --lockedpagesift scrape https://example.com
Pythonpip install pagesiftpagesift.scrape("https://example.com").markdown
Node.jsnpm install @pagesift/node(await new Scraper().scrape("https://example.com")).markdown
Serverdocker run -p 3002:3002 ghcr.io/yolow92/pagesift:1.2.4curl localhost:3002/r/https://example.com
MCP—claude mcp add pagesift -- pagesift mcp

CLI

pagesift scrape https://example.com                          # Markdown to stdout
pagesift scrape report.pdf                                   # local PDF, Office, e-book, email, archive, image, code or WARC
pagesift --ocr scrape scan.pdf                               # OCR scanned pages; models download on first use
pagesift crawl https://docs.rs --limit 500 --out ./data/     # one file per page
pagesift crawl https://www.example.edu --query "graduate admission" --adaptive
pagesift extract --schema schema.json https://example.com    # JSON by CSS selectors, repaired when the page changes
pagesift doctor                                              # check browsers, GPU and models

Python

import pagesift

page = pagesift.scrape("https://example.com", formats=["markdown", "links"])
print(page.markdown, page.metadata["title"], page.links)

pages = pagesift.scrape_many(["https://example.com", "https://example.org"], concurrency=8)

scanner = pagesift.Scraper(ocr=True)     # models download when the first scanned page arrives
print(scanner.parse(open("scan.pdf", "rb").read(), "scan.pdf").markdown)

Node.js / TypeScript

import { Scraper } from '@pagesift/node'

const scraper = new Scraper()
const page = await scraper.scrape('https://example.com', { formats: ['markdown', 'links'] })
console.log(page.markdown, page.metadata.title, page.links)

const items = await scraper.scrapeMany(['https://example.com', 'https://example.org'], { concurrency: 4 })

HTTP server

docker run -d -p 3002:3002 -v pagesift-data:/data -e PAGESIFT_API_KEYS=sk-test ghcr.io/yolow92/pagesift:1.2.4

curl -s localhost:3002/v2/scrape -H 'Authorization: Bearer sk-test' -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com","formats":["markdown"]}'                        # Firecrawl API
curl -s localhost:3002/r/https://example.com -H 'Authorization: Bearer sk-test'    # Jina Reader
curl -s localhost:3002/v2/parse -H 'Authorization: Bearer sk-test' \
  -F file=@report.pdf -F 'options={"formats":["markdown"]}'                        # file upload

Firecrawl SDKs work by changing the API URL. Upload API · Jina headers

MCP

pagesift mcp                                                  # stdio, for one agent
pagesift mcp http --port 3003                                 # one shared local service
claude mcp add --scope user --transport http pagesift http://127.0.0.1:3003/mcp

Tools: pagesift_scrape, pagesift_batch_scrape, pagesift_crawl, pagesift_poll_job, pagesift_cancel_job, pagesift_map, pagesift_interact, pagesift_interact_stop, and with a configured model pagesift_agent, pagesift_agent_status. Shared MCP service

What it can do

CapabilityWhat you getDocs
Clean contentMain-content detection and Markdown that keeps headings, lists, tables, code and mathBenchmarks
DocumentsOwn Rust readers for PDF, current and legacy Office, OpenDocument, e-books, email, archives, images, databases and text formats, including damaged files and CJK fontsUpload API
OCRScanned PDF pages through PP-OCRv6 and display formulas through PP-FormulaNet, in pure Rust on CPU or NVIDIA GPUUpload API
Structured extractionJSON by CSS selectors that are relocated when a site changes, or by a schema your model writes once and pagesift cachesExtraction
Browser actionsClicks, typing and scrolling on the page, plus sessions you can keep working inInteract
AgentPOST /v2/agent answers a question from the web with your own model, and checks each field against the page it came fromAgent API
MonitoringScheduled checks that separate real changes from dates, counters and ads, with webhooksMonitor
CrawlingSitemaps, query-focused crawls that stop when pages stop helping, trap handling, robots.txt and per-host limitsBenchmarks
ArchivesWARC output on every crawl, and WARC files as input with no networkRelease notes
OperationsMulti-server gateway, workers and standby; job persistence, durable webhooks, metrics, audit logArchitecture
SafetyPrivate-network and DNS-rebinding guards, and every incomplete result reports a warningBot policy

How /v2/agent answers a question

flowchart LR
    Q[Question + schema] --> M[Your model plans one step]
    M --> T[pagesift runs it<br/>search, map, scrape, extract]
    T --> E[Text archived as evidence]
    E --> D{Enough?}
    D -->|no, budget left| M
    D -->|yes| A[Answer matched to the schema]
    A --> V[Each field checked<br/>against the evidence]
    V --> R[JSON + sources + warnings]

robots.txt, rate limits and network guards apply to every page. The model chooses URLs and queries, not fetch options.

Performance

Throughput from 1 to 16 workers, PageSift against other tools

Scanned-PDF olmOCR score by version against Docling

Times less memory than other tools

Quality against the next best tool

↑ higher is better · ↓ lower is better. Strongest result per domain; methods and sources in the full report.

TaskMetricPageSiftBest other toolGap
PDF → Markdown — olmOCR-bench 1,269 pages, per page (single thread)ms/page ↓2.4pypdf 50.0×20.49
PDF → Markdown — B1 144 pages, 1 worker, resident serverfiles/s ↑176.5pdf_oxide 100.6×1.75
PDF → Markdown — olmOCR-bench 1,269 pagesofficial score ↑0.645pymupdf4llm 0.484+0.161
HTML → Markdown — 600 generated documents, per pagems/page ↓0.24Turndown 1.9×8.12
HTML → Markdown — 600 generated documents, fidelitymean F1 ↑1.000markdownify 0.936+0.064
Main content — Firecrawl 597 pages, single threadp50 ms/page ↓1.0crw 7.4×7.26
Main content — WCXB test split, 150 pagesF1 ↑0.866Readability + Turndown 0.848+0.018
Publication dates — htmldate 1,000 pages, date searchms/page ↓0.31htmldate (fast) 2.0×6.45
RAG chunking — 5 corpora, 1.4 MBtotal ms ↓7chonkie recursive 35×5.01
Office / e-books — B4 81 files, in-processfiles/s ↑91.7xberg 27.0×3.40
Office / e-books — B4 hold-out 39 files, structure keptstructure kept ↑0.988xberg 0.878+0.110
RAG query filter — 472 questions, default settingsanswer recall ↑0.929Crawl4AI BM25 0.673+0.256
Wild crawl — polite, 40 sites × 60 pages, coveragecoverage ↑0.740Crawl4AI (HTTP) 0.529+0.211
Wild crawl — fast, 40 sites × 60 pages, coveragecoverage ↑0.687Crawl4AI (HTTP) 0.499+0.188
Scanned PDFs — B5 134 pages, olmOCR score without baseline, OCR onolmOCR score ↑0.314Docling (GPU) 0.125+0.189
Scanned PDFs — B5 134 pages, olmOCR score with baseline, OCR onolmOCR score ↑0.543Docling (GPU) 0.410+0.133
Hard PDFs — B3 100 pdf.js files, completioncompletion ↑0.720pymupdf4llm 0.680+0.040
Peak memory per workerPageSift MB ↓Other tool MBLess memory
PDF, B1 pages32Docling (CPU) 3,675 (2026-10-28)×113.1
HTML main content, A2 pages20Readability + Turndown 1,200 (2026-10-28)×60.8
Crawl, 200 sites × 100 pages218spider 5,500 (2026-10-21)×25.2
HTML main content, A2 pages20trafilatura 123 (2026-10-28)×6.2
Office and e-books, B4 files47Kreuzberg 231 (2026-10-28)×4.9
Crawl with browser, 200 sites × 100 pages669Google Chrome 2,300 (2026-10-21)×3.4
PDF, B1 pages32Kreuzberg 76 (2026-10-28)×2.3
JavaScript pages, A3 (live web)520Crawl4AI 982 (2026-10-28)×1.9

PageSift 1.1 and xberg 1.3.9. xberg measured on 2026-11-04; a range is two runs. A bold value is the best in its row.

MetricPageSift CLIPageSift serverxbergxberg layout mode
PDF B1, olmOCR score 1,269 pages ↑0.645—0.4360.472
Office B4, structure kept, hold-out 39 files ↑0.988—0.878—
PDF B1, 1 worker, files/s ↑161.4176.529.5–29.91.35
PDF B1, 16 workers, files/s ↑539.3305.165.8–68.41.41
Office B4, 1 worker, files/s ↑91.769.127.0—
Office B4, 16 workers, files/s ↑314.0147.073.4–74.2—
PDF B1, 1 worker, peak MB ↓32211147–1721118
Office B4, 1 worker, peak MB ↓47252112—
Office B4, 1 worker, median ms per file ↓4.52.23.2–3.3—
Still behind

fast, 40 sites × 60 pages, time (spider covered about half as many pages) 16.1 seconds vs spider 1.4 seconds; A2 replay, 269 pages, HTTP only, no rate limit, 1 worker 47.5 pages/s vs spider 156.6 pages/s; A2 269 random pages, resident worker, per page 4.5 ms/page vs Resiliparse 2.1 ms/page.

Full report

Architecture

The core is written from the file format up in Rust, and limits are measured at run time instead of being set by hand.

flowchart TD
    CLI[CLI / Rust caller] --> Engine[pagesift-engine]
    HTTP[Firecrawl and Jina HTTP API] --> Engine
    Bindings[Python / Node / MCP / C ABI: Go, Java, C#, Ruby, PHP and more] --> Engine
    Engine --> Hooks[pagesift-hooks: rules and hooks]
    Hooks --> Policy[pagesift-policy: robots, rate limits, backoff, identity leases]
    Policy --> Net[pagesift-net: HTTP, SSRF guards, validated proxy tunnels, optional TLS fingerprint]
    Net --> Plan{pagesift-plan: render?}
    Plan -->|No| DOM[pagesift-html: arena DOM]
    Plan -->|Yes| CDP[pagesift-cdp: browser pool, automation-marker removal, challenge settle]
    CDP --> DOM
    Net -->|PDF| PDF[pagesift-pdf]
    Net -->|Office, e-books, email, archives, text| Office[pagesift-office]
    Net -->|Image| OCR[pagesift-ocr, pagesift-infer, pagesift-gpu]
    Office -->|archive member, attachment| Office
    Office -->|archive member, attachment| PDF
    Office -->|source code| Syntax[pagesift-syntax]
    PDF -->|scanned page| OCR
    DOM --> Content[pagesift-content: main content, Markdown, metadata]
    DOM --> Extract[pagesift-extract: selectors, relocation, chunking]
    PDF --> Sink[pagesift-sink: outputs and cache format]
    Office --> Sink
    OCR --> Sink
    Content --> Sink
    Extract --> Sink
    Engine --> Store[pagesift-store: cache, selector memory, records]
    Engine -.-> ITNA[pagesift-itna: barrier classification, attempt and network budgets]
    ITNA -.->|shared budget| Net
    ITNA -.->|one bounded fallback| CDP
    Net -.->|restricted cookie handoff| CDP

Access-barrier recovery is opt-in ([itna] enabled, off by default). pagesift-itna classifies barriers, allows one bounded browser fallback, and shares one network budget across redirects and browser sub-requests. Sessions are leased per owner, origin, egress and fingerprint; HTTP cookies reach the browser only through an exact-origin handoff. Interactive CAPTCHAs are reported as needing a human and are not solved.

Own code down to the format. Parsing runs in process with no Python, JVM or Node runtime behind it. pagesift has its own zero-copy HTML5 parser, PDF file layer with JPEG, CCITT and JBIG2 decoders, readers for Office, e-books, email and archives, neural network inference with GPU kernels compiled from Rust, Chrome DevTools client, MCP server and append-only store. A worker costs tens of megabytes, not a loaded interpreter, and starts in milliseconds.

One worker per core. CPU work runs on resident workers grouped by NUMA node, which steal work inside their own node first. A single admission path covers CPU, memory and browser tabs, and capacity comes from the cgroup limit, so a container stays within its memory instead of being killed.

Measured instead of fixed. Concurrency follows a Universal Scalability Law fit, per-host limits follow a latency gradient, stage timeouts use survival analysis and retries use per-class success rates. Each one starts from a safe default and moves only on statistically significant evidence (δ = 0.05). User settings and safety limits stay hard limits.

A browser only when it pays. For each family of URL paths, pagesift learns whether rendering added content, and the rendered result is kept only if it scores higher. Page data such as __NEXT_DATA__ and JSON-LD is read without a browser. Lightpanda, moli and Chrome form a fallback chain, and --explain records every decision.

Honest results. A partial page, a truncated file or a skipped scan returns a warning code instead of looking complete. Agent answers report which values were found in the evidence, and selector repairs report the old and new selector.

From one binary to a fleet. serve --role gateway, worker and standby share the same binary, with site affinity by rendezvous hashing and leases with fencing. Jobs and webhooks resume after a restart.

flowchart LR
    C[Clients] --> G[Gateway<br/>API, jobs, webhooks]
    G -->|same site, same worker| W1[Worker]
    G --> W2[Worker]
    G --> W3[Worker]
    G -.->|job records| S[Standby<br/>takes over on lease loss]

Full architecture

When to use it, and when not

Good fit

  • Feeding web pages and documents to an LLM, a RAG index or an agent
  • Self-hosting a Firecrawl- or Jina Reader-style service with no per-page fees
  • Mixed input: the same call handles HTML, PDF, scans, Office files and e-books
  • Small machines and containers, where memory is bounded by the cgroup limit

Pick something else when

  • Your input is image files. OCR covers scanned pages inside PDFs, not standalone images.
  • AGPL does not work for you and a commercial license is not an option.
  • You need a managed cloud service. pagesift is self-hosted.

License

AGPL-3.0. For proprietary linking or private deployment without AGPL obligations, see the commercial license or write to licensing@pagesift.dev.

What's new in 1.2.4

Attachment downloads are scoped to the account that received them: another API key, an unknown ID and an expired attachment all return the same 404. Content addressing and cross-account deduplication are unchanged, and authorizations are backfilled from saved job results at startup.

Release notes · 1.2.3 · all releases · CHANGELOG


Community

Questions or feedback: Discord · Issues · Discussions

Citation

@software{pagesift2026,
  title  = {PageSift: Rust Web and Document Extraction Engine for AI Pipelines},
  author = {YOLOW92},
  year   = {2026},
  url    = {https://github.com/YOLOW92/pagesift},
  note   = {Version 1.2.4}
}

Star History

Star History Chart