Back to Learnings

Learnings / Building with SearXNG

Give your agents a search endpoint you control.

How we connected SearXNG to an agent workflow, with structured results and an explicit fallback when search fails.

The reason

A search query can reveal what you are working on.

An agent searching for documentation may include details from the task you gave it. We wanted a search connection we could configure and inspect, rather than leaving that choice to whichever tool the agent used.

We connected a self-hosted SearXNG instance to the agent through a small script. It gives us control over that connection. It does not keep web searches offline.

01 / The concept

Make search a part of the stack we operate

The starting point was the search tool our agents used. A web search looks like a small action, but the query can contain project names, technical problems or details copied from a conversation. We wanted to choose where that request went and how the results came back.

We used SearXNG, an existing open-source metasearch engine, rather than building a search engine ourselves. Our work was the integration around it: a local service, a script for retrieving results and instructions for the agent to use that script.

The companion guides show this with OpenClaw. The search script can also be tested on its own, so you can check the service before involving an agent.

02 / The problem

Self-hosted does not mean the query stays at home

SearXNG forwards web queries to the search engines you enable and combines their results. Those engines still receive the query and see the network address your server uses to reach them. A sensitive name in the query remains sensitive after passing through your own server.

The useful distinction is control over the intermediary. We can choose its configuration and how our agent connects to it. We also need to review logging in the surrounding infrastructure, including any reverse proxy, rather than assuming that running the application ourselves makes every record disappear.

There is an operational trade-off too. We run and maintain the service, and upstream engines can refuse requests or become unavailable. This is not a promise of free, unlimited or anonymous search. The SearXNG documentation explains the project and its configuration options.

03 / How it works

From an agent query to results it can inspect

One endpoint for the search request

The local setup runs SearXNG in a container. The agent calls a shell script, which sends the query to that instance. The script uses a configurable server address so the connection is defined in one place.

Agent → search script → your SearXNG instance
                              ↓
                    External search engines
                              ↓
Agent ← titles, links and snippets ← combined results

The diagram shows the privacy boundary: the agent calls your service, but the service still contacts external engines. Do not put credentials or private material in a query just because the first endpoint is local.

Structured results instead of a page to scrape

We enable JSON output in SearXNG. The script requests that format, then uses jq to select a limited number of results and return their titles, URLs and snippets. The Search API documentation describes the request parameters and supported output formats.

That gives the agent links it can follow. A snippet is only a lead, not enough evidence for every claim. The agent still needs to open relevant sources and check what they say.

Give the agent instructions, then test the connection

The OpenClaw integration pairs search.sh with a SKILL.md file explaining how to call it. We test the script directly before asking the agent to use it. That separates service or configuration failures from a failure to follow the instructions.

Instructions alone do not prevent the agent from using another search tool. If a particular request path is required, the available tools and their permissions must match that requirement.

Make a fallback visible

The recovery guide adds a wrapper that checks for usable output. When it cannot obtain results, it prints a FALLBACK_TO_BRAVE marker. The wrapper does not call Brave itself. The agent needs a configured backup tool and instructions about when it may use it.

This matters because a fallback changes the service receiving the request. Decide whether that is acceptable before enabling it. An empty result and a failed connection also deserve different explanations; neither should be presented as evidence that nothing exists.

04 / Installation

Let's set up the local search service

Start with Docker and Compose, plus curl, jq and openssl. OpenClaw is needed for the agent-specific part of the guide. The service needs internet access to contact its search engines.

Deploy SearXNG and verify its JSON response first. Then create the search script, test it from the terminal and connect the agent. Keep the local endpoint bound to loopback unless you deliberately configure access from another machine.

The guides below contain the configuration and commands. Begin with the installation requirements, or open the part you need.

Connect your agents to your own search service.

Run SearXNG, verify the results and connect the agent.

All guides