Skip to main content

webresearcher-mcp-server

A light, standalone web-research MCP server: DuckDuckGo search, headless Camoufox page scraping (a hardened open-source Firefox), and same-domain crawling — zero Firecrawl, no API keys, no per-client browser download (in Docker mode).

It exposes four LLM-facing tools over MCP; the host LLM does the synthesis:

Tool What it does
web_search(query, limit=5) DuckDuckGo via ddgs (browser-grade TLS). Numbered results: title, URL, snippet.
web_scrape(url, max_chars=20000) Camoufox — a hardened open-source Firefox. Renders JavaScript and gets past cookie-consent banners (Yahoo/OneTrust/Cookiebot) that a bare HTTP fetch skips; degrades to a "rely on search" note when a page is protected or unreachable. max_chars=0 = full text.
web_crawl(url, limit=10) Starts a background same-domain BFS crawl (one browser, wall-detected per page). Returns a crawl id immediately — never blocks.
web_crawl_status(crawl_id, max_chars=20000) Crawl progress; on completion, per-page URLs + content (0 = full text).

Failures are graceful by design: a blocked page or outage returns a short SCRAPE UNAVAILABLE / SEARCH UNAVAILABLE note (never an exception), and the note tells the LLM not to retry the same URL/query.

Why not just WebFetch / WebSearch?

This is not a replacement for your IDE's built-in fetch/search — it is the tool for JS-rendered, consent-gated, and multi-page research:

  • web_scrape reads pages a bare HTTP fetch can't. It runs a real browser (Camoufox), so JavaScript renders and cookie-consent overlays are handled — where the built-in fetch returns an empty shell, this returns the content. When a page is protected or unreachable it degrades to a clear "rely on search" note instead of failing.
  • web_crawl has no built-in equivalent (multi-page BFS + per-page blocked-page detection).
  • web_search is free and independent of the harness's search availability; built-in search has the better generic index — use both.
  • Plain public static pages: the built-in fetch is fine, no need to route everything through this server.

A typical session: web_search("BOX stock news")web_scrape the 2–4 best results → optional web_crawl of the newsroom → synthesize with citations.

Quick start (uvx — no Docker)

Run it straight from PyPI. uvx auto-installs the package (and its mcp extra) into an isolated env and runs the stdio server as an ordinary child process — no Docker, no install step, and it's cleaned up when your session ends:

uvx "webresearcher-mcp-server[mcp]" --help    # sanity check
uvx "webresearcher-mcp-server[mcp]"          # stdio server (default transport)

The Camoufox browser (used by web_scrape/web_crawl) is downloaded on first use (~5 min one-time) or pre-fetched with python -m camoufox fetch.

Shared HTTP server (optional — one detached process shared by every IDE/session so pacing + cache are global; the only Docker path we still use):

docker build -t webresearch-mcp .     # or: docker compose up -d
docker run -d --name webresearch-mcp -p 8001:8001 webresearch-mcp \
  --transport streamable-http --host 0.0.0.0 --port 8001

