Skip to main content
Glama
yeivily-mcp
by yeib

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 with POST /search, POST /extract, POST /search/context, GET|POST /html, GET /health.

  • yeivily-mcp (yeivily_mcp.py): MCP server over stdio with two tools, web_search and fetch_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:

  1. Tavily-shaped JSON contract (/search, /extract, /search/context) for tools/SDKs that speak Tavily rather than raw ddgs.

  2. 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).

  3. Resilient local caching & rate-limit protection: built-in TTL cache, single-flight deduplication for concurrent identical agent queries, concurrency limiting, and explicit 429 Retry-After handling instead of silently returning empty lists on upstream blocks.

  4. 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

pipx install yeivily
# or: pip install yeivily

yeivily                               # starts HTTP server on http://127.0.0.1:8000
yeivily-mcp                           # runs stdio MCP server directly

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

Related MCP server: DuckDuckGo Search MCP Server

Verified Compatibility & Footprint

  • Official tavily-python SDK: Verified end-to-end with tavily-python (v0.8.5) executing live TavilyClient(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) using yeivily-mcp over stdio (web_search and fetch_page tools).

  • Memory Footprint: Measured via process RSS WorkingSet on Python 3.12 (Windows 11 x64) with ddgs loaded under active search and HTTPS page extraction load:

    • ~44 MB RSS for yeivily HTTP daemon.

    • ~24 MB RSS for yeivily-mcp stdio worker.

    • (Compare to ~180-250 MB for FastAPI/Uvicorn-based search wrappers or 500 MB - 1.5 GB for Dockerized SearXNG).

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

  • score is derived from rank, not relevance. Do not threshold on it.

  • answer is null unless 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-After instead of pretending there were no results.

Security notes

  • Binds to loopback (127.0.0.1) by default; requests with an Origin header (browsers) or a foreign Host header (DNS rebinding) are rejected with 403.

  • 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, set YEIVILY_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.

Available Tools

2 tools
fetch_pageA
Read-onlyIdempotent

Download a single web page and return its readable text. Use it to read a URL found via web_search. Does not execute JavaScript and does not read PDFs.

Inputs: url (required), max_chars.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.2/5.0

    Scored across 2 tools

    Disambiguation5/5

    The two tools cover clearly disjoint steps of a retrieval workflow: web_search discovers URLs and fetch_page reads a known URL. Descriptions even cross-reference each other, making the intended pipeline unambiguous.

    Naming Consistency5/5

    Both names follow a consistent snake_case verb_noun pattern (web_search, fetch_page). The only nuance is that web_search puts the resource before the verb, but the two names still read as a coherent, predictable pair.

    Tool Count4/5

    Two tools is minimal but each earns its place in a search-then-read workflow, with no redundancy. It is slightly thin for a standalone server, since filters or pagination would otherwise be separate tools.

    Completeness4/5

    Search plus fetch covers the core web-retrieval lifecycle with no dead ends for the stated scope. Gaps exist but are documented (no PDF reading, no JavaScript, no date/region filters or result-count control), which agents can work around.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      D
      maintenance
      Provides local web search and content fetching capabilities for AI assistants, enabling them to search DuckDuckGo and extract clean text from web pages. All requests originate from the user's machine to ensure direct network control and bypass external proxies.
      2
      -
    • F
      license
      A
      quality
      C
      maintenance
      Enables keyless web search across multiple engines with fallback and relevance ranking, plus anonymous HTTP(S) page fetching, all without API keys or vendor dependencies.
      2
      1
      -
    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to perform local web searches through DuckDuckGo, with a shared TTL cache and user click history via an Exa-compatible API.
      5
      -