MCP Web Engine
This MCP server gives clients web search plus public-page fetching and Markdown extraction through an operator-controlled SearXNG backend.
Use
web_searchto run aggregate multi-engine searches and return structured results, with a query and optional result limit.Use
fetch_urlto fetch raw text from public HTTP(S) pages after SSRF/public-address checks, with an optional byte limit.Use
extract_markdownto scrape public HTML pages and convert them into clean Markdown for LLM analysis, with the same URL and byte-limit controls.It is not a browser automation service: authenticated pages and JavaScript rendering are outside scope.
Provides a web_search tool that queries an operator-configured SearXNG instance with JSON search enabled, returning search results for research and source inspection.
MCP Web Engine
Give your MCP client web search, public-page fetching and Markdown extraction through a self-hostable server. For developers using Claude Desktop, Cursor, VS Code or their own MCP agents who want an operator-controlled SearXNG backend. Current release: 1.2.2.
Use it to research a question and inspect its sources, fetch public documentation while coding, or turn a public article into Markdown for further analysis. It is not a browser automation service: authenticated pages and JavaScript rendering are outside its scope.
Contents
Related MCP server: scrapesearch-mcp
Tools
Tool | Arguments | Purpose | Example arguments |
|
| Search through configured SearXNG |
|
|
| Fetch a public HTTP(S) page |
|
|
| Convert fetched HTML to Markdown |
|
Use tools/list for authoritative schemas and bounds.
Recorded demo (30–60 seconds)

This 35-second replay of real tool execution is paced for readability: not a Claude/Cursor UI recording and not a performance benchmark. It shows initialization, tool listing, a live search, public-page fetch and Markdown extraction using public release 1.2.1 over stdio. Replay duration is not execution time. See the runnable demo, captured JSON exchange and replay renderer. Recording requires a reachable SearXNG backend for search.
Use cases
Research with sources: search a topic, inspect result URLs and fetch the pages before summarizing.
Coding with public documentation: give an agent current documentation text without requiring a browser session.
Prepare Markdown for analysis: extract readable content from static public HTML for a downstream workflow; review source material before relying on it.
Architecture

