MCP Web Fetch Server
An all-in-one MCP web research server for fetching/searching/extracting/summarizing web content and optional local file or offline corpus access.
Fetch public URLs as markdown with chunked reading and optional raw/robots overrides.
Get HTTP metadata via HEAD, and batch-fetch up to 10 URLs concurrently with isolated errors.
Search the live web via DuckDuckGo with SearXNG fallback, optionally including a local corpus.
Extract structured links/images and summarize pages using the connected client’s LLM via MCP sampling.
Read, write, and list files within sandboxed local directories, with overwrite confirmation and roots support.
Use optional offline corpus/RAG features: hybrid search, cited answers, ranking explanations, corpus stats, ingestion, enrichment, classification, and embedding.
Expose MCP resources, prompts, completions, elicitation, progress notifications, logging, and an admin GUI; connect via stdio or Streamable HTTP with security controls.
Provides web search capability using DuckDuckGo, with no API key required. Used for fetching search results via the web_search tool.
Provides a fallback search engine via a local SearXNG instance, used automatically when DuckDuckGo scraping fails. Allows self-hosted metasearch integration.
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., "@MCP Web Fetch Server search for latest AI news"
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.
MCP Web Fetch Server
An all-in-one Python MCP server for web research: fetch pages, search the web, batch-fetch, extract links, summarize via client-side sampling, and (optionally) read/write local files — all for LLM agents like Cursor. Supports local stdio and Streamable HTTP for remote access, and exercises essentially every MCP protocol capability (Tools, Resources, Prompts, Completions, Sampling, Elicitation, Roots, Progress, Logging).
Documentation:
Document | What's inside |
Full end-user guide: install (Docker/Linux/Windows), Cursor setup, all tools, admin GUI, config, troubleshooting | |
Full technical reference: architecture, modules, MCP APIs, admin API, security, Docker stack, testing | |
Turning the server into an offline archive a local model can browse and search |
Features
Tools
fetch_url— page content as markdown, with chunked reading (start_index,max_length)fetch_metadata_tool— HEAD request metadatabatch_fetch— fetch multiple URLs concurrently, with per-URL error isolation and progressweb_search— search the live web (DuckDuckGo, no API key, with SearXNG fallback), the local corpus, or both, viasource=auto|web|corpus|bothimage_search— web image search (via SearXNG), returning image URLs, titles and source pagesdescribe_image— have the local vision model read any image URL and describe it, including text in itextract_links— structured link/image extraction from a pagesummarize_url— asks the connected client's LLM to summarize a page (MCP sampling)read_file/write_file/list_dir— sandboxed local file access (opt-in, disabled by default)
Offline corpus (optional)
Ingest your own documents and the same tools serve them instead of the web — an offline archive a local model can browse as if it were the internet.
rag_search— hybrid semantic + exact-term search over your documents, with citable URLsrag_answer— an answer written from your documents alone, with numbered citationsrag_explain— why a search ranked the way it did, arm by armcorpus_stats— what the archive containsPrompts:
explore_archive,research_corpus,cite_claim,compare_documents,summarize_categoryfetch_url,web_search,extract_linkstransparently serve the archive whenFETCH_NET_MODEisofflineorhybrid
uv sync --extra rag
ollama serve # the local model lives on the host
mcp-fetch-server ingest ./my-documents # PDF, DOCX, PPTX, EPUB, HTML, MD, TXT
mcp-fetch-server enrich # titles, summaries, tags, questions
mcp-fetch-server taxonomy bootstrap # propose categories, then edit the file
mcp-fetch-server classify # file documents under them
mcp-fetch-server embed # build the search index
mcp-fetch-server search "your question" # or --answer for a written answer
mcp-fetch-server watch ./my-documents # keep the corpus in step with a folder
./scripts/install-watch-unit.sh # ...or run that as a systemd unit (WSL)mcp-fetch-server doctor checks the whole stack before you start, and
mcp-fetch-server eval --from-corpus measures retrieval quality so accuracy
changes can be verified rather than assumed. Qdrant runs embedded on local
disk when FETCH_QDRANT_URL is empty, so no Docker is needed.
See docs/RAG_PLAN.md for the full picture.
Other MCP capabilities
Resources:
config://settings,history://recent,fetch-cache://{encoded_url}Prompts:
fetch,research_topic,summarize_page,extract_key_facts,compare_sourcesCompletions: URL/depth autocomplete for prompt and resource arguments
Elicitation:
write_fileconfirms before overwriting an existing fileRoots: local file tools honor client-exposed directories in addition to
FETCH_LOCAL_FILES_ROOTProgress notifications:
batch_fetchandsummarize_urlreport progress as they runManagement GUI: web dashboard at
/adminfor status, config, history, cache, and tools
Security
SSRF protection with resolve-then-check and redirect re-validation
robots.txtcompliance (override withignore_robots_txt=true)Optional domain allowlist
Local file tools sandboxed to one configured directory, path-traversal safe
Bearer token auth + rate limiting for HTTP mode
/healthendpointWindows
.exebuild (no Python required for end users)
Related MCP server: myscrape
Quick Start
One-command install (any platform)
# Linux / macOS / WSL
curl -fsSL https://raw.githubusercontent.com/narimanamiri/mcp-fetch-server/master/scripts/install.sh -o install.sh
bash install.sh --yes# Windows
irm https://raw.githubusercontent.com/narimanamiri/mcp-fetch-server/master/scripts/install.ps1 -OutFile install.ps1
powershell -ExecutionPolicy Bypass -File install.ps1 -YesClones the project if it is not already present, installs uv and the
dependencies, writes a .env with a freshly generated MCP_AUTH_TOKEN,
checks Ollama and pulls the models, brings up Qdrant (or picks embedded mode
when Docker is absent), and runs doctor to verify. Re-running never
overwrites an existing .env.
Useful flags (--help for all): --mode offline, --qdrant embedded,
--no-models, --rerank, --corpus PATH, --watch.
Option A: Docker — full stack (recommended for server deployment)
Runs the MCP server, admin GUI, and SearXNG together.
Linux / macOS:
cd mcp-fetch-server
cp .env.docker.example .env # edit MCP_AUTH_TOKEN
chmod +x scripts/docker-up.sh
./scripts/docker-up.sh
# or: docker compose up -d --buildWindows (PowerShell):
cd "E:\my python projects\MCP\mcp-fetch-server"
copy .env.docker.example .env
.\scripts\docker-up.ps1Service | URL |
MCP protocol |
|
Admin GUI |
|
Health |
|
SearXNG (search fallback) |
|
Connect Cursor over HTTP (Bearer token required):
{
"mcpServers": {
"web-fetch": {
"url": "http://127.0.0.1:8000/mcp",
"headers": { "Authorization": "Bearer your-token-from-env" }
}
}
}Local files for read_file/write_file map to the ./workspace folder on your host.
Option B: Windows executable (local / Cursor stdio)
cd "E:\my python projects\MCP\mcp-fetch-server"
.\dist\mcp-fetch-server.exe --transport stdioBuild the exe yourself: .\scripts\build_exe.ps1 → outputs dist\mcp-fetch-server.exe
Option C: Python + uv (development)
cd "E:\my python projects\MCP\mcp-fetch-server"
uv sync --dev
copy .env.example .env
uv run mcp-fetch-server --transport stdioConnect to Cursor
See the User Manual — Connect to Cursor for step-by-step instructions.
Minimal .cursor/mcp.json using the executable:
{
"mcpServers": {
"web-fetch": {
"command": "E:/my python projects/MCP/mcp-fetch-server/dist/mcp-fetch-server.exe",
"args": ["--transport", "stdio"],
"env": { "PYTHONIOENCODING": "utf-8" }
}
}
}Management GUI
A built-in web dashboard lets you monitor and manage the server without using Cursor:
Mode | URL |
stdio (Cursor default) |
|
streamable-http |
|
The dashboard shows uptime, registered tools, redacted configuration, recent fetch history, cached page previews, and a button to clear history/cache. It auto-refreshes every 30 seconds.
If MCP_AUTH_TOKEN is set, enter it in the dashboard's auth bar (stored in your
browser session only). Disable the GUI with FETCH_ADMIN_ENABLED=false.
Optional: SearXNG search fallback
web_search uses DuckDuckGo by default and falls back to SearXNG when that scrape fails.
When you use Docker (docker compose up), SearXNG is started automatically and the MCP
container is preconfigured to reach it at http://searxng:8080.
For local (non-Docker) use, you can still run only SearXNG:
docker compose up -d searxngSet FETCH_SEARXNG_URL=http://localhost:8080 in .env. See searxng/settings.yml.
Remote HTTP Mode (without full Docker stack)
$env:MCP_AUTH_TOKEN = "your-long-random-token"
.\dist\mcp-fetch-server.exe --transport streamable-http --host 127.0.0.1 --port 8000MCP endpoint:
http://127.0.0.1:8000/mcpHealth check:
http://127.0.0.1:8000/health
Project Structure
mcp-fetch-server/
├── dist/mcp-fetch-server.exe # Windows executable
├── src/mcp_fetch_server/ # Source code (tools, resources, prompts, security, ...)
├── tests/ # 84 pytest tests
├── docs/ # User manual + technical docs
├── scripts/docker-up.sh # Linux/macOS stack startup
├── scripts/docker-up.ps1 # Windows stack startup
├── docker-compose.yml # Full stack: MCP server + SearXNG
├── .env.docker.example # Environment template for Docker Compose
├── Dockerfile # MCP server image
├── workspace/ # Host folder mounted for local file tools (Docker)
├── searxng/settings.yml # SearXNG config (JSON API enabled)
├── src/mcp_fetch_server/admin.py # Management web GUI
└── .cursor/mcp.json # Cursor configDevelopment
uv run pytest
uv run ruff check .
./scripts/docker-up.sh # Linux / macOS
docker compose downWindows only:
.\scripts\build_exe.ps1
.\scripts\docker-up.ps1License
MIT
Available Tools
9 toolsbatch_fetchARead-only
Fetch up to 10 public URLs concurrently and return each page's content (or error) in one response.
Inputs: urls (required), max_length, ignore_robots_txt. Returns: result
extract_linksBRead-only
Fetch a URL and extract all links and images from the page as a list.
Inputs: url (required), max_links. Returns: result
fetch_metadata_toolARead-only
Return HTTP metadata for a URL using a HEAD request.
Inputs: url (required). Returns: result
fetch_urlARead-only
Fetch a public HTTP/HTTPS URL and return page content as markdown. Use start_index to read long pages in chunks.
Inputs: url (required), raw, max_length, start_index, +1 more. Returns: result
list_dirARead-only
List the contents of a directory within an allowed local directory. Leave path empty to list the root itself.
Inputs: path. Returns: result
read_fileARead-only
Read a text file from an allowed local directory (configured via FETCH_LOCAL_FILES_ROOT, plus any directories the client exposes as roots). Path is relative to the allowed directory.
Inputs: path (required). Returns: result
summarize_urlA
Fetch a URL and ask the connected client's LLM (via MCP sampling) to summarize it. Requires a client that supports the sampling capability; otherwise use fetch_url and summarize the content yourself.
Inputs: url (required), focus, max_length. Returns: result
web_searchARead-only
Search the web via DuckDuckGo (no API key required) and return titles, URLs, and snippets for the top matches. Automatically falls back to a local SearXNG instance (FETCH_SEARXNG_URL) if DuckDuckGo's scrape fails.
Inputs: query (required), max_results. Returns: result
write_fileADestructiveIdempotent
Write text content to a file within an allowed local directory. If the file already exists and overwrite=false, the user will be asked to confirm before it is replaced.
Inputs: path (required), content (required), overwrite. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Each tool has a distinct purpose: fetching URLs (single, batch, metadata, links, search, summarize) and local file operations (list, read, write). No overlap between tools.
Most tools follow a verb_noun pattern in snake_case. The one minor inconsistency is 'fetch_metadata_tool' which includes an unnecessary 'tool' suffix, but otherwise naming is consistent.
9 tools is appropriate for a web fetch server that also includes local file capabilities. Not too many, not too few.
Web fetching covers single, batch, metadata, links, search, and summarize. Local file ops cover list, read, write but lack a delete tool. Minor gap.
Maintenance
Related MCP Connectors
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.
Docs: https://docs.keenable.ai/mcp-server Keenable is a free, remote MCP server that gives agents access to the web index. Search the web with ranked results and date/site filters, then fetch any indexed page as clean markdown. Works out of the box with no account or API key.
Turn any public website into an MCP server for agents to search, read and navigate.
Related MCP Servers
- FlicenseAqualityDmaintenanceAn MCP server providing tools for web research, code review, and concept explanation, callable by any MCP-compatible client.3-
- AlicenseNot gradedqualityCmaintenanceA self-contained web-research MCP server that lets local LLM agents search, fetch, and synthesize web content using tools like web_search, web_fetch, and web_research.2MIT
- AlicenseAqualityDmaintenanceAn MCP server that fetches web pages and extracts clean, AI-usable context from them, enabling tools for link discovery, content search, and integrated fetch-and-search operations.517 npm1MIT
- AlicenseAqualityDmaintenanceThis MCP server enables free web search and page content extraction using real browsers, with support for multiple search engines and stealth browser backends. It provides tools for searching, fetching pages, and setting up the Camoufox stealth browser.3MIT