SearXNG Search

Run free, keyless meta-search through a SearXNG instance, a privacy-respecting self-hosted aggregator that queries 70+ search engines simultaneously.

Hermes Intermediate Copied: 0
1 resource

Requirements

  • No API key is required when using a public instance, and SearXNG can alternatively be self-hosted for full control. The skill automatically appears as a fallback when the main web search toolset (FIRECRAWL_API_KEY) is not configured.
  • SearXNG requires a SEARXNG_URL environment variable pointing to your SearXNG instance.
  • Search requests are built from query parameters: q (query string, URL-encoded, e.g. q=python+async), format (output format: json, csv, rss, e.g. format=json), engines (comma-separated engine names, e.g. engines=google,bing,ddg), limit (max results per engine, default 10, e.g. limit=5), categories (filter by category, e.g. categories=news,science), safesearch (safesearch: 0=none, 1=moderate, 2=strict, e.g. safesearch=0) and time_range (filter: day, week, month, year, e.g. time_range=week).
  • SEARXNG_URL must always be set; without it, the skill cannot function.

How to use

This skill runs on Linux and macOS, is tagged for search, meta-search and self-hosted use, and acts as a fallback for the web toolset.

Public SearXNG instances are available if you do not want to self-host.

Instance availability: if the SearXNG instance is down or unreachable, search fails, so always check SEARXNG_URL is set and the instance is reachable.

No content extraction: SearXNG returns snippets, not full page content; use web_extract, browser tools, or curl for full articles.

Rate limiting: some public instances limit requests; self-hosting avoids this.

Engine coverage: available engines depend on the SearXNG instance configuration, and some engines may be disabled.

Results freshness: meta-search aggregates external engines, so result freshness depends on those engines.

For troubleshooting: if SEARXNG_URL is not set, no instance is configured, so use a public SearXNG instance or set up your own; if the connection is refused, the instance is not running or the URL is wrong, so check both; for empty results the instance blocks the query, so try a different instance or self-host; for slow responses the public instance is under load, so self-host or use a less-loaded one; if the json format is not supported, the SearXNG version is old, so try format=rss or upgrade SearXNG.

Self-hosting is best: public instances may go down, rate-limit, or block, while a self-hosted instance is reliable.

If SEARXNG_URL is not set and the user asks about SearXNG, help them either find a public SearXNG instance by searching for a public searxng instance, or set up their own with Docker or pip; public instances are listed at the SearXNG site.

Setting up their own instance can be done with Docker or pip.

Public instances are listed at the SearXNG website.

Set the SEARXNG_URL environment variable to a public instance URL (no setup required) or to your self-hosted SearXNG instance.

Point SEARXNG_URL at your SearXNG instance as shown in the configuration example.

# Public instances (no setup required)
SEARXNG_URL=https://searxng.example.com

# Self-hosted SearXNG
SEARXNG_URL=http://localhost:8888

If no instance is configured, this skill is unavailable and the agent falls back to other search options.

Before choosing an approach, run the detection check to confirm what is actually available.

Check what is actually available before choosing an approach.

# Check if SEARXNG_URL is set and the instance is reachable
curl -s --max-time 5 "${SEARXNG_URL}/search?q=test&format=json" | head -c 200

If SEARXNG_URL is set and the instance responds, use SearXNG; if it is unset or unreachable, fall back to other available search tools.

When SEARXNG_URL is unset or unreachable, fall back to other available search tools.

The preferred method is calling the SearXNG JSON API from the command line as shown, including text searches, safesearch settings and category filters.

Use curl via terminal to call the SearXNG JSON API; this avoids assuming any particular Python package is installed.

# Text search (JSON output)
curl -s --max-time 10 \
  "${SEARXNG_URL}/search?q=python+async+programming&format=json&engines=google,bing&limit=10"

# With Safesearch off
curl -s --max-time 10 \
  "${SEARXNG_URL}/search?q=example&format=json&safesearch=0"

# Specific categories (general, news, science, etc.)
curl -s --max-time 10 \
  "${SEARXNG_URL}/search?q=AI+news&format=json&categories=news"

Parse the JSON results to extract each result's fields.

# Extract titles and URLs from JSON
curl -s --max-time 10 "${SEARXNG_URL}/search?q=fastapi&format=json&limit=5" \
  | python3 -c "
import json, sys
data = json.load(sys.stdin)
for r in data.get('results', []):
    print(r.get('title',''))
    print(r.get('url',''))
    print(r.get('content','')[:200])
    print()
"

Alternatively, call the SearXNG REST API from Python using the requests library.

Use the SearXNG REST API directly from Python with the requests library as shown.

import os, requests, urllib.parse

base_url = os.environ.get("SEARXNG_URL", "")
if not base_url:
    raise RuntimeError("SEARXNG_URL is not set")

query = "fastapi deployment guide"
params = {
    "q": query,
    "format": "json",
    "limit": 5,
    "engines": "google,bing",
}

resp = requests.get(f"{base_url}/search", params=params, timeout=10)
resp.raise_for_status()
data = resp.json()

for r in data.get("results", []):
    print(r["title"])
    print(r["url"])
    print(r.get("content", "")[:200])
    print()

Self-host SearXNG using the Docker command shown, then point SEARXNG_URL at the local instance.

# Using Docker
docker run -d -p 8888:8080 \
  -v $(pwd)/searxng:/etc/searxng \
  searxng/searxng:latest

# Then set
SEARXNG_URL=http://localhost:8888

Alternatively, install SearXNG via pip, edit its settings file, and run it as shown.

pip install searxng
# Edit /etc/searxng/settings.yml
searxng-run

Follow the search-then-extract workflow: search first, then extract full content from the most relevant URL.

SearXNG returns titles, URLs, and snippets — not full page content. To get full page content, search first and then extract the most relevant URL with web_extract, browser tools, or curl.

# Search for relevant pages
curl -s "${SEARXNG_URL}/search?q=fastapi+deployment&format=json&limit=3"
# Output: list of results with titles and URLs

# Then extract the best URL with web_extract

Always set SEARXNG_URL; without it, the skill cannot function.

URL-encode queries: spaces and special characters must be URL-encoded in curl, or use urllib.parse.quote() in Python.

Use format=json: the default format may not be machine-readable, so always request JSON explicitly.

Set a timeout: always use --max-time or timeout= to avoid hanging on unreachable instances.

Source: nousresearch/hermes-agent and its contributors. License: MIT.

Copyright (c) 2025 Nous Research

Translation and editorial adaptation by ClawCases.

>Resources

>Related Use Cases

>More at this level: Intermediate