A side-by-side look at the Agentfetch MCP and Olostep MCP Server MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Agentfetch MCP for search & data extraction work as a local process; choose Olostep MCP Server for search & data extraction as a local process. You can also run both side by side in one mcpServers block.
JINA_API_KEY, FIRECRAWL_API_KEY, REDIS_URL, CACHE_TTL_SECONDS.fetch_url, estimate_tokens, fetch_multiple.OLOSTEP_API_KEY.create_map, create_crawl, get_crawl_results.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Search & Data Extraction | Search & Data Extraction |
| Quality signal | 57/100 · Good | 61/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Local subprocess (stdio) | Local subprocess (stdio) |
| Auth | API key required | API key required |
| Pricing | Free | BYOK (pay the provider) |
| Required env vars | JINA_API_KEYFIRECRAWL_API_KEYREDIS_URLCACHE_TTL_SECONDS | OLOSTEP_API_KEY |
| Verified owner | Community listing | Community listing |
| GitHub stars | 3 | 24 |
| Directory activity | 4 views 0 installs 0 upvotes | 1 views 0 installs 0 upvotes |
| Tools | 4 | 10 |
| Full listing | View Agentfetch MCP | View Olostep MCP Server |
fetch_urlFetch any URL and return clean, LLM-ready Markdown with token count, metadata, and 6h caching.
WHEN TO USE:
- You have a specific URL whose content you need.
- You want to cap response size to stay inside your context window.
- You want repeat fetches to be cheap (cache hits ≈ $0.0001).
- The URL might be JS-rendered, a PDF, or behind a paywall — this tool
auto-routes to the right fetcher (Trafilatura → Jina → FireCrawl → PDF).
WHEN NOT TO USE:
- You don't know which URL to fetch — use search_and_fetch instead.
- You have many URLs to fetch — use fetch_multiple instead.
Args:
url: The URL to fetch.
max_tokens: Hard cap on response size. Default unlimited. Pass this
if you're tight on context budget — cheaper than over-fetching.
format: "markdown" (default — recommended), "text", or "json".
use_cache: True returns a cached copy if one exists (≤6h old).
Pass False only when freshness matters (live news, prices).
Returns:
{
"url": str, "success": bool, "markdown": str,
"metadata": {title, author, published_date, domain, word_count,
token_count, reading_time_seconds, content_type, language},
"cache": {hit, cached_at, expires_at},
"fetch_info": {fetcher_used, fetch_time_ms, cost_credits},
"error": str | None
}
estimate_tokensEstimate token count of a URL's content WITHOUT fetching the body.
WHEN TO USE:
- You're considering fetching a URL but unsure if it fits your remaining
context window. This call is ~10x cheaper than a full fetch.
- You want to triage a list of candidate URLs before deciding which to
actually retrieve.
IMPORTANT: Many servers omit Content-Length on dynamic / chunked
responses. When that happens, this tool returns confident=false and
estimated_tokens=null. In that case, call fetch_url with a max_tokens
cap instead of trusting the estimate.
Args:
url: The URL to estimate.
Returns:
{
"url": str, "success": bool,
"estimated_tokens": int | null,
"byte_size": int | null,
"content_type": str,
"confident": bool,
"note": str
}
fetch_multipleFetch up to 20 URLs concurrently. Each result is the same shape as fetch_url.
WHEN TO USE:
- You have a list of URLs (search results, links from a doc, sitemap)
and want them retrieved in parallel rather than one at a time.
Args:
urls: 1–20 URLs. Larger batches: split into multiple calls.
max_tokens_each: Per-result cap. Apply this to keep total response
inside your context budget — total ≈ len(urls) * max_tokens_each.
use_cache: True for cache-aware fetching (default).
Returns:
{"count": int, "results": [<fetch_url shape>, ...]}
search_and_fetchWeb search + fetch top results in one call.
WHEN TO USE:
- You have a research question, not specific URLs. E.g. "what's the
latest on X", "find docs for Y library", "recent news about Z".
- You'd otherwise have to call a search tool, parse results, then call
fetch — this collapses that into one round-trip.
Args:
query: Search query (2–500 chars).
num_results: Top N to fetch (1–10, default 3).
max_tokens_each: Per-result cap (default 2000).
Returns:
{"query": str, "count": int, "results": [<fetch_url shape>, ...]}
create_mapGet a LIST of URLs on a website (URL discovery only — does NOT scrape content). Use when the user wants a list of links: 'show me all URLs on this site', 'map this website', or when you want to surface candidate URLs to the user before scraping a subset. Prefer `create_crawl` if the goal is to scrape the whole site — it discovers AND scrapes in one workflow. Use this only when the URL list itself is the deliverable.create_crawl**PREFERRED tool for crawling a website.** Use this whenever the user says 'crawl', 'scrape the whole site', 'get all pages from a site', or wants multiple pages from a single domain. This is the CORRECT tool for any whole-site scraping task. **Do NOT use `batch_scrape_urls` for crawling** - that tool is only for when you already have a specific list of unrelated URLs from different domains. Starts an ASYNC crawl that autonomously discovers and scrapes pages by following links from a start URL. Returns a crawl_id - the crawl runs in the background. You MUST then call `get_crawl_results` with the returned crawl_id to poll status and retrieve the scraped pages. Do NOT call `get_batch_results` with a crawl_id - crawls and batches are separate resources.get_crawl_resultsRetrieve the status and scraped pages for a crawl job. Pass the crawl_id returned by create_crawl. If the crawl is still in_progress, returns the current status so you can call again later (poll every ~10 seconds). Once completed, returns the list of discovered pages with their scraped content in the requested formats. This is the REQUIRED companion to create_crawl — create_crawl only kicks off the async job, this tool is how you actually get the content.batch_scrape_urlsScrape a SPECIFIC, KNOWN list of URLs (typically from different domains). **Do NOT use this for crawling a website** - if the user wants to scrape a whole site or 'crawl' a domain, use `create_crawl` instead. Use this only when you already have an explicit list of URLs to scrape (e.g., user provides a CSV of URLs, or you need to scrape unrelated pages). Returns a batch_id immediately. Use `get_batch_results` with the batch_id to fetch the scraped content once the batch completes (~5–8 min). Set `wait_for_completion_seconds` to poll automatically.get_batch_resultsRetrieve the status and scraped content for a batch job. Pass the batch_id returned by batch_scrape_urls. If the batch is completed, returns the scraped content for each URL. If still in_progress, returns the current status so you can call again later.Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"bch1212-agentfetch-mcp": {
"command": "uvx",
"args": [
"agentfetch-mcp"
],
"env": {
"JINA_API_KEY": "YOUR_JINA_API_KEY_HERE",
"FIRECRAWL_API_KEY": "YOUR_FIRECRAWL_API_KEY_HERE",
"REDIS_URL": "YOUR_REDIS_URL_HERE",
"CACHE_TTL_SECONDS": "YOUR_CACHE_TTL_SECONDS_HERE"
}
}
}
}
{
"mcpServers": {
"olostep-olostep-mcp-server": {
"command": "npx",
"args": [
"-y",
"olostep-mcp"
],
"env": {
"OLOSTEP_API_KEY": "YOUR_OLOSTEP_API_KEY_HERE"
}
}
}
}
answersAnswer a factual question using web search, optionally shaped into a flat JSON object of fields (returned with sources and citations). Best for a bounded, factual answer (e.g. a company's founding year, a product's current price). It is NOT reliable for enumerating a live list from a page (e.g. 'the latest N blog posts with titles and dates'). For that, use create_map or get_webpage_content on the page and read the results instead.search_webSearch the web for a given query and return structured results (non-AI, parser-based).scrape_websiteExtract content from a single URL. Supports multiple formats and JavaScript rendering.get_webpage_contentRetrieve content of a webpage in markdownget_website_urlsSearch and retrieve relevant URLs from a website (URL discovery only - does NOT scrape content). Use this only when the user wants a *filtered list of links* matching a search query. **Do NOT use this as a precursor to scraping** - if the user wants to scrape/crawl a site, use `create_crawl` directly.