Yeivily
A tiny, keyless, Tavily-style search server and MCP provider for local LLM setups (Ollama, Goose, Aider, LangChain, ...).
Search comes from DuckDuckGo through ddgs; everything else is Python standard library.
yeivily(yeivily.py): local HTTP server withPOST /search,POST /extract,POST /search/context,GET|POST /html,GET /health.yeivily-mcp(yeivily_mcp.py): MCP server over stdio with two tools,web_searchandfetch_page. It talks to the HTTP daemon if it is running (sharing its TTL cache) and otherwise runs the same engine in-process.
No Docker, no SearXNG, no API key, no database.
Why Yeivily? (vs. ddgs api / ddgs mcp / SearXNG proxies)
ddgs itself ships ddgs api (FastAPI) and ddgs mcp, and several SearXNG-based projects expose Tavily-compatible APIs (Sifthound, Trawl, OrioSearch, ...). Yeivily's specific niche is combining all of the following in one tiny package:
- Tavily-shaped JSON contract (
/search,/extract,/search/context) for tools/SDKs that speak Tavily rather than rawddgs. - Zero-Docker, zero-FastAPI footprint: pure Python stdlib +
ddgs(~44 MB RAM for the HTTP daemon under load; ~24 MB RAM for the stdio MCP server). - Resilient local caching & rate-limit protection: built-in TTL cache, single-flight deduplication for concurrent identical agent queries, concurrency limiting, and explicit
429 Retry-Afterhandling instead of silently returning empty lists on upstream blocks. - Dual HTTP + MCP with automatic fallback: MCP clients work whether the background HTTP daemon is running or not.
Quick start
Install with pipx or pip (no clone needed)
pipx install git+https://github.com/yeib/yeivily.git
# or: pip install git+https://github.com/yeib/yeivily.git
yeivily # starts HTTP server on http://127.0.0.1:8000
Or run directly from source
pip install -r requirements.txt
python yeivily.py # http://127.0.0.1:8000
curl -s localhost:8000/search -H 'Content-Type: application/json' \
-d '{"query": "ollama latest release", "max_results": 3}'
Use it where Tavily is expected
Works in clients and SDKs that let you override the Tavily base URL (the official SDKs do):
from tavily import TavilyClient
client = TavilyClient(api_key="anything", api_base_url="http://127.0.0.1:8000")
print(client.search("rust async runtimes", max_results=5))
print(client.extract(urls=["https://example.org"]))
If a tool hardcodes https://api.tavily.com, Yeivily cannot help (there is no TLS and no DNS trickery here).
MCP Setup
Claude Desktop / Cursor / Generic mcpServers JSON
If installed via pipx / pip:
{
"mcpServers": {
"yeivily": {
"command": "yeivily-mcp"
}
}
}
Or pointing directly to the script (keep yeivily.py next to yeivily_mcp.py so the in-process fallback works):
{
"mcpServers": {
"yeivily": {
"command": "python",
"args": ["/path/to/yeivily_mcp.py"]
}
}
}
Block Goose (~/.config/goose/config.yaml or %APPDATA%\Block\goose\config\config.yaml)
extensions:
yeivily_search:
name: yeivily_search
type: stdio
cmd: yeivily-mcp
args: []
enabled: true
timeout: 30
Verified Compatibility & Footprint
- Official
tavily-pythonSDK: Verified end-to-end withtavily-python(v0.8.5) executing liveTavilyClient(api_key="...", api_base_url="http://127.0.0.1:8000")calls:client.search("Chile capital", max_results=2)-> returns valid structured results.client.extract(urls=["https://example.com"])-> returns clean extracted page text without SSL or contract errors.
- Goose CLI: Verified on Windows 11 & WSL2 (Ubuntu) with Goose CLI v1.58.0 and local Ollama (
gemma4:12b) usingyeivily-mcpover stdio (web_searchandfetch_pagetools). - Memory Footprint: Measured via process RSS WorkingSet on Python 3.12 (Windows 11 x64) with
ddgsloaded under active search and HTTPS page extraction load:- ~44 MB RSS for
yeivilyHTTP daemon. - ~24 MB RSS for
yeivily-mcpstdio worker. - (Compare to ~180-250 MB for FastAPI/Uvicorn-based search wrappers or 500 MB - 1.5 GB for Dockerized SearXNG).
- ~44 MB RSS for
Configuration (environment variables)
| Variable | Default | Meaning |
|---|---|---|
YEIVILY_HOST / YEIVILY_PORT |
127.0.0.1 / 8000 |
Bind address (port 8000 is popular: use --port if it clashes) |
YEIVILY_API_KEY |
unset | Require Authorization: Bearer <key> |
YEIVILY_REGION |
wt-wt |
ddgs region (es-es, cl-es, us-en, ...) |
YEIVILY_SAFESEARCH |
moderate |
on, moderate, off |
YEIVILY_CACHE_TTL / YEIVILY_CACHE_MAX |
600 / 256 |
Cache seconds / entries |
YEIVILY_DEEP_TOP_N |
3 |
Results enriched with page text when include_raw_content or search_depth=advanced |
YEIVILY_PROXY |
unset | HTTP or SOCKS5 proxy URL (--proxy, e.g. socks5://127.0.0.1:9050) |
YEIVILY_ALLOW_PRIVATE_FETCH |
off | Let /extract reach LAN/localhost addresses |
YEIVILY_FAKE_ANSWER |
off | Fill answer with concatenated snippets (not an LLM answer) |
YEIVILY_URL (MCP) |
http://127.0.0.1:8000 |
Where the MCP server finds the daemon |
Honest differences from Tavily
scoreis derived from rank, not relevance. Do not threshold on it.answerisnullunless you opt into the snippet-concatenation hack (--fake-answer).- No
/crawl,/map,/research; no images; no JavaScript rendering; no PDF extraction. - Search quality is whatever DuckDuckGo gives you. Upstream rate limits are real: Yeivily caches, de-duplicates concurrent identical queries, limits concurrency and answers
429+Retry-Afterinstead of pretending there were no results.
Security notes
- Binds to loopback (
127.0.0.1) by default; requests with anOriginheader (browsers) or a foreignHostheader (DNS rebinding) are rejected with403. - Page extraction refuses private/loopback/link-local addresses (also after HTTP redirects) to prevent SSRF unless you explicitly opt out via
YEIVILY_ALLOW_PRIVATE_FETCH=1. - If you bind to
0.0.0.0, setYEIVILY_API_KEY. - Scraping search engines can conflict with their terms of service. Intended for personal/local development use.
Tests & Benchmark
Unit Tests (Offline)
python -m unittest discover -v # 22 tests; no network and no ddgs required
Concurrency & Saturation Benchmark
python benchmark.py # 20 concurrent queries (single-flight dedupe + queue)
License & Disclaimer
MIT License. See LICENSE for details.
Disclaimer: Yeivily is an independent open-source project and is not affiliated with, sponsored by, or endorsed by Tavily.
Metadata
Release files for yeivily 1.0.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 | Provenance | Actions |
|---|---|---|---|---|
| yeivily-1.0.0.tar.gz | 20.3 kB | With provenance | Details for yeivily-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| yeivily-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for yeivily-1.0.0-py3-none-any.whl |
Total release size: 42.2 kB
Release files / yeivily-1.0.0.tar.gz
| Download URL | yeivily-1.0.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4efc07cfdf1e0959365cfb50b37b01c5aad5136d160ef6d6c2d0a0850f00ade
|
|
BLAKE2b-256 checksum How to use checksums |
64a02fe2436948654cec9ea703cdeed9dff71bb59190be094e73ca5ddce065c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.
Transparency logRelease files / yeivily-1.0.0-py3-none-any.whl
| Download URL | yeivily-1.0.0-py3-none-any.whl |
|---|---|
| Size | 21.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
85de2e52535b2b1af13c2d619ed88cff299568bafd1f17b9253fd0bc8b79e937
|
|
BLAKE2b-256 checksum How to use checksums |
0e9bf232d7f50184db57126b4248dbb06c6c440bf4ea8de6f6646174cee3f579
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.
Transparency logSecurity for yeivily 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for yeivily-1.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 10, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.