--- name: searxng_skills description: Search the live web via Jack's self-hosted SearXNG (https://searxng.erhe.top) using token-authenticated JSON output. Use when the agent needs current pricing/news/docs/product specs without invoking browser tools. --- # SearXNG Web Search (Jack's server) Search the live web through Jack's self-hosted SearXNG. 129 engines enabled (bing / duckduckgo / startpage / brave / mojeek / qwant / wikipedia 系 / etc.). Google main engine is OFF; google scholar/images/videos/news/cse sub-APIs are enabled. ## Endpoint - **URL**: `https://searxng.erhe.top` ⚠ `erhe.top`, **NOT** `ehre.top` - **Token**: `fGWEFWGrgasegtjt1jUJG` (passed as `?token=...` query param) - **Method**: GET works here. (Local docker 2026.7 default is `server.method=POST` — different; if porting code to a stock local SearXNG, flip to POST.) - **JSON 200**: This server has limiter/token auth configured, so `?format=json&token=...` returns 200. Stock local docker returns 403 unconditionally on JSON — different from this. ## Quick start CLI (preferred; auto-renders results): ```bash python3 ~/.hermes/skills/searxng_skills/searxng_search.py "" -m 5 -l en ``` Direct API (works fine from any script): ```python import urllib.request, urllib.parse, json url = "https://searxng.erhe.top/search?" + urllib.parse.urlencode({ "q": "", "format": "json", "token": "fGWEFWGrgasegtjt1jUJG", }) data = json.loads(urllib.request.urlopen(url, timeout=30).read()) for r in data.get("results", [])[:5]: print(r["engine"], r["title"][:80], "→", r["url"]) ``` ## Response shape JSON: `{results: [...], unresponsive_engines: [...], suggestions: [...], query: ...}` Each result: `title, url, content, host, engine, score, type, publishedDate (optional)`. Alternative formats: - `?format=csv` → CSV with columns `title,url,content,host,engine,score,type` (great for scripts) - `?format=rss` → RSS 2.0 feed ## Pitfalls - **Domain typo is the #1 way to silently break this skill**. `searxng.erhe.top` ≠ `searxng.erhe.top`. Jack's `docker-compose.yaml` says `ehre.top`; the live deployment is `erhe.top`. If `Could not resolve host` / DNS `NXDOMAIN`, double-check the spelling — almost certainly an `h`/`r` swap. - **JSON endpoint requires the token**. Without `?token=...`, returns 403. Token is rotated by changing `SEARXNG_API_KEY` env in docker-compose; no code redeploy needed. - **Google main engine is OFF**. `google.com` is blocked at upstream (Cloudflare anti-bot). Only `google_scholar` / `google_images` / `google_videos` / `google_news` / `google_cse` are enabled. If the user says "用 google 搜 XX", expect mostly bing/duckduckgo results — be honest about it rather than silently re-routing. - **LibreSSL/OpenSSL warning from urllib3 v2** is harmless on macOS Python 3.9. `urllib3 v2 only supports OpenSSL 1.1.1+, but the 'ssl' module is compiled with LibreSSL`. The search still runs to completion; ignore the warning, do not reinstall. - **SEO content farm pollution**. DuckDuckGo heavily surfaces AI-generated SEO blogs (llmmac / meshmac / neokvm / vulcloud / maccompute). For pricing/spec verification, filter by `host` to `apple.com`, `wikipedia.org`, `*.edu`, `github.com`, `arxiv.org`, `*.gov`. Don't blindly trust first-page blog links for actual prices. - **brave / mojeek / qwant commonly time out** (server logs show them in `unresponsive_engines`). Real workhorses: bing, duckduckgo, startpage, wikipedia 系, github 系. ## CLI flags (for `searxng_search.py`) | Flag | Meaning | |---|---| | `-m N` / `--max-results N` | Result row limit (default 10) | | `-l LANG` | `auto` / `zh` / `en` / `ja` / `de` / `fr` | | `-c CAT` | `general` / `images` / `videos` / `news` / `music` | | `--time-range` | `day` / `week` / `month` / `year` | | `--safesearch` | `0` / `1` / `2` | | `--raw` | Print raw JSON | | `-v` / `--verbose` | Verbose per-result output | ## Companion docs in this folder - `searxng_skills.md` — full API reference (more endpoints) - `searxng_README.md` — quickstart (Chinese) - `searxng_search.py` — the CLI entry; can also be imported as a module