svipall
Svipall is a local-first Rust MCP/REST/CLI server that gives AI agents web reading, crawling, searching, browser automation, and local challenge handling without API keys or telemetry.
Read pages: fetch one or many URLs as clean Markdown (or text/HTML), with relevance filtering, token caps, cursors, cache, and PDF/Office extraction.
Extract structured data: use
schema(auto or custom) ortablesto get typed rows from listings and tables, optionally written to CSV/JSON/JSONL on disk.Crawl sites: same-domain crawling with robots.txt, dedup, depth/page/token limits, resumable
crawl_id,llms.txtoutput, and optional saturation stopping.Discover URLs:
web_maplists a site's URLs from robots.txt, sitemaps, feeds, and homepage links without crawling.Search: keyless web search (DuckDuckGo/Bing/Brave, merged) and per-site search-form discovery.
Drive a real browser:
web_snapshotreads interactive structure with refs;web_actand persistentbrowser_open/browser_doclick, type, scroll, wait, eval, and screenshot.Capture APIs:
web_capturerecords the JSON/XHR calls a page makes, exposing the site's own data endpoints.Read video:
web_videoreturns captions and chapters as a timeline, with optional keyframes and local transcription.Track changes:
web_diffcompares against the cached copy;web_watchpersists scheduled checks of a page or CSS region.Handle challenges: automatic tier escalation (http → browser → stealth → real → warm), local captcha solving (Turnstile, reCAPTCHA v2, hCaptcha, image),
solve_and_continue, and a human dashboard fallback.Manage identity:
web_loginsaves cookies to profiles,web_profileexports/imports them encrypted, andweb_routeassigns proxies with country-aware exits.Remember state:
web_noteskey-value storage, plusweb_logandweb_statusfor tier history, cooldowns, budgets, and resets.Integrate anywhere: 29 MCP tools, a CLI, and a bearer-key-protected local REST API with async job streaming and resume.
Detects and attempts to bypass Cloudflare's anti-bot challenges (such as 'checking your browser' walls) to retrieve content from Cloudflare-protected websites, with explicit verdicts when a block is detected.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@svipall Fetch the article at https://example.com/blog/rust and summarize the key points."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Everything runs locally. There are no third-party API keys, no paid captcha services and no telemetry. Web requests reach the sites you visit, and results reach the agent or client you connect.
Svipall fetches and renders pages locally, extracts their content, and reports detected challenges and extraction-quality labels. Some sites still block it, and an apparently successful response can contain incomplete records or a page shell. The published comparisons therefore audit useful content separately from HTTP status and the tool's own verdict.
Why Svipall
What goes wrong | Svipall |
Your agent reads a "checking your browser" screen and summarises it as the article. It was a | Twelve wall kinds, each naming the move it implies. Detected blocks carry an explicit verdict; classification is heuristic details |
You crawl 5,000 pages and can't tell which are worth keeping | Assessed pages carry quality and duplicate observations, and quality labels never discard a page details |
One page = 300,000 tokens of raw HTML. The fixes are four manual jobs you now own | Clean Markdown by default; opt into tables as rows, |
You want to attempt a supported captcha without a paid solver | Fifteen widget families and eleven answer modalities, all local, optional vision models depending on the build, and a human dashboard for unresolved challenges details |
It records successful visits, failures, incomplete extraction and rejected changes. Historical benchmark logs and the current comparison use different scoring rules and configurations; the results section distinguishes them.
Rust · MCP + CLI + REST · no Node, no Python, no API key · local storage and processing
The comparison table describes other projects' documented scope.
Related MCP server: Crawl4AI MCP Server
Install
Every channel below installs the latest release,
built from the tree this README describes. svipall doctor reports what an installed build can do
on the machine it is on.
The README factual audit records the source checks, documentation corrections and limits of this review.
Choose agent-assisted setup, the Claude Code plugin, or a manual installation.
Ask the agent you already have
Paste this into Claude Code, Cursor, Codex, opencode, or anything else that can run a command:
Install and configure Svipall by following the instructions here:
https://raw.githubusercontent.com/ilien-dev/svipall/main/docs/install.mdThat page guides an agent through platform detection and verification, then asks which integration you want: CLI + Skill (recommended, lower context use) or MCP + Skill (the full MCP tool surface). It also asks whether to configure every project or only the current one, and verifies the chosen result instead of treating a skill as MCP registration. When Svipall already exists, it shows the installed and latest versions and asks whether to update the shared user installation or keep the current version before it writes the integration. Completion depends on the agent, client configuration and available permissions.
Claude Code: install the plugin
/plugin marketplace add ilien-dev/svipall
/plugin install svipall@svipall
/svipall:setup/svipall:setup installs the binary if it is missing, checks the server answers, and offers to make
Svipall the way Claude reaches the web in every project. It asks before each of those.
/svipall:doctor reports the installation's capabilities. /svipall:update shows the installed
and latest releases, then updates the binaries only if you choose to. /svipall:uninstall offers
removal of setup's registration, memory and strict-mode changes. Removing the binary and the data
are separate choices.
Install it yourself
One line, with no toolchain and nothing to compile:
curl -fsSL https://raw.githubusercontent.com/ilien-dev/svipall/main/install.sh | sh # macOS, Linux
irm https://raw.githubusercontent.com/ilien-dev/svipall/main/install.ps1 | iex # WindowsOr a package manager, or the container image:
brew install ilien-dev/svipall/svipall # macOS, Linux
scoop bucket add svipall https://github.com/ilien-dev/scoop-svipall && scoop install svipall
docker pull ghcr.io/ilien-dev/svipall:latest # or :slim, the http tier only; see container notes
npx --yes svipall doctor # if node is already there
cargo install svipall # from source; add `svipall models install` for the modelsThe installers verify checksums where they can, and a mismatch stops the install. A missing checksum file, entry or hashing utility only warns, so a successful exit is not by itself proof the archive was verified: read the output. If the destination already contains another version, the installer states that the binaries are shared by every harness and asks before replacing them.
When a newer release exists, Svipall says so once per session. One command updates both binaries with the channel that installed them and refreshes the skills you copied by hand:
svipall update # --check only compares versionsThen close every session that uses Svipall and open it again. An agent can do the same from docs/update.md.
Platform builds, what ships where, building from source and wiring it into any MCP client are all in docs/install.md. If you have never installed anything from a terminal, GET-STARTED.md is this section with nothing assumed.
Then ask for something
There is no key to paste and no account to create.
"Read this page and summarise the pricing." "Crawl these docs and write me an
llms.txt." "Watch this listing and tell me when the price moves." "Get me every row of that table as CSV."
The assistant can choose among the exposed tools. Supported challenges that need a pair of eyes
go to a human dashboard at http://localhost:8787/human.
Or drive it from a shell
svipall fetch https://example.com/article
svipall fetch https://shop.example/item --query "shipping costs"
svipall fetch https://docs.example/api --schema auto # rows from a listing you've never seen
svipall crawl https://docs.example/ --pages 50 --out pages.csv
svipall search "rust async runtime" --engine all
svipall snapshot https://news.ycombinator.com # the page as roles and refs, not markup
svipall serve --port 8788 # the same server as a local REST APICompleted data commands print one JSON object to stdout and diagnostics to stderr, so the
output can be piped to jq. serve is a long-running server, and help is written to stderr.
What comes back
A historical run of svipall fetch https://example.com, with the content string cut short.
Current automatic fetches also report identity_used, and the fallback fields described below when
they have something to report:
{
"attempts": ["http: 200 (170ms) OK"],
"chars": 167,
"content": "# Example Domain\n\nThis domain is for use in documentation examples…",
"final_url": "https://example.com/",
"optimization": "ordinary",
"quality": "thin",
"quality_reasons": ["thin_text"],
"status": 200,
"tier_used": "http",
"title": "Example Domain",
"tokens_estimated": 42,
"url": "https://example.com"
}tier_used says how hard it had to try and quality says what actually arrived. When a page does
not arrive, the same object carries blocked_reason, wall_kind, wall_vendor, wall_evidence
and a note telling your agent what to do next. Straight from a committed benchmark record:
{ "wall_kind": "vendor", "wall_vendor": "kpsdk.io", "wall_evidence": "header x-kpsdk-ct" }A detected block carries a verdict alongside the returned content. A clear verdict still needs a content check, because the classifier cannot show that the requested records arrived intact.
What you can actually do with it
You want to… | It looks like this |
Read one page cleanly |
|
Turn a listing into rows |
|
Pull a data table |
|
Read what a video says |
|
Skip the scraping entirely |
|
Turn a docs site into a corpus |
|
Search without a key |
|
Let the agent click things |
|
Attempt a browser challenge | Automatic routing can escalate to a patient browser tier; unresolved challenges and detected blocks are reported, but the remote cause is not always identifiable |
Attempt a captcha locally | Fifteen widget families and eleven answer modalities, model support where available and a phone-friendly human dashboard. No paid solver; local budgets and remote restrictions still apply |
Log in once and stay in |
|
Watch a page |
|
Read PDFs and Office files | docx, xlsx, pptx, odt, epub, rtf, csv and pdf come back as Markdown, from the web or from |
Drive it from any language |
|
Who it is for
You are… | Svipall gives you… |
A Claude Code, Claude Desktop or Cursor user | One line of setup and tools your assistant picks by itself. Research, documentation, price comparison, monitoring |
A developer building AI agents | A local web layer with structured output, token budgets, file export and resumable crawls; live web outcomes remain variable |
A RAG or dataset builder | Bounded site crawls to Markdown, near-duplicate labels, |
A data or research person | Pages that sit behind "checking your browser" walls, and an honest answer when your address cannot open one |
A privacy-conscious operator | No scraping API, no captcha farm, no geolocation lookup, no update check, no telemetry. Additional downloads are the managed browser when needed (automatic provisioning can be disabled) and the blocklists you enabled |
A security or QA engineer testing your own site | A reproducible benchmark whose raw run logs are committed in this repository, and a request log that names which tier answered and which wall appeared |
Svipall runs on your own hardware. If you want a URL you can curl from a serverless function,
use a hosted scraping service instead. If you want the web inside your own agent, Svipall does that
processing locally; browser traffic and optional downloads are described under
Privacy and safety.
How it works, in plain words
The steps below describe the emulated tiers. The current automatic policy can promote a supported emulated route and append one eligible native fallback. Wall verdicts can end the attempt. Content-quality labels alone do not trigger escalation.
Ask for the page through HTTP first on a new route. The default engine emulates selected Chrome network characteristics. In the historical
public31runs above, 59 of 93 cells stopped at this tier, and 44 of those scoredokunder that benchmark's rule. A route that stops here has still not necessarily delivered the page.If the page needs JavaScript, open a browser. Headless Chromium runs the scripts and hands back the rendered document.
If the site checks for robots, wear a disguise. The stealth tier patches known browser surfaces to match the emulated identity. The offline probes check those surfaces; they cannot prove that an arbitrary detector will accept them.
If the site wants a real person, act like one. The
realtier is a visible-but-offscreen browser with a persistent profile. It moves the pointer along curves and scrolls with a wheel.If there is a challenge, answer it or wait it out. The
warmtier runs the captcha strategy loop during its bounded wait and avoids pointer activity on recognized self-verifying interstitials. This does not guarantee clearance.Use native only as a last resort. When eligible and within the remaining budgets, try one native browser attempt. It exposes real device characteristics and reports a privacy notice.
Remember what worked. Two supporting observations can promote a useful emulated route for later visits in the same context. Native stays last even when it succeeds.
Report the observed failure. Where available, a blocked result includes
blocked_reason, the classified wall, recognized vendor/evidence and a suggested next step. Classification is heuristic. Transport errors and local budget deferrals may have less page evidence.
MCP tools
Twenty-nine tools, all local.
Tool | What it does |
| Fetch a page as Markdown or structured JSON. |
| Bounded-parallel fetch of many URLs, with |
| DuckDuckGo / Bing / Brave without an API key; |
| Discover a site's search form and learn its query-URL pattern when possible; later fetches still follow normal routing and policy |
| Same-domain crawl with robots.txt, dedup, boilerplate removal, |
| A site's URLs without crawling it: robots.txt, sitemaps (nested indexes and |
| The page as roles, accessible names and short refs that |
| click, type, fill, press, hover, select, scroll, wait, eval, goto, screenshot, hold, verify, console; supported pointer/keyboard/wheel actions use the behavior layer, while |
| Observe matching JSON/network responses during a bounded browser visit; API usability and completeness are not guaranteed |
| A video's captions (a person's first, else the platform's automatic ones, in |
| Persistent session with cookies and page state across calls |
| PNG of the rendered page, |
| What changed on a page since Svipall last saw it |
| Persist a watch and check it while the server runs; list or check to retrieve changes. Region recovery after a redesign is heuristic |
| Key-value memory that outlives the session |
| Which tier answered, which wall appeared, how long it took, per domain |
| Visible window for a manual login or challenge; cookies saved to a profile |
| Per-domain proxy, or a pool of |
| Export/import an encrypted browser profile between machines |
| Learned tiers, cooldowns, routes, per-exit health and latency, profiles, open browsers, solver stats, which models answer and from where, whether the host has a real GPU, |
| Download or manage Chrome for Testing |
| Attempt a captcha on the blocked page and return the resulting content or unresolved state |
| Local captcha attempts; the dashboard also exposes |
The CLI
svipall fetch | crawl | snapshot | capture | search | map | log | notes | watch
profile | browser | route | status | serve | doctor | update | hook
config show | set | preset
solver export-corpus
quality ask | export-training | trainA test asserts the usage text names every command the binary answers to, and a second test keeps
skill/SKILL.md in step with both.
The REST API
The same server, over HTTP, so any language can drive it without an MCP client or a shell.
svipall serve --port 8788 # the bearer key is printed once, and kept in ~/.svipall/api_key
curl -sH "Authorization: Bearer $KEY" -H 'content-type: application/json' \
-d '{"url":"https://example.com","query":"pricing"}' localhost:8788/v1/fetchsvipall-mcp mounts the same router when rest_port is set, on its own listener, and shares its
browser pools, page cache and route evidence with the MCP tools.
Nineteen routes, one per tool, each taking that tool's own JSON as the body:
| pages |
| finding things |
| a real browser |
| the captcha, answered on the blocked page |
| memory |
| configuration |
| what this installation has learned. |
| the one route with no key, so a container healthcheck does not need one |
A blocked page is a 200: the call ran, the page did not. blocked_reason, wall_kind and
note can appear in the body as over MCP. Non-2xx responses include a malformed body (400), a bad key
(401), a browser Origin or a rebound Host (403), a body over 2 MB (413) or a broken
installation (500). An unknown job can return 404, and routing can reject unsupported paths
or methods. A client must inspect both the HTTP status and the tool result before deciding to retry.
Every tool and job route needs the key, including on loopback. Only /v1/health is exempt.
A local port is not a boundary on its own: Svipall carries logged-in profiles, cookies and your
exit address, so anything that reaches the port can make requests as you.
Two more checks sit in front of the key, because binding to 127.0.0.1 does not stop a page in your
own browser being served a DNS answer of 127.0.0.1 and posting to it: any request carrying an
Origin header is refused, and on a loopback bind so is any Host that is not loopback. There is no
CORS layer and there will not be one, because no browser page is a client of this API.
Ten tools are deliberately not routes, in three groups, and rest.rs records why next to each:
browser_open/browser_do/browser_close, whose persistent session lifecycle is outside this
REST interface's current design; web_login, whose interactive window is also excluded; and the six
solve_*/captcha_status/report_captcha tools, which already answer on the dashboard port in the
classic solver wire shape. Twenty-nine tools minus those ten is the nineteen routes above. A new
#[tool] fails the test suite until it is listed as a route or as a named exclusion.
A long crawl runs as a job and does not hold the connection. "async": true answers 202 with an id. GET /v1/jobs/{id} polls it, GET /v1/jobs/{id}/stream follows it as Server-Sent Events, DELETE stops
it. The id is the crawl_id, so there is one handle to learn and resuming is {"crawl_id": "…"},
the same word the MCP tool and the CLI already use. A cancelled crawl stops between pages after
that page's links are queued, so its frontier is kept. It is never aborted, because that would leak a
browser page. A job whose process was killed becomes interrupted, and interrupted is resumable.
The first frame of a stream is always a snapshot from the store, so a subscriber that joins at page
forty is never told the job started at zero. And a queued job whose site already has one running is
held back: two crawls of one site would spend one address's reputation with that host twice as fast,
which is the scarcest thing a local-only tool has. Full contract in docs/rest.md.
How Svipall compares
The following describes project scope from primary documentation checked on 2026-09-07. It is not a feature-exhaustive comparison or a head-to-head performance test.
Project | Documented focus |
Svipall | Local Rust CLI, MCP and REST server; bounded automatic routing, content labels and local challenge attempts with human fallback |
Web scraping/crawling API with hosted and self-hosted options; the open-source and cloud offerings differ | |
Python crawler with browser extraction and a Docker server offering API and MCP access | |
Python adaptive parsing, fetchers and spiders, with session/proxy controls and MCP integration | |
Browser automation through MCP using structured accessibility snapshots |
The historical benchmark above does not establish current superiority over these projects. Choose based on your required integration and validate your own target pages.
Everything else
This file is the short version. Everything it leaves out is in the documents below.
Every platform, what ships where, building from source, wiring it into any MCP client | |
Every published number, with the command and the log that reproduce it, failures included | |
The whole surface, tool by tool | |
Fifteen widget families, eleven answer modalities, and what happens when none of them work | |
Every key in | |
Nineteen routes, the job routes, and what a status code means | |
How a page becomes Markdown, and how well, measured against three corpora | |
What leaves this machine, and what does not | |
Stated on purpose | |
The crates, and why they are separate | |
Building, testing, and the benchmarks | |
What the binary returns, for scripts | |
The embedded weights, their licences and their sizes | |
Firefox · HTTP/3 · Benchmarks | The engineering notes |
Changelog · Contributing · CLA · Disclaimer |
About the name
Svipall is one of Odin's names in Grímnismál, stanza 47. Bellows renders it as "The Changing" in his translation notes. The project uses that name as an image of changing appearance, not as a promise of invisibility.
That is the idea behind its emulated identities: keep the machine, browser, network fingerprint and input behaviour coherent within a session, and retire sessions when they are refused. Native fallback instead uses real browser/device characteristics. Neither policy guarantees that a site will accept the visit or be unable to link it to an earlier one.
License
AGPL-3.0-only, subject to the terms in LICENSE, including its conditions for
distribution and section 13 on remote network interaction. The component licences and linking
exception below also apply. This paragraph is not a substitute for those terms.
crates/svipall-extract, the extraction engine, is deliberately MIT OR Apache-2.0 so that a
project under any licence can depend on it. crates/svipall-cdp keeps its upstream terms
(chromiumoxide, MIT OR Apache-2.0) and crates/svipall-quic keeps its own (quiche, BSD-2-Clause). The default build links BoringSSL under an explicit AGPL section 7 linking
exception. These are set out in NOTICE and
THIRD-PARTY-NOTICES.md.
Contributions are taken under CLA.md: contributors keep the copyright in their work and
grant the maintainer a licence broad enough to also release it under other terms. The public
release stays AGPL-3.0-only. For a licence other than the AGPL, write to code@ilien.dev.
Trademark
The name Svipall and the Svipall logo are trademarks of the author. They are not licensed under the AGPL, and nothing in this repository grants a licence to them.
The licence gives you the code. It does not give you the name. Run it, study it, modify it, fork it and redistribute it freely under the AGPL. Distribute a modified version under a different name and without the logo, so that nobody who downloads it is misled about who produced it or what is in it.
The project permits descriptive references such as saying that your project uses Svipall, works with Svipall, or is a fork of Svipall, without implying endorsement.
Disclaimer
Svipall is provided as is, with no warranty and no liability, and it grants you no
authorisation with respect to any system you point it at. Complying with the law, with
data-protection rules and with a site's terms is the operator's responsibility, not the author's.
Read DISCLAIMER.md before you run it against something that is not yours.
Available Tools
30 toolsbrowser_closeA
Close a session opened with browser_open and release its browser. Call it when the multi-step work is done; sessions left open keep a browser running.
Inputs: session_id (required).
browser_doA
Navigate and act inside a session from browser_open: the same actions as web_act, ref from web_snapshot accepted. Omit url to keep acting on the current page. Returns per-action results and the page content, filtered by query when given.
Inputs: session_id (required), url, query, actions, +2 more.
browser_openA
Open a persistent stealth browser session and return a session_id for browser_do. Use for multi-step work where cookies and page state must survive between calls: log in, then browse; add to cart, then check out. For one page and a few actions web_act is simpler. profile reuses cookies saved by web_login. Close it with browser_close.
Inputs: proxy, profile, visible.
browser_setupA
Manage the browser behind the browser, stealth, real and warm tiers. status (default) says which binary would run and why; install downloads Chrome for Testing (about 190 MB) when the machine has none; update replaces it with current stable; remove deletes it. Use when a fetch or web_status reports no usable browser. Nothing is downloaded unless asked.
Inputs: action, artifact.
captcha_statusARead-only
Check a captcha task by its taskId, as returned by solve_turnstile, solve_recaptcha_v2, solve_hcaptcha or solve_image_captcha. Returns status solved, processing or failed, with the token or text once solved.
Inputs: taskId (required).
report_captchaA
Report whether a captcha answer worked (good=true) or was rejected (good=false), by taskId. Call it after submitting a token from solve_turnstile, solve_recaptcha_v2 or solve_hcaptcha: the outcome orders the strategies tried next time on that route, so an unreported rejection is repeated.
Inputs: good (required), taskId (required), note.
solve_and_continueA
Solve the captcha on a blocked page in place and return the page behind it. The right choice whenever the goal is the content: solve_turnstile, solve_recaptcha_v2 and solve_hcaptcha return a bare token bound to the session and address that produced it, which rarely works elsewhere. Use after web_fetch returns blocked_reason with a captcha widget. Non-interactive widgets clear on their own; one that needs a person opens a visible window or the dashboard (URL in web_status).
Inputs: url (required), profile, timeout_s, extraction, +1 more.
solve_hcaptchaA
Solve an hCaptcha challenge from its sitekey and pageUrl and return the token. Use only when you will submit the token yourself from the same session and address; to read the page behind the challenge use solve_and_continue. Returns the token, or a taskId to follow with captcha_status while a person solves it.
Inputs: pageUrl (required), sitekey (required).
solve_image_captchaA
Read the characters in an image captcha given as base64 or a URL and return them as text. Use when a form shows a picture of distorted characters you will type yourself; for a challenge widget on a blocked page use solve_and_continue. Returns text, or a taskId to follow with captcha_status.
Inputs: image (required), is_base64.
solve_recaptcha_v2A
Solve a reCAPTCHA v2 challenge from its sitekey and pageUrl and return the gRecaptchaResponse token. Use only when you will submit the token yourself from the same session and address; to read the page behind the challenge use solve_and_continue. Returns the token, or a taskId to follow with captcha_status while a person solves it.
Inputs: pageUrl (required), sitekey (required), invisible.
solve_turnstileA
Solve a Turnstile challenge from its sitekey and pageUrl and return the token. Use only when you will submit the token yourself from the same session and address, such as a form posted with web_fetch method=POST; to read the page behind the challenge use solve_and_continue. Returns the token, or a taskId to follow with captcha_status while a person solves it.
Inputs: pageUrl (required), sitekey (required).
web_actA
Open a URL in a browser, run a list of actions and return the resulting page. One shot with no session: for several steps on one login or cart use browser_open + browser_do. Take a web_snapshot first and name elements by ref. Actions: click, type, fill, press, hover, select, scroll (until:'stable' loads everything), wait, eval, goto, verify, console, screenshot, hold; each is an object with do and the fields it needs. Returns per-action results and the final page as markdown.
Inputs: url (required), actions (required), tier, proxy, +3 more.
web_captureARead-only
Record the JSON and XHR responses a page fetches while it loads and return them: the site's own API, smaller, typed and more stable than the HTML built from it. Use to find the real endpoint behind a listing or pagination; an endpoint that took page=1 takes page=2, which beats following links. Call once without pattern to see what the page asked for, then with pattern (URL substring) and bodies=true for the payloads. Returns endpoints and responses with url, status, mime, and body when asked.
Inputs: url (required), tier, bodies, pattern, +3 more.
web_crawlARead-only
Crawl one site from a start URL and return every page as markdown, deduplicated, robots.txt obeyed. Use when the pages are not known in advance; when they are, web_fetch_many is cheaper, and web_map lists a site's URLs for a few hundred tokens before deciding to crawl. max_pages (20), max_depth (2), include (URL substring), query (rank by relevance, stop when saturated), strategy=dfs for a manual or a paginated listing, schema or tables for rows from every page. For many rows pass out_file (.csv, .json, .jsonl): a path comes back instead of the pages. Returns the pages and a crawl_id; pass it back as crawl_id to resume an interrupted crawl. Links to a page's own site are paths, to be joined to that page's url.
Inputs: url (required), also, mode, dedup, +19 more.
web_diffARead-only
Compare a page with the copy svipall cached last time and return what changed: changed, similarity, and the added and removed markdown blocks. Use for a one-off question of whether a page changed since it was last read; to keep checking on a schedule use web_watch. Cheap: the comparison is a stored fingerprint, not a second full copy.
Inputs: url (required), refetch.
web_fetchARead-only
Fetch one URL and return its main content as markdown (PDF and office documents too), or as rows with schema or tables. The default way to read a page: mode=auto climbs http -> browser -> stealth -> real -> warm, remembers the working tier per domain, and is never set by hand. Cut tokens with query (keep only relevant blocks), css_selector, max_tokens + cursor (page through), or out_file (write to disk, return a path). To click use web_snapshot; for the site's JSON API use web_capture; for several known URLs use web_fetch_many. Returns content, title, tier_used and quality; links to the page's own site are paths, to be joined to url. A wall returns blocked_reason and a note saying what to do: act on it, never retry blindly.
Inputs: url (required), body, mode, cache, +24 more.
web_fetch_manyARead-only
Fetch several URLs in parallel with the same escalation, query filter, schema and tables as web_fetch, results in input order. Use when the URLs are already known, from web_search, web_map or a listing; to discover them use web_crawl. Returns one web_fetch result per URL plus corroboration: how many distinct documents the set really is, duplicates marked same_text_as.
Inputs: urls (required), mode, query, schema, +4 more.
web_logARead-only
Report what this installation has done per domain: which tier answered, which wall appeared, how long it took. view=summary shows domains that are half blocked or slow, the sign of a learned tier gone wrong (reset it with web_status forget_tier); view=recent lists the last events. web_status shows the current state; this is the history.
Inputs: view, limit, domain, since_secs.
web_loginA
Open a visible browser window so a person can log in or pass a challenge by hand, then save the cookies to a profile. Use when a fetch returns blocked_reason naming a login wall or a challenge no automatic tier clears. Without profile the domain's auto profile is used and later fetches pick it up on their own; name a profile to reuse it explicitly. Move it to another machine with web_profile.
Inputs: url (required), profile, timeout_s.
web_mapARead-only
List a site's URLs without fetching its pages: robots.txt, sitemaps (nested indexes and .gz), RSS/Atom feeds and homepage links. Use before web_crawl to decide what is worth fetching, or to find the page for a topic: a few hundred tokens instead of the thousands a crawl costs. Returns urls with sources_used, sitemaps and feeds; read the ones that matter with web_fetch_many.
Inputs: url (required), limit, include, sources.
web_notesA
Remember a value across sessions: set a key, get it back, list by prefix, delete it. Use for state needed in a later session, such as the last id seen, a learned URL pattern or a checkpoint. Keys are path-like (shop/last_id) so a prefix groups them.
Inputs: key, value, action, prefix.
web_profileA
Move a logged-in browser profile between machines: export writes an encrypted archive, import restores it, list shows the profiles web_login saved. Use so a challenge a person passed once with web_login is not passed again elsewhere. password is required; there is no unencrypted form.
Inputs: file, name, action, password.
web_routeA
Send one domain (subdomains inherit) through a proxy from now on, or through a pool with proxies and countries; remove drops the route, no arguments lists routes, check=true tests the exits for liveness, latency and DNS leak. Use when a fingerprinting wall never yields at any tier, or a site is locked to a country. Give country so the browser's timezone and language match the exit.web_status shows each exit's health per domain.
Inputs: check, proxy, domain, remove, +4 more.
web_screenshotARead-only
Save a PNG of a page rendered in a real browser, anti-bot handled like web_fetch, and return its path, by default with the image inline. Use when the question is visual: layout, a chart, an image, how a page looks to a person. To read or act on a page use web_snapshot instead: cheaper, and it gives refs, whereas a screenshot cannot be clicked. full_page captures the whole scroll height, mobile renders it as a phone.
Inputs: url (required), tier, proxy, inline, +4 more.
web_searchARead-only
Search the web without an API key by reading public search engines' own result pages; the first engine with results answers, engine=all merges them. Use to find URLs for a topic, then read them with web_fetch or web_fetch_many. To search inside one site use web_site_search. Returns title, url and snippet per result, not the pages.
Inputs: query (required), limit, engine.
web_site_searchARead-only
Search one site through its own search box and learn the URL pattern the form produces. Use for shops, job boards and docs whose content only appears when asked for: a crawl reaches only what is linked, and web_search covers the whole web, not one site. Returns results_url, the pattern (/search?q=...) that makes every later query a plain web_fetch with no browser, plus the first results while fetch is true.
Inputs: url (required), query (required), fetch, timeout.
web_snapshotARead-only
Read a page as its interactive structure: every button, link and field with its role, accessible name and a short ref such as e12. Use instead of web_fetch when the next step is to click or type, and instead of web_screenshot when a page has to be understood: deterministic, no image, a fraction of the tokens. find keeps only matching nodes, max_depth goes shallower. Returns the nodes; pass a ref to web_act or browser_do so no CSS selector has to be guessed.
Inputs: url (required), find, tier, limit, +3 more.
web_statusA
Show the current state: learned tiers, cooldowns, address budgets, proxy routes, profiles, open browser sessions, resumable crawls, solver stats and the dashboard URL. Use when something is blocked or slow to see why, and to reset it: clear_cooldown, forget_tier, clear_budget and clear_cache take a domain. Without arguments nothing changes. The history per domain is web_log.
Inputs: configure, clear_cache, forget_tier, clear_budget, +1 more.
web_videoARead-only
Read a video: captions and chapters as one [m:ss] timeline, from a watch page, an embedded player, tracks or the stream manifest. Use instead of web_fetch on a video page, which returns only the description. Returns content, captions (manual, auto or asr), chapters, notes; an encrypted stream is reported as drm, never read.
Inputs: url (required), lang, cursor, frames, +3 more.
web_watchA
Watch a page, or one css_selector region of it, and report when it changes. add starts a watch (interval_secs, default 3600), list shows what changed and when, check looks now, remove stops. A check that finds nothing costs one conditional request. Watches survive restarts but run only while the server is up. For a single comparison with no watch use web_diff.
Inputs: url, label, action, css_selector, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 30 tools
Each tool has a clearly distinct purpose: fetching vs browsing vs crawling vs captcha solving vs session management. Even similar tools like web_fetch and web_fetch_many are clearly differentiated by known vs unknown URLs. The separate solve_* tools for different captcha types avoid ambiguity.
All tools follow a consistent lowercase snake_case pattern with domain prefixes (web_, browser_, solve_, captcha_, report_). The verb_noun or noun_verb structure is predictable, e.g., web_fetch, browser_open, solve_turnstile.
30 tools is on the high end, but the broad scope of web automation (fetching, browsing, captcha solving, monitoring, state) justifies the count. Each tool serves a specific function, and the organization into clear categories prevents the set from feeling bloated.
The toolkit covers the full lifecycle of web interaction: fetching, browsing, crawling, searching, captcha solving, session persistence, monitoring, and diagnostics. There are no obvious dead ends—every operation has a corresponding tool, and helpers like web_status and web_log provide transparency.
Maintenance
Related MCP Connectors
Turn any public website into an MCP server for agents to search, read and navigate.
One MCP server for all web data. Scrape, search, crawl, and AI research in one install.
Web search API and MCP server for developers building AI agents.
Free web search for AI agents. No API key required. Hosted MCP in active development.
Related MCP Servers
- FlicenseBqualityDmaintenanceAn MCP Server for Web scraping and Crawling, built using Crawl4AI224-
- FlicenseNot gradedqualityDmaintenanceA locally-hosted MCP server that provides AI assistants with advanced web crawling capabilities, including structured data extraction, deep site crawling, and page screenshots. It enables users to convert single or multiple URLs into clean Markdown content for processing by LLMs without requiring external API keys for basic features.-
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server that gives AI agents the web as compact, ranked, verified evidence — no API keys, no cloud retrieval, all models local.35 npm1MIT
- AlicenseNot gradedqualityDmaintenanceA fully local MCP server that provides web search via self-hosted SearXNG and page-to-markdown conversion (static and JS-rendered), all aggregated behind a single endpoint for use with AI assistants.MIT