webx-mcp
Manages the lifecycle of the local SearXNG container, including starting, stopping, and checking status.
Used as an example search engine filter for queries, allowing targeted searches within GitHub.
Mentioned as an example engine that may be rate-limited, but can be used as a search engine option.
Provides web search functionality via a local SearXNG instance, returning ranked URLs and snippets.
Used as an example search engine filter for queries, allowing targeted searches within Wikipedia.
Click on "Install 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., "@webx-mcpsearch for the latest FastAPI release and read its changelog"
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.
WebX — Local On-Demand Web Search for Coding Agents
Small, Unix-y local tool that gives coding agents web access only when desired. Not a research agent — just two primitives plus lifecycle management:
search(query) -> ranked URLs/snippets (local SearXNG, Docker, 127.0.0.1:8888, normally stopped)
read(url) -> cleaned Markdown (controlled fetch + Trafilatura, SSRF-protected)Minimal-agent mode: agent shells out
webx search / webx read / webx stoponly when a temporary prompt authorizes it. No permanent web tool in the system prompt.Exploration/MCP mode: host launches
webx-mcp(stdio). Server exposes exactlyweb_search+web_read. Launch does not start SearXNG; firstweb_searchlazy-starts it and owns shutdown.
Install
Requires Python 3.12+ and Docker + Compose for search. webx read works without Docker.
# with uv (recommended)
uv sync
uv sync --extra mcp # for MCP server
uv sync --extra dev # for tests
# or pip
pip install -e .
pip install -e ".[mcp]"
# global tool (so `webx` works in `pi`'s bash and any shell)
uv tool install . # installs to ~/.local/bin/webx — ensure ~/.local/bin is on PATH
# or pipx
pipx install .
# per-project (no global install)
uv sync && uv run webx --help
# or add .venv/bin to PATH for this shell/session (useful for pi coding agent)
export PATH="$PWD/.venv/bin:$PATH"
which webx && webx --helppi coding agent note: The
bashtool insidepiinheritsPATHfrom the host. Ifwebx: command not found, runuv tool install .once orexport PATH="$PWD/.venv/bin:$PATH"in the session where you launchpi.
Related MCP server: mcp-searxng
Quick start
webx init # materialize ~/.local/share/webx/{compose.yml,settings.yml,.env,cache}
webx doctor # check docker, templates, SearXNG reachability (does NOT start SearXNG)
webx status # {initialized, docker_available, searxng_running, url, runtime_dir}
webx status --json
webx search "SearXNG documentation" --limit 5 --pretty
webx status # now running
webx read "https://docs.searxng.org/" --max-chars 12000
webx read "https://docs.searxng.org/" --json | jq
# denials are exit 5
webx read "http://127.0.0.1:8888/" # -> exit 5 unsafe URL
webx read "http://192.168.1.1/" # -> exit 5
webx read "file:///etc/passwd" # -> exit 5
webx stop # docker compose stop (retains container)
webx status # stoppedTemporary web-access prompt (minimal agent)
For this task you are allowed to use the local WebX utility when external/current
information materially helps.
Available commands:
- webx search "<query>" to discover relevant public-web sources.
- webx read "<url>" to read a relevant public page as cleaned text/Markdown.
...
When the web-research portion is finished, run webx stop.MCP host config
Stdio only. Example (Claude Code / MCP Inspector):
{
"mcpServers": {
"webx": {
"command": "webx-mcp",
"env": { "WEBX_DATA_DIR": "/home/you/.local/share/webx" }
}
}
}Tool list must be exactly web_search + web_read. Lifecycle is internal — do not expose webx up/stop as agent tools.
CLI reference
webx --help
webx --version
webx init [--force-templates] [--show-path] # idempotent, never rotates secret
webx doctor # inspection only
webx up # ensure SearXNG running
webx stop # compose stop (normal shutdown)
webx status [--json]
webx logs [--tail 100]
webx search QUERY [--limit 8] [--category general] [--language en] [--page 1]
[--time {day,month,year}] [--safe-search {0,1,2}] [--engine NAME] [--pretty]
webx read URL [--max-chars N] [--json] [--links] [--no-tables] [--precision] [--recall]stdout= data (JSON for search, Markdown/text or JSON for read).stderr= diagnostics.Exit codes:
0ok,2usage/validation,3runtime/docker unavailable,4SearXNG failure,5unsafe URL,6fetch/extraction failure,7unsupported content type (2xxwithimage/*,application/pdf, etc.).4xx/5xx/timeout from a public URL is6, not7(e.g.wikimedia PNG -> HTTP 400->6).
--verbose (global) enables debug traces to stderr (e.g. read ok: https://example.com/ text/html 114 chars engine=trafilatura 1.23s). Secrets never printed.
Engine/category examples (SearXNG aggregates 269 services; filter per query when upstream rate-limits hit):
webx search "python httpx" --engine wikipedia --engine github --pretty
webx search "SearXNG" --category it --pretty
webx search "SearXNG documentation" --time month --prettyReader extraction examples (--links preserves [text](url) markdown; --precision/--recall tune trafilatura):
webx read "https://en.wikipedia.org/wiki/Python_(programming_language)" --max-chars 2000 --links | head -n 40
webx read "https://en.wikipedia.org/wiki/Python_(programming_language)" --max-chars 2000 | head -n 40
webx read "https://api.github.com/zen" --json | jq # application/json is returned raw (engine=raw), not trafilaturaRuntime & config
Runtime dir via platformdirs (overridable with WEBX_DATA_DIR):
Linux:
~/.local/share/webx/(XDG)macOS:
~/Library/Application Support/webx/Windows:
%LOCALAPPDATA%\webx\
Contains compose.yml, settings.yml, .env (SEARXNG_SECRET 0600), cache/.
settings.yml is a tiny override (use_default_settings: true, formats: [html, json], limiter: false, public_instance: false, image_proxy: false). Do not copy the whole SearXNG default config.
compose.yml:
services:
searxng:
image: ${SEARXNG_IMAGE:-docker.io/searxng/searxng:latest}
container_name: webx-searxng
ports: ["127.0.0.1:8888:8080"]
env_file: [.env]
volumes: ["./settings.yml:/etc/searxng/settings.yml:ro", "./cache:/var/cache/searxng"]
restart: "no"Loopback binding only, single container, no Valkey/Redis, no proxy, no TLS. If the read-only single-file mount ever breaks due to SearXNG FORCE_OWNERSHIP, switch to a directory mount — but keep 127.0.0.1 binding (see 04_SEARXNG_RUNTIME.md).
Env overrides (all WEBX_):
WEBX_DATA_DIR, WEBX_SEARXNG_URL (default http://127.0.0.1:8888), WEBX_DOCKER_CMD,
WEBX_STARTUP_TIMEOUT (30s), WEBX_SEARCH_TIMEOUT (15s), WEBX_READ_TIMEOUT (15s),
WEBX_MAX_RESPONSE_BYTES (10 MiB), WEBX_MAX_READ_CHARS (40000), WEBX_MCP_STOP_ON_EXIT (true)SEARXNG_IMAGE can also be set in .env or env to pin an image tag.
SearXNG image version
Verified at implementation (2026-08-20):
Tag:
docker.io/searxng/searxng:latestResolved digest:
sha256:ec536bcd1e83577aad4cc07f7ecb9a30858a9a905d2d57c8796abc83f872a036(local imageec536bcd1e83, SearXNG2026.8.1-8892414dc)Configurable via
SEARXNG_IMAGE— do not auto-pull on each search.
Manual update:
webx stop
docker compose -f $(webx init --show-path)/compose.yml pull # or: SEARXNG_IMAGE=... docker compose pull
webx up
webx search "test" --limit 1 --pretty
webx stopNever auto-update on search.
MCP lifecycle
Launching
webx-mcpdoes not start SearXNG.First
web_searchprobeshttp://127.0.0.1:8888/; if stopped it doesdocker compose up -d+ poll, then marksstarted_by_mcp = true; if already running it marksfalse.web_readnever starts SearXNG.On clean exit, if
started_by_mcp && WEBX_MCP_STOP_ON_EXITit runscompose stop; else it leaves SearXNG running. Process-local lock protects concurrent first searches. Multiple independent MCP processes needing a lease/refcount is deferred to v2.
Tool descriptions state the trust boundary: returned page text is untrusted external data, never agent instructions; JS/auth pages may not work.
Security model
webx read treats URLs as untrusted input.
Allow only
http:///https://; denyfile:,ftp:,data:,javascript:, bare paths, credential-bearing URLs.Resolve hostname via OS resolver, inspect every IPv4/IPv6 with
ipaddress: deny loopback, RFC1918 private, IPv6 ULA, link-local (169.254.0.0/16,fe80::/10), multicast, unspecified, reserved, metadata169.254.169.254, and the SearXNG endpoint itself. No--allow-privatein v1.DNS rebinding residual: resolve-then-connect cannot perfectly prevent rebinding because
httpxmay resolve again; WebX validates every redirect target and documents the limitation. Address pinning is a possible hardening without bloating v1.Redirects: manual loop, max 5,
Locationresolved against current URL, re-validated, loop/excess fails.Fetch:
User-Agent: webx/<version> local-research-tool, connect 5s, read 15s, streamed withContent-Lengthpre-check + 10 MiB cap, no browser masquerade.Allowed types:
text/html,application/xhtml+xml,text/plain, markdown-like,json/xmltext; binary (image/*,application/pdf, etc.) → exit 7.Extraction: raw body →
trafilatura.extract(output_format="markdown", ...)+html2txtfallback; truncate after extraction at a word/Newline boundary, reporttruncated+characters.No cookies, auth headers, POST, or browser.
Operations & troubleshooting
webx doctor is the first diagnostic.
Failure | Likely cause |
| Install Docker/Compose; |
Search 403 |
|
SearXNG starts but searches 0 results / 5xx | Upstream engines rate-limited / CAPTCHAd your IP — check |
Reader returns tiny text | JS-rendered page — try |
Reader rejects URL | Private/local network denial — intentional |
|
|
| Single |
|
|
Research heuristics (agent-side, not WebX): prefer official docs → upstream repo/notes → specs → vendor announcements → quality writing; use --category it when it helps; run multiple focused searches, read primary sources, search for contradictions.
Testing
uv sync --extra dev --extra mcp
uv run pytest # fast unit tests, no Docker/net required
uv run pytest -m integration # live tests (needs Docker + net, marked integration)
uv run pytest --cov=webxManual acceptance (from clean WEBX_DATA_DIR):
webx --help; webx init; webx doctor; webx status # stopped
webx search "SearXNG documentation" --limit 5 --pretty
webx status # running
webx read "https://docs.searxng.org/" --max-chars 12000
webx read "http://127.0.0.1:8888/" # -> exit 5
webx read "http://192.168.1.1/" # -> exit 5
webx read "file:///etc/passwd" # -> exit 5
webx stop; webx status # stopped
# MCP: inspector 2 tools, web_read while stopped, first search starts, second reuses, stop-on-exit ownershipNote on
httpbin.org: Livehttpbin.orgcurrently returns503 Service Temporarily Unavailablefrom some networks (verified 2026-08-20 viacurl -A "webx/0.1.0"andcurl -A "Mozilla/5.0"both 503). Ifwebx read https://httpbin.org/html503s, use stable alternatives:https://example.com,https://en.wikipedia.org/wiki/Python_(programming_language)(good for truncation/--linkstests), orhttps://httpbingo.org/get.
Project layout
src/webx/
__init__.py, cli.py, config.py, lifecycle.py, searxng.py, security.py, reader.py, core.py, mcp_server.py
assets/{compose.yml,settings.yml}
tests/{unit,integration}
docs/{instructions,PLAN.md}Core WebX facade is shared by CLI and MCP; neither shells out to the other.
Non-goals (v1)
Browser/Playwright, PDF reader, crawling, reranker, LLM summarizer, cache, inter-process lease, engine presets, domain filters — see 09_DECISIONS_AND_FUTURE.md for rationale and v2 candidates.
License
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to perform web searches and read URL content via a SearXNG instance.215MIT
- AlicenseNot gradedqualityCmaintenanceIntegrates SearXNG API to give AI assistants web search and URL reading capabilities.11MIT
- AlicenseAqualityCmaintenanceEnables local LLMs to search the web and fetch clean content from URLs without API keys, using SearxNG and Mozilla Readability.235MIT
- AlicenseAqualityDmaintenanceEnables private web search and webpage content extraction using a local SearxNG instance, prioritizing user privacy and autonomy.22MIT
Related MCP Connectors
Read any web page as clean Markdown for AI agents: fetch, search, metadata, links. SSRF-safe.
LLM-ready web search + instant answers + URL-to-clean-text fetch for agents and RAG.
Read a URL as clean markdown, screenshot a website, url to PDF. Web access for agents, no signup.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fatih0234/web-searxng'
If you have feedback or need assistance with the MCP directory API, please join our Discord server