Rover Fetch
БесплатноНе проверенAn MCP server for fetching and prepping web content for LLM agents.
Описание
An MCP server for fetching and prepping web content for LLM agents.
README

Rover
An MCP server that turns the web into clean, token-efficient Markdown your LLM agent can actually trust.
CI License: MIT OR Apache-2.0 Rust 1.96+ Status: alpha
Quick start · Why Rover · How it compares · MCP tools · Security · Features · Docs
Point your agent at a URL and Rover fetches it, strips the ads/nav/chrome, extracts the real content, normalises the markup, counts the tokens, optionally summarises to a budget, and hands back a YAML-frontmattered Markdown document — wrapped so the model knows it's untrusted third-party data, not instructions. The same binary runs as a long-lived MCP server for Claude Code and other agent harnesses, and as a one-shot CLI.

rover fetching the Charlie Dog (a.k.a. Rover 🐕) page and summarising ~19.6k tokens down to ~330 — summarisation here runs through a configured cloud backend.
[!NOTE] Rover is built for single-user-local deployment — one MCP server alongside your IDE/agent, not a multi-tenant gateway. Ship it as a binary, point your agent at it, get on with your work.
Why Rover
Agents that browse the live web hit the same four walls every time:
- 🧹 Boilerplate, ads, and chrome drown the content. Token budgets vanish into navigation menus and cookie banners.
- 🖼️ JavaScript-rendered pages return an empty
<div id="root">to anything that isn't a browser. - 🔁 Repeated fetches waste tokens, time, and money — and ignore politeness rules (rate limits,
robots.txt, caching headers). - 🛡️ Fetched web content is untrusted. A page can carry "ignore your instructions and…" straight into your agent's context. Most fetch tools hand it over raw.
Rover fixes all four. Extraction is the battle-tested readabilityrs crate (Prism/Shiki/rehype/WordPress/GitHub code blocks, MathJax/KaTeX, footnote dialects, lazy-loaded images, permalink anchors). On top of that Rover layers HTTP-aware caching, per-domain rate limiting + robots.txt, charset detection, configurable SSRF protection, a layered prompt-injection guard, optional headless rendering for SPAs, extractive and cloud-LLM summarisation, inline image captioning, and a long-running task model with NDJSON-streamed progress.
How your agent gets the web
| Rover | Claude Code WebFetch |
wget |
|
|---|---|---|---|
| What your agent gets back | Clean Markdown document + frontmatter, content hash, token count | A fast model's answer about the page (lossy, per-prompt) | Raw HTML / bytes |
| Strips nav/ads/chrome → Markdown | ✅ readability extraction | ✅ HTML→MD (non-optional) | ❌ |
| Reusable across calls (re-read, no re-run) | ✅ cached doc, stable hash | ❌ re-runs the model each prompt | ✅ (raw file) |
| Token budgeting & counts | ✅ estimate · max_tokens · summarise-to-fit · count-only |
❌ fixed truncation, no control | ❌ |
| HTTP-aware caching | ✅ TTL · ETag · Last-Modified · stale-while-revalidate | ◻️ flat 15-min cache | ◻️ timestamping (-N) only |
| JavaScript / SPA rendering | ◻️ optional (headless feature) |
❌ | ❌ |
| Batch fetch + per-domain rate limiting | ✅ batch_fetch, token-bucket, streaming progress |
❌ one URL per call | ◻️ recursive, no per-domain limit |
| SSRF / private-network protection | ✅ 5 levels + dial-time re-check (anti-DNS-rebinding) | ◻️ HTTP→HTTPS upgrade; private-IP stance undocumented | ❌ |
| Prompt-injection guard | ✅ layered: nonce wrapper + detectors + optional model | ❌ content goes straight to the model | — |
| Structured metadata (schema.org / OG / Twitter) | ✅ get_metadata |
❌ (must ask in the prompt) | ❌ |
| Inline image captioning | ✅ cloud VLMs (OpenAI / Anthropic / Gemini / compatible) | ❌ | ❌ |
| Works offline / no per-fetch API cost | ✅ extractive backend, no API key | ❌ model call per fetch | ✅ |
| Shared instance for multiple agents | ✅ rover mcp --http — bearer auth, one cache for every caller |
❌ stdio, one process per agent | ❌ |
✅ full · ◻️ partial/optional · ❌ no · — n/a · WebFetch column per the official Claude Code docs.
Rover isn't a web crawler. To recursively mirror or crawl an entire site, reach for
wgetorhttrack— Rover fetches and preps individual pages for an agent to reason over, not bulk downloads.
Quick start: wire it into your agent
rover meta use does the whole wiring in one command (MCP server, steering hooks for Claude Code, and a rules-file block):
rover meta use claude # Claude Code: claude mcp add + SessionStart (startup/clear/compact) + WebFetch hooks + CLAUDE.md block
rover meta use general # other harnesses: ./mcp.json + an AGENTS.md steering block
-s/--scope local|user|project (default local) mirrors the Claude CLI. It's idempotent and validates before it writes, so it leaves everything untouched if the claude binary is missing or a target file is malformed JSON. Full walkthrough, per-scope file mapping, and by-hand setup: rover-fetch.com/docs/quickstart.
To add just the MCP server by hand, run claude mcp add rover -- rover mcp for Claude Code, or point any MCP client at rover mcp over stdio with the standard JSON shape:
{
"mcpServers": {
"rover": {
"command": "rover",
"args": ["mcp"]
}
}
}
Running Rover for more than one agent? rover mcp --http serves the same tools over Streamable HTTP instead, so every caller on the network shares one instance and its cache. See Deployment.
Your agent now has these tools:
| Tool | What it does |
|---|---|
fetch |
Single URL → cleaned Markdown. Caching, headless rendering, image modes, token budgeting, inline summarisation. |
batch_fetch |
Fetch N URLs concurrently with per-domain rate limiting. Returns a task_id; stream progress with rover batch <id> --monitor. |
summarize |
Compact a cached or fresh page via extractive (offline) or cloud backends. Steerable with focus, preserve, target_tokens. |
get_metadata |
Extract Schema.org, Open Graph, and Twitter Card metadata without pulling the full body. |
count_tokens |
Estimate a URL's token cost across cl100k / o200k / claude / llama3 / qwen3 tokenisers without paying it. |
Full tool reference: rover-fetch.com/docs/mcp-tools.
…or use it from the shell
Every capability is also a one-shot CLI command — handy for scripts, CI, and trying things out:
rover fetch https://example.com/article # clean Markdown → stdout
rover fetch --max-tokens 4000 https://example.com # summarise to fit a budget
rover cache stats # entry count, size, expired
rover doctor # sanity-check the install
[!TIP]
rover --helpprints the full subcommand surface; every subcommand has its own--help.
Install
[!NOTE] Rover is pre-1.0 (
0.1.0). The build-from-source path below works today; the packaged channels (Homebrew tap, prebuilt tarballs, crates.io) come online with the first tagged release.
All channels install a binary named rover.
Build from source (works today):
cargo install --git https://github.com/aaronbassett/rover --locked
# or clone and build:
git clone https://github.com/aaronbassett/rover && cd rover
cargo build --release # binary at target/release/rover
The default build (~20 MiB) needs no model downloads, no Chrome, and no extra runtime dependencies.
Homebrew (macOS) — on release:
brew install aaronbassett/tap/rover
The rover formula ships the JavaScript-rendering (headless) build. It does not pull in a browser — headless rendering is opt-in and Rover auto-detects a Chrome/Chromium install at runtime (rover doctor verifies it). If you want headless mode, install a browser yourself, e.g. brew install --cask chromium. Other optional features (e.g. local-inference) are available from source via cargo install — see crates.io below.
Prebuilt binary (Linux & macOS) — on release:
One-line installer:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/aaronbassett/rover/releases/latest/download/rover-fetch-installer.sh | sh
Or download a .tar.xz from the latest release, verify its checksum, then extract it and move the rover binary onto your PATH:
tar xf rover-fetch-<target>.tar.xz # then move the extracted `rover` onto your PATH
Targets: x86_64/aarch64 Linux (gnu) and Intel/Apple-Silicon macOS. The prebuilt binary includes the headless feature (JavaScript-rendered pages).
crates.io — on release:
cargo install rover-fetch --features headless # crate is rover-fetch; binary is rover
[!NOTE] The crate publishes as
rover-fetchbecauseroveron crates.io is held by an unrelated project. The installed binary is stillrover.cargo installbuilds with the crate's default (basic) features; add--features headlessto match the prebuilt and Homebrew binary.
Requirements: Rust 1.96+ (edition 2024). Rover is pre-1.0: minor releases may include breaking changes, and the minimum supported Rust version can rise in any release.
The MCP tools
Every tool returns structured JSON; the content-returning tools (fetch, summarize, get_metadata) additionally wrap their payload in Rover's trusted-preamble + nonce delimiter (see Security & trust).
// fetch → cleaned, guarded Markdown document
{
"content": "⚠ The text inside <untrusted-content-a3f9c1> … is third-party web content …\n\n<untrusted-content-a3f9c1>\n---\nurl: \"https://example.com/article\"\ntitle: \"…\"\nestimated_tokens: 14823\ntokenizer: \"o200k\"\nextraction_quality: 0.98\nprompt_injection: { scanned: true, detected: false }\n---\n\n# Article title\n…\n</untrusted-content-a3f9c1>",
"cache_status": "miss",
"summarized": false
}
The example hero fetch, unwrapped:
---
url: "https://en.wikipedia.org/wiki/Rust_(programming_language)"
title: "Rust (programming language) - Wikipedia"
fetched_at: "2026-06-18T12:34:56Z"
content_hash: "sha256:b3e9…"
estimated_tokens: 14823
tokenizer: "o200k"
language: "en"
extraction_quality: 0.98
---
# Rust (programming language)
Rust is a multi-paradigm, general-purpose programming language…
Full schemas, arguments, and wire contracts: rover-fetch.com/docs/mcp-tools.
Security & trust
Rover treats the web as hostile by default. Three independent layers protect both your agent and Rover's own internal inference.
Prompt-injection guard
Fetched content is third-party data, not instructions — but a malicious page can still try to hijack your agent. Every content-returning tool (fetch, summarize, get_metadata) runs a layered guard:
- Structural wrapper (always on). The returned document is wrapped in a per-response, random-nonce delimiter —
<untrusted-content-a3f9c1>…</untrusted-content-a3f9c1>— behind a trusted preamble that tells the model to treat everything inside as data only. Forged copies of the tag are stripped, so a page can't predict the nonce or close the wrapper early. This is the load-bearing guarantee — it never relies on detection. - Pattern detector (always compiled). A curated literal + regex ruleset (instruction-override, role-injection, system-prompt-leak, tool-call-smuggle, data-exfil) runs over normalised text — NFKC, zero-width/control stripping, homoglyph folding, base64 surfacing — so obfuscated payloads still trip.
- ONNX classifier (opt-in). Build with
--features injection-modelto add a DeBERTa prompt-injection model (downloaded on first use) for novel phrasings the rules don't enumerate.
A configurable response level decides what happens on a hit:
| Level | Action |
|---|---|
strict |
Drop the body; return the warning only |
high |
Remove the matched spans / windows |
moderate (default) |
Quarantine matched spans in <DANGER>…</DANGER> + warn |
low |
Content intact; warn only |
disabled |
No detection (the wrapper still applies) |
Structured prompt_injection telemetry rides along on every response, and content Rover feeds to its own summariser/caption models is always independently cleaned at high strength — that hardening can't be disabled. Configure under [prompt_injection]; full contract in rover-fetch.com/docs/mcp-tools.
SSRF protection
Five levels: strict · loopback · project · lan · none. Every outbound URL is validated twice — once by parsed scheme/host, once against every resolved address before the socket opens — and a dial-time SSRF resolver re-applies the policy at each connection attempt, closing the DNS-rebinding TOCTOU window for both the initial request and every redirect hop. Default is strict (public IPs, http/https only). Full level matrix, the always-blocked address floor, and file:// handling: rover-fetch.com/docs/security.
Secret redaction
The tracing layer scrubs URL query-string secrets (api_key, token, secret, password) and HTTP Authorization-style credentials (Bearer … / Basic …, plus any field literally named authorization) before events reach any log destination.
[!CAUTION] The HAR recorder (
[debug] har_path) writes request/response bodies to disk unredacted by design — it's opt-in debug instrumentation. Protect the file with filesystem permissions and treat it as sensitive. Full threat model: rover-fetch.com/docs/security.
Features
Output that respects your token budget
Every fetch returns YAML-frontmattered Markdown with cache provenance, content hash, language, extraction-quality score, and a token estimate. Pass max_tokens (MCP) / --max-tokens (CLI) and Rover summarises to fit — the body is replaced with a budget-sized summary and the frontmatter gains summarized: true. The MCP fetch count_only arg (and the standalone count_tokens tool) returns just the estimate without the body. Token counts span five tokenisers (cl100k, o200k, claude, llama3, qwen3; default o200k).
Caching, with care
A single SQLite database (WAL mode) backs the cache, task state, and event log. Cache decisions honour Cache-Control, Expires, ETag, Last-Modified, and stale-while-revalidate. The default TTL is 15 minutes — deliberately short, so content that's been poisoned or quietly changed has a small blast radius before the next revalidation.
rover cache list
rover cache get <url>
rover cache purge 'https://example.com/*'
rover cache stats
rover fetch --force-refresh <url> # bypass cache for this request
Cache location: $XDG_DATA_HOME/rover/rover.db (or ~/.local/share/rover/rover.db). Override with ROVER_DATA_DIR.
Background tasks with streaming progress
batch_fetch (MCP) and rover batch <id> / rover task <id> (CLI) schedule long-running work and stream NDJSON events:
rover batch <id> --monitor # live: item_started, item_done, …, task_completed
rover task <id> # snapshot: progress, ETA, last event
rover task <id> --cancel # cooperative cancellation
rover batch <id> --format=ndjson # single JSON line, scripting-friendly
rover task <id> --monitor --from-event <id> # resume an interrupted stream
Tasks survive rover mcp restarts: batch jobs resume from persisted progress; summarisation jobs mark failed with a clear reason so the agent can re-request.
Summarisation
Two backends ship by default — and you can configure as many cloud backends as you want, each addressable by name:
[summarization]
default_backend = "default"
fallback_to_extractive = true
[backends.default]
kind = "extractive" # offline TextRank; no API key, no network
[backends.fast]
kind = "cloud"
provider = "openai" # openai, anthropic, gemini, openai_compat
model = "gpt-4o-mini"
api_key_env = "OPENAI_API_KEY"
openai_compat covers LM Studio, Ollama, vLLM, and anything else speaking the OpenAI chat-completions dialect. Steering parameters (focus, preserve, target_tokens, style) work uniformly across backends. When a cloud backend fails (auth, rate limit, network), Rover transparently falls back to extractive and tags the response with summarizer_fallback: { from, reason } — set fallback_to_extractive = false for strict-error mode.
Inline image captioning
Set images: caption (MCP) and Rover replaces images with model-written alt-text inline in the Markdown. Captioning uses cloud vision models and is always compiled in — no feature flag:
[image_captions]
default = "openai"
max_per_page = 5
[captioners.openai]
provider = "openai" # openai, anthropic, gemini, openai_compat
model = "gpt-4o-mini"
api_key_env = "OPENAI_API_KEY"
openai_compat works here too — point it at a local Ollama or LM Studio vision server (e.g. llama3.2-vision) for fully offline captioning with no API key.
Per-domain rate limiting & robots.txt
A per-host token bucket and a global concurrency cap, always on and configurable. The robots.txt gate is opt-in (off by default — Rover is an agent's browser, not a crawler, and robots.txt governs crawling); set robots.respect = true to enable it. When enabled, a Crawl-Delay floor is respected and the robots cache fails closed (a cached disallow_all sentinel for the configured failure_ttl), so a flaky robots endpoint doesn't quietly let traffic through.
HAR debug recording
Set [debug] har_path and every round-trip lands in a HAR file that imports cleanly into Chrome DevTools' Network panel. Sub-requests (CSS, fonts, beacons) are excluded so the file stays focused on what Rover actually returned.
[debug]
har_path = "./rover-debug.har"
har_body_cap = "64KiB"
Optional features (Cargo feature flags)
| Feature | Adds | Notes |
|---|---|---|
headless |
JavaScript-rendered SPA support via chromiumoxide | Uses system Chrome/Chromium (~32 MB) |
local-inference |
Local LLM summarisation via mistral.rs (default model: Qwen 3.5 0.8B) | ~80 MB; model downloaded on first use |
injection-model |
ONNX DeBERTa prompt-injection classifier (guard method 3) | Native ONNX runtime; ~200 MB model downloaded on first use |
cargo build --release --features headless
cargo build --release --features local-inference,headless
cargo build --release --features injection-model
Local models download on first use (or ahead of time via rover model download <repo_id>) and live under $HF_HOME/hub; manage them with rover model {list,download,remove}.
[!IMPORTANT] Cloud captioners (OpenAI, Anthropic, Gemini, OpenAI-compatible) are always compiled in — no feature flag. The
headlessfeature needs a Chrome/Chromium browser on the host; Rover auto-detects standard install paths (override with[headless] chrome_executable), androver doctorverifies the launch path.
Setup details, model recommendations, and memory profiles: rover-fetch.com/docs/features.
Configuration
Rover reads rover.toml from $XDG_CONFIG_HOME/rover/rover.toml (or ~/.config/rover/rover.toml); override with ROVER_CONFIG. Every key has a sensible default — the file is optional.
rover config show # merged effective config + per-key provenance
rover config set ssrf.level loopback # mutate in place (comments preserved, round-trip validated)
rover config set summarization.default_backend fast
A minimal rover.toml:
[fetch]
user_agent = "my-agent/1.0"
timeout_secs = 30
[ssrf]
level = "strict"
[cache]
default_ttl = "15m" # default; raise per-origin Cache-Control still wins
max_ttl = "7d"
[rate_limit]
requests_per_minute_per_domain = 30
per_domain_concurrency = 2
global_concurrency = 8
[summarization]
default_backend = "default"
[backends.default]
kind = "extractive"
The full reference — every section, key, and default — lives at rover-fetch.com/docs/configuration.
Subcommands at a glance
rover fetch <url> one-shot fetch → Markdown on stdout
rover mcp long-running MCP server (stdio)
rover cache list|get|purge|stats inspect / manage the local cache
rover batch <id> batch status; --monitor streams events
rover task <id> task status (any kind); --cancel, --monitor
rover doctor health checks; --format=ndjson for scripting
rover config show|set inspect / mutate config (provenance-aware)
rover model download|list|remove manage local model cache (feature-gated)
Full reference, exit codes, and NDJSON event shapes: rover-fetch.com/docs/cli.
Documentation
| Doc | What's in it |
|---|---|
| CLI | Every subcommand, flag, exit code, and NDJSON event shape. |
| MCP tools | MCP tool schemas: fetch, batch_fetch, summarize, get_metadata, count_tokens, and the prompt-injection wire contract. |
| Configuration | Every config section and key, with defaults, types, and examples. |
| Backends | Summarisation backend reference: extractive (TextRank) and cloud providers. |
| Features | Cargo feature flags: headless, local-inference, injection-model — setup, models, sizes. |
| Security | SSRF levels, address floor, DNS-rebinding mitigation, secret redaction, prompt-injection guard, known limitations. |
Contributing: CONTRIBUTING.md · Security policy: SECURITY.md · Changelog: CHANGELOG.md.
License
Licensed under either of MIT or Apache-2.0, at your option.
Установка Rover Fetch
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/aaronbassett/roverFAQ
Rover Fetch MCP бесплатный?
Да, Rover Fetch MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Rover Fetch?
Нет, Rover Fetch работает без API-ключей и переменных окружения.
Rover Fetch — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Rover Fetch в Claude Desktop, Claude Code или Cursor?
Открой Rover Fetch на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
автор: modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
автор: xuzexin-hzMCP-Agent
A simple, composable framework to build agents using Model Context Protocol by [LastMile AI](https://www.lastmileai.dev)
автор: lastmile-aiSpring AI MCP Client
Provides auto-configuration for MCP client functionality in Spring Boot applications.
mcp.natoma.ai
A Hosted MCP Platform to discover, install, manage and deploy MCP servers by [Natoma Labs](https://www.natoma.ai)
MCPHub
Website to list high quality MCP servers and reviews by real users. Also provide online chatbot for popular LLM models with MCP server support.
MCP Servers Rating and User Reviews
Website to rate MCP servers, write authentic user reviews, and [search engine for agent & mcp](http://www.deepnlp.org/search/agent)
mkinf
An Open Source registry of hosted MCP Servers to accelerate AI agent workflows.
Compare Rover Fetch with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории ai
