WHSearch
AI-native research search engine built as a lightweight modular monolith.
Current phase
All phases implemented: foundation, multi-provider web discovery
(DuckDuckGo + Wikipedia fan-out), robots-gated reader, passage retrieval,
adaptive research planning with stopping conditions, claim-level evidence
with source-independence and contradiction checks, MCP search agent
(search, read_page, search_and_read, research), bounded
SQLite/FTS5 local index, and explicit research budgets.
Design rules
- Evidence first: retrieve sources and passages before generating research conclusions.
- Online first: use external discovery initially; keep persistent storage bounded.
- Respect robots.txt, access policies, and conservative per-domain rate limits.
- Domain models and protocols must not depend on HTTP clients, providers, MCP, or extractors.
- MCP is an adapter layer; research/search logic stays in application modules.
- Optional integrations must not be required for importing the core domain.
- Resource limits are explicit so the system remains usable on low-memory machines.
Planned phases
Foundation: contracts, configuration, logging, testing, architecture checks.Done.Web discovery: provider abstraction and DuckDuckGo discovery.Done (+Wikipedia).Web reader: robots policy, fetching, extraction, metadata, passages.Done.Retrieval: passage ranking and deduplication.Done.Research: adaptive query planning and stopping conditions.Done.Evidence: claims, source independence, contradictions, verification.Done.Search agent: orchestration through the MCP tools.Done.Local index: SQLite/FTS5 bounded cache and reusable evidence.Done.Autonomous research budgets and larger-scale discovery.Done (budgets + fan-out).
Development
Use the repository virtual environment when available:
.venv/bin/python -m pytest
.venv/bin/python -m compileall -q src tests
.venv/bin/ruff check src tests
The quality gate must pass before moving to the next phase.
Install as an MCP server
Requires Python >= 3.12. After the whsearch package is published to PyPI,
no manual install is needed — uvx fetches and runs it on first use:
{
"mcpServers": {
"whsearch": { "command": "uvx", "args": ["--from", "whsearch[mcp]", "whsearch"] }
}
}
Alternatives:
uv tool install "whsearch[mcp]" && whsearch # persistent install via uv
pipx install "whsearch[mcp]" && whsearch # persistent install via pipx
pip install -e ".[mcp]" && whsearch # from source
WHSEARCH_INDEX_PATH enables the persistent local index.
Optional headless-browser fallback (L3)
Pages that render only via JavaScript (JS-shell SPAs) defeat static
extraction. When the js extra is installed, the reader tries headless
Chromium only for pages where static extraction yields almost nothing:
pip install -e ".[mcp,js]" && .venv/bin/playwright install chromium
Behavior and limits (all free, no keys):
- L1 trafilatura → L2 embedded JSON/meta → L3 headless, first hit wins.
- L3 triggers only below 200 extracted chars; rendered text must also clear it.
- At most 2 concurrent renders, 15s each, images/fonts/media blocked.
- Missing playwright (or any render failure) degrades silently to static text.
WHSEARCH_BROWSER=0disables it;WHSEARCH_BROWSER_TIMEOUTtunes seconds.whsearch://statsreportsreader.browser_installed/enabled/timeout.
License
GPL-3.0-or-later, see LICENSE. Copyright (C) 2026 WHSearch contributors.
Per-file copyright holder names were intentionally left generic; update them
to your name before publishing if you are the sole author.
Release files for whsearch 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| whsearch-0.2.0.tar.gz | 51.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| whsearch-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 115.6 kB
Release files / whsearch-0.2.0.tar.gz
| Download URL | whsearch-0.2.0.tar.gz |
|---|---|
| Size | 51.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a75b6d6df7eb4750d51e922da8ff3002ca5fa8dab56e8e1ac9bd5af7e0a564f8
|
|
BLAKE2b-256 checksum How to use checksums |
78e3515023f1f830be3ee91543c74a77522de10e59c01b5d9dd109f00b6ed11b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / whsearch-0.2.0-py3-none-any.whl
| Download URL | whsearch-0.2.0-py3-none-any.whl |
|---|---|
| Size | 63.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0607bd6545c8069e556a17f1b37e40df2c43f8633147ad3dd43ca5cf6de02932
|
|
BLAKE2b-256 checksum How to use checksums |
b2f715001f13003e1179326816c381e88ac23bb7a721036de4d1417253b040ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|