web_search sends queries to the operator-configured SearXNG backend, which may
use a private address. SearXNG and its upstream engines receive those queries.
fetch_url and extract_markdown use the public-fetch path: canonical URL
validation, public-address checks, validated-address connection pinning and
redirect revalidation. These paths have separate trust boundaries.
Local stdio clients initialize before using tools. HTTP includes an initialize-based compatibility route and a project-specific stateless route; see HTTP for transport limitations. The diagram shows outbound request paths, not a guarantee of complete MCP transport compliance or network isolation.
Prerequisites
Python >=3.11 for the server.
For npm: Node >=18 (prefer a maintained release) and uv on PATH. npm installs a launcher, not Python or SearXNG; uv can provision Python.
A reachable, operator-controlled SearXNG instance with JSON search enabled for
web_search. The examples usehttp://127.0.0.1:8082/search; change this to your backend. SearXNG is not bundled. Initialization, tool listing and public-page fetch/extraction do not require SearXNG.An MCP-capable client with local stdio support. Approve tools according to your client's trust controls.
Installation resolves Python dependencies and may access package indexes. uv isolates dependencies; it is not a security sandbox. Search queries go to SearXNG and its upstream engines; see security and privacy.
npm quick start
Use this when you want an MCP server without cloning the repository. Requirements: Node >=18 (prefer a maintained Node release), uv on PATH, Python >=3.11 (uv can provision it), and a reachable SearXNG instance with JSON search enabled. npm installs the launcher; it does not bundle Python or SearXNG. Install uv from its official instructions.
Launch the pinned npm release (it waits for a stdio client):
npx --yes mcp-web-engine@1.2.2For actual agent use, paste this into your MCP client's server configuration and replace the SearXNG URL with yours:
{
"mcpServers": {
"mcp-web-engine": {
"command": "npx",
"args": ["--yes", "mcp-web-engine@1.2.2"],
"env": {
"SEARXNG_URL": "http://127.0.0.1:8082/search",
"ALLOW_DDG_FALLBACK": "false"
}
}
}
}Ready-to-copy files: Linux/macOS and Windows. On Windows the example uses cmd /c npx for the npm command shim. The stdio server waits for a client: silence after manually running npx --yes mcp-web-engine@1.2.2 is normal, not a chat prompt. Initialization lists three tools; a working search backend is needed only when you search. First launch may access package indexes.
If setup fails: check node --version and uv --version in the environment used by the client. Desktop clients may not inherit your interactive shell's PATH; supply the absolute executable path if needed. If tools appear but search fails, verify SearXNG's /search?q=test&format=json endpoint returns JSON, not an HTML page or a disabled-JSON error. Local stdio does not need an HTTP API key.
Connect your client
Claude Desktop
Open Settings → Developer → Edit Config to locate
claude_desktop_config.json.Merge the
mcpServersentry above into that file (do not overwrite existing servers). Use the Windows configuration on Windows or Linux/macOS configuration elsewhere.Save, fully restart Claude Desktop and check the available tools. Ask it to search a topic with
web_search, then fetch a public result withfetch_urlorextract_markdown; approve calls when prompted.
See the official local-server guide.
Cursor
Create
.cursor/mcp.jsonin your project, or use~/.cursor/mcp.jsonfor your user-wide setup.Merge the same
mcpServersconfiguration above, choosing the Windows example where appropriate.Open Cursor's MCP settings, enable/reload the server, and check its tool list. In Agent, request a search and approve tool execution if prompted.
See Cursor's official MCP documentation.
VS Code
Copy examples/vscode-mcp.json to your workspace's
.vscode/mcp.json; on Windows use examples/vscode-mcp.windows.json.Set your SearXNG URL. VS Code uses a top-level
servers, notmcpServers, and each entry explicitly sets"type": "stdio". Do not paste the Claude/Cursor JSON unchanged.Use MCP: List Servers in the Command Palette to start the server, review the trust prompt, then enable its tools in agent chat. Request a search and inspect the tool result.
See VS Code's official MCP documentation. Client versions and organization policies can change available controls.
Verification scope: installed npm stdio command shims were tested on Windows/macOS/Linux with Node 18/22. Configuration examples are schema checked; no full end-to-end GUI sessions in Claude Desktop, Cursor or VS Code were tested. A successful stdio smoke test is not proof of a graphical client's integration.
PyPI installation (without npm)
Use an isolated virtual environment rather than installing into an externally managed system Python (PEP 668):
python -m venv .venv
# Linux/macOS:
. .venv/bin/activate
# Windows PowerShell instead: .venv\Scripts\Activate.ps1
python -m pip install "mcp-web-engine==1.2.2"
mcp-web-engine --versionIn your client configuration, replace command with the absolute path to .venv/bin/mcp-web-engine (Windows: .venv\Scripts\mcp-web-engine.exe) and use "args": []; keep the backend environment settings. Escape Windows backslashes as \\ inside JSON. This route needs Python and pip, not Node or uv. The same SearXNG requirements apply. Alternatively, with uv installed: uvx --from mcp-web-engine==1.2.2 mcp-web-engine.
Local stdio
git clone https://github.com/Arbolencio/mcp-web-engine.git
cd mcp-web-engine
uv run --locked mcp-web-engineCLI accepts --stdio (default), --serve, or its --sse alias as mutually exclusive transport choices. Use mcp-web-engine --help for usage and mcp-web-engine --version for the installed version; unknown flags are rejected.
Default transport is newline-delimited JSON-RPC over stdin/stdout. Diagnostics and installer output belong on stderr. Clients should initialize, send notifications/initialized, then use ping, tools/list, and tools/call. No search service is required for initialization or listing tools.
Client configuration (replace the absolute checkout path):
{
"mcpServers": {
"mcp-web-engine": {
"command": "uv",
"args": ["tool", "run", "--from", "/absolute/path/mcp-web-engine", "mcp-web-engine"],
"env": {"SEARXNG_URL": "http://127.0.0.1:8082/search", "ALLOW_DDG_FALLBACK": "false"}
}
}
}For a pinned public installation use uvx --from mcp-web-engine==1.2.2 mcp-web-engine or npx --yes mcp-web-engine@1.2.2. These pin the project version, not its transitive dependencies. The clone above follows the repository default branch, not a release pin; use a reviewed commit and uv sync --locked for source deployments.
The npm tarball includes the canonical Python src package and build metadata. npx --package /absolute/path/mcp-web-engine-1.2.2.tgz mcp-web-engine delegates to uv; Python/uv remain prerequisites, and first launch may need network access for dependencies.
HTTP
export API_KEY="$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')"
export SEARXNG_URL=http://127.0.0.1:8082/search
uv run mcp-web-engine --serveHTTP defaults to 127.0.0.1:5050; API_KEY must contain at least 32 non-whitespace characters. Send Authorization: Bearer <YOUR_API_KEY> to protected endpoints. Keep the key out of source control and URLs. /health is a liveness endpoint, not a SearXNG connectivity check.
POST /v1/mcp/legacy provides the initialize-based compatibility path. /v1/mcp is a project-specific stateless extension requiring Mcp-Method (and Mcp-Name for tool calls). Its 2026-07-28 label is an internal extension identifier, not a claim of official MCP conformance. SSE support is limited; this is not a complete implementation of every MCP transport or optional feature.
Configuration
Process environment is authoritative. CWD .env files are not loaded automatically. To explicitly load one, set MCP_WEB_ENGINE_ENV_FILE to an existing absolute file path; process variables override file values.
Variable | Default | Meaning |
|
| Trusted operator-controlled search backend; search needs it running |
|
| Opt in to sending queries to DuckDuckGo if SearXNG fails |
| empty | Operator-generated HTTP bearer key; mandatory for CLI HTTP mode |
|
| HTTP bind address and port |
|
| Per-key HTTP admission limit, persisted in local SQLite |
|
| Outbound timeout, up to 120 seconds |
|
| Payload ceiling, up to 16 MiB |
|
| Process-local ceiling on in-flight HTTP requests; not a multi-worker global limit |
|
| Absolute HTTP request-body read deadline in seconds, not a timeout reset by each chunk |
|
| Local SQLite admission quotas and per-key tool telemetry; share one local file across workers |
| Same state directory, | Operator-managed credentials, separate from telemetry; use an absolute path |
|
| Logging and environment settings |
Docker
Need SearXNG too? Use the local stack guide and
compose.local.yml to start both services with JSON search already enabled,
loopback-only host ports and a live verification command. The existing setup
below connects to a search backend you already run.
# With API_KEY already exported as above:
docker compose up --build -dThe image installs the Python package, runs as a non-root user and explicitly starts mcp-web-engine --serve on port 5050. Compose publishes only host loopback. Container HOST=0.0.0.0 is necessary for that port mapping; do not confuse it with the host binding. Set SEARXNG_URL to a reachable backend: compose defaults to http://host.docker.internal:8082/search, using the host gateway. An instance bound only to host loopback may not be reachable from Docker. No SearXNG instance or credentials are bundled. See operations and limitations.
Troubleshooting
Symptom | What to check |
The stdio command starts but prints nothing | It is waiting for an MCP client to send JSON-RPC messages. Connect it through your client's server configuration. |
The client reports | Check the executable in the client's environment. GUI clients may have a different |
Tools appear, but search returns | Check that your SearXNG |
A container cannot reach SearXNG | Container loopback refers to that container. Use a reachable host gateway or a shared Docker network; the host service must listen on an address reachable from that network. |
The local stack cannot bind a host port | Set |
HTTP startup rejects the API key, or a protected request returns 401 |
|
Changes to a working-directory | Set |
| Health checks report liveness. Use the local stack live probe to check actual search, fetching and extraction. |
A public-fetch tool rejects a local or private URL | This is expected SSRF policy. The trusted SearXNG backend is a separate path; its private address does not permit tools to fetch arbitrary private URLs. |
For client JSON examples, see client setup. For state permissions, persistence and deployment boundaries, see operations.
Security controls and limitations
Public fetches validate schemes, resolved addresses and redirects, rejecting loopback/private/reserved destinations. Bounded payloads, timeouts and tool argument validation reduce resource exposure. These are defense-in-depth controls, not a guarantee against all SSRF, DNS, routing, proxy or upstream failures; enforce outbound network policy independently.
SearXNG is an intentional trusted-backend exception to public-fetch restrictions and can use a private address. Its operator and upstream engines receive queries; self-hosting does not keep searches entirely on-host. DuckDuckGo fallback is off by default, but ordinary SearXNG searches still involve upstream services. Fetched pages are untrusted input and may contain prompt injection. Dependency isolation does not isolate filesystem/network access. HTTP authentication is not TLS or a multi-host distributed rate limiter; use a restricted network and a TLS reverse proxy when needed. Do not expose the service directly to the Internet.
HTTP mode persists admission counters and tool telemetry keyed by hashed key IDs in local SQLite; operator-managed JSON credentials are stored separately. Self-hosting is not a promise of no logging or no disk writes: review logging, state paths, retention and filesystem permissions before handling sensitive workloads. See operations and limitations.
Development and artifact verification
uv sync --locked --extra test
uv run --locked python -m pytest -q
uv run --with build python -m build
npm pack
python3 tests/artifact_smoke.py -- uv tool run --from /absolute/path/to/package.whl mcp-web-engineTests are offline by default. The artifact smoke sends no search query: initialize, silent notification, ping, tool listing, and a rejected loopback fetch. CI tests Python 3.11–3.13 and builds/installs wheel and npm artifacts outside the checkout. Package dependency installation still requires package-index access unless cached.
Contributing and security reports
Read CONTRIBUTING.md for the development workflow, test requirements and distribution checks. Follow SECURITY.md to report a suspected vulnerability.
For release notes, see the changelog. Maintainers can follow the release guide.
License
MIT License. See LICENSE.
Available Tools
3 toolsextract_markdownB
Scrapes a web page and converts HTML into clean, structured Markdown for LLMs.
Inputs: url (required), max_bytes.
fetch_urlB
Fetches raw text content of a web page after SSRF security checks.
Inputs: url (required), max_bytes.
web_searchB
Performs aggregate multi-engine web search returning structured search results.
Inputs: query (required), limit.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 3 tools
web_search is clearly distinct, but fetch_url and extract_markdown both retrieve page content and could be confused when an agent wants Markdown versus raw text. The descriptions help differentiate, but the boundary is not as sharp as ideal.
All names use snake_case consistently. However, web_search uses a noun-first pattern while fetch_url and extract_markdown follow verb_noun, creating a minor inconsistency.
Three tools is a tight, well-scoped set for a web engine, covering search, raw fetch, and Markdown extraction without redundancy or bloat.
The core lifecycle (search, fetch, extract) is covered. Minor gaps like batch fetching or metadata extraction exist but are not essential for the stated purpose.
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.
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceA self-hosted MCP server providing private web search, web page fetching, and current date/time tools, powered by a bundled SearXNG instance for API-key-free local search.2-
- AlicenseNot gradedqualityDmaintenanceMCP server that provides web search scraping from DuckDuckGo (with Mojeek fallback) and URL content fetching as markdown/text or raw HTML.1ISC
- 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
- AlicenseAqualityCmaintenanceMCP server that exposes SearXNG search and HTTP fetch tools for AI agents, enabling web search and clean page text extraction via natural language.4MIT