(healthcheck: curl -fs -X POST http://localhost:8001/mcp -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' → lists the four tools)

Integrating with Claude Code / Cursor

Claude Code

uvx (recommended — no Docker): add to your project .mcp.json (or claude mcp add). First use auto-installs the package into an isolated env (cached afterward); the server runs as an ordinary child process and is cleaned up when the session ends:

{ "mcpServers": {
    "webresearch": {
      "command": "uvx",
      "args": ["webresearcher-mcp-server[mcp]", "--transport", "stdio"]
    } } }

Avoid the docker run -i --rm per-session shape. It leaks orphaned containers: Claude Code closes the child's stdin pipe on exit, the container (owned by the Docker daemon) never receives a stop signal, so --rm never fires and stray containers pile up. Known issue: anthropics/claude-code#29058.

Docker-HTTP (one detached container shared by all sessions): run the shared container above, then:

{ "mcpServers": { "webresearch": { "type": "http",
                                    "url": "http://localhost:8001/mcp" } } }

Plain venv (no uv/uvx on the box): install the package in a venv, then:

{ "mcpServers": { "webresearch": {
      "command": "/path/to/.venv/bin/python",
      "args": ["-m", "webresearch_mcp"] } } }

Cursor

Same shapes in ~/.cursor/mcp.json (user) or .cursor/mcp.json (project). uvx (no Docker):

{ "mcpServers": { "webresearch": {
      "type": "stdio",
      "command": "uvx",
      "args": ["webresearcher-mcp-server[mcp]", "--transport", "stdio"] } } }

or the {"url": "http://localhost:8001/mcp"} form for the shared HTTP container. See docs/integration.md for the full walkthrough, including the optional cross-IDE plugin (plugin/): one directory, two manifests (Claude Code + Cursor), bundling the stdio server + an always-on research rule + a /research command + a web-researcher subagent — no Docker needed.

Plain Python (no uv/uvx)

python3 -m venv .venv && . .venv/bin/activate
pip install "webresearcher-mcp-server[mcp]"   # or: pip install -e ".[mcp]" from a clone
python -m camoufox fetch          # one-time browser download
webresearcher-mcp-server                   # stdio server
webresearcher-mcp-server --transport streamable-http --port 8001

Configuration (env vars)

Variable Default Effect
WEBRESEARCH_MIN_CALL_INTERVAL_S 10 Paces the start of search/scrape calls (polite rate-limiting).
WEBRESEARCH_SUCCESS_TTL_S 3600 Cache TTL for successful search/scrape results.
WEBRESEARCH_CACHE_SIZE 512 LRU cache size (failures cached 60 s regardless).
WEBRESEARCH_CRAWL_PAGE_DELAY_S 3 Inter-page delay inside crawls (kept small so multi-page crawls stay fast).
WEBRESEARCH_CONSENT_AUTOACCEPT true Auto-click cookie-consent "accept" banners (Yahoo guce, OneTrust, Cookiebot). Set false to never click.
TRADINGAGENTS_CAMOUFOX_HEADLESS true Headless browser (set false to watch it work).
TRADINGAGENTS_WEB_SCRAPE_TIMEOUT_S 120 Per-page load timeout (s).

Notes: crawl state is in-memory (a restart loses in-flight crawls); crawls hold the single browser, so standalone scrapes queue behind an active crawl.

Development

pip install -e ".[mcp,test,lint]"
ruff check .
pytest -m "unit or smoke"          # hermetic (CI runs exactly this)
pytest -m integration              # live network + Docker (auto-skip if missing)

Layered markers: unit (pure helpers, patched seams), smoke (real MCP protocol over stdio/HTTP against a hermetic fake upstream), integration (live web + real browser + Docker image).

Responsible use

This is a research/reading tool for publicly available content, intended for personal and internal use.

  • Respect each site's Terms of Service and robots.txt. If a page or site blocks you, stop — don't keep trying to get past it.
  • Don't use it to access paywalled or protected content, or to harvest content or personal data at scale.
  • You are responsible for how you use it: scraping may be restricted by the site you're reading and by the law in your jurisdiction.

License

Apache-2.0. Portions derived from TradingAgents (Apache-2.0) — see NOTICE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

webresearcher_mcp_server-0.1.1.tar.gz (39.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

webresearcher_mcp_server-0.1.1-py3-none-any.whl (28.2 kB view details)

Uploaded Python 3

File details

Details for the file webresearcher_mcp_server-0.1.1.tar.gz.

File metadata

  • Download URL: webresearcher_mcp_server-0.1.1.tar.gz
  • Upload date:
  • Size: 39.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for webresearcher_mcp_server-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e2fcf85254b760951a29078118a20ce69870eaadfd8d9609aca32bf5d15b6a9f
MD5 ce87196e6b6822e9f23f7846491bd1bf
BLAKE2b-256 843d61c7617b200b4db98475ee4f29a58e5e94d49d63bb18e7ccb0f088d2b7a1

See more details on using hashes here.

File details

Details for the file webresearcher_mcp_server-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: webresearcher_mcp_server-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 28.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for webresearcher_mcp_server-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f0fc962866664e9c6a2cd2075fe1dbae09b730534185b1c7b3cfa1aba8c199b2
MD5 277bebc1e82664e2a4d89d2ef09d5c02
BLAKE2b-256 9919aba758dacc37810e300ec6f8b87b35b09f643dcd3bb160e178b765ecf7ab

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page