ask-search: a SearxNG wrapper that gives CLI agents web search without an API key
Self-hosted web search skill for AI agents (OpenClaw/Claude Code/Antigravity) via SearxNG
At a glance
- What is it?
- ask-search is a small Python CLI and MCP server that turns a self-hosted SearxNG instance into a search tool for OpenClaw, Claude Code and Antigravity. It removes per-query API billing and query leakage, but it does not solve page fetching, and the README is candid about where that breaks.
- Who is it for?
- Adopt ask-search if you already run SearxNG or are willing to run it, and your agent's job is to find URLs and snippets rather than read full pages. Do not adopt it if you need reliable full-page retrieval from Reddit, Zhihu or Medium, because the README itself documents that datacenter IPs and login walls block those fetches, and ask-search has no built-in proxy layer.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 177 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The billing and privacy problem ask-search is aimed at
The README opens with a price list. Brave Search API is quoted at $3 per 1000 queries with rate limits, Google Custom Search at $5 per 1000 with daily caps, and Bing described as paid and complex to set up. Built-in web search in most agent frameworks is called out separately: it sends queries to third-party servers, which means the query text leaves your machine. The stated goal is narrow and clear. You want a local agent to search Google without paying per query and without leaking the query to a vendor.
The intended user is someone running an agent on their own infrastructure, whether a laptop, a home server or a VPS. That person already accepts the operational cost of running services, because ask-search does not ship a search index. It ships a client. The actual search engine is SearxNG, a separate project that aggregates Google, Bing, DuckDuckGo, Brave and, per the README, 70 or more sources. ask-search is the thin layer between an agent and that instance. If you are not willing to run SearxNG, this project has nothing to offer you, because the CLI has no default backend other than a SearxNG URL on localhost.
How the CLI, the MCP server and SearxNG fit together
The repository layout is four files and a directory. scripts/core.py holds the main logic and the CLI entry point. mcp/server.py is the MCP server used for Antigravity and Claude Code integration. install.sh is the installer. SKILL.md is the descriptor that OpenClaw reads when loading the skill. There is no bundled SearxNG; the searxng directory in the repo holds a docker-compose.yml and an .env.example that you are expected to configure yourself.
The data flow is one hop. The agent invokes ask-search with a query string. The CLI reads SEARXNG_URL, defaults to http://localhost:8080, and issues a request to that SearxNG instance. SearxNG fans the query out to whatever engines it is configured to use, merges the results and returns them. ask-search then prints them, either as human-readable numbered entries with title, URL, snippet and a bracketed list of contributing engines, or as raw JSON when --json is passed. The README's example output shows the engine attribution inline, for instance [google,brave], which is useful when you are debugging which upstream engine returned a result.
The MCP path is the same logic behind a different transport. mcp/server.py exposes three tools: web_search and web_search_news both go through SearxNG, and web_search_tavily goes to Tavily and requires TAVILY_API_KEY. That means the MCP server is not purely self-hosted. If an agent picks the Tavily tool, the query leaves your network. The README does not explain how an agent is expected to choose between the three tools, and that is a real gap: nothing in the supplied material describes routing logic, so selection is presumably left to the model or the caller.
Getting it running: two paths and the settings that must be changed
There are two documented install paths. The short one assumes SearxNG is already reachable: clone the repository, run bash install.sh, then run ask-search "hello world". The full path starts SearxNG first, either with a docker run command that publishes 127.0.0.1:8080 and sets SEARXNG_SECRET_KEY, or with the docker-compose.yml in the searxng directory. The README recommends generating the secret with python3 -c "import secrets; print('SEARXNG_SECRET=' + secrets.token_hex(32))" and copying searxng/.env.example to searxng/.env before starting the stack.
One step is easy to miss and will produce silent failures. SearxNG does not return JSON unless you enable it. The README instructs you to edit settings.yml and add json under search.formats, alongside html. Without that change, ask-search's JSON parsing has nothing to parse. The second documented gotcha is bot detection: limiter.toml may block requests from some IPs, and the README says to add your server IP to pass_ip. It also advises binding to 127.0.0.1 unless you need remote access, which is the right default given that SearxNG has no authentication layer described here.
Configuration is environment variables. SEARXNG_URL defaults to http://localhost:8080. SEARCH_PROVIDER defaults to searxng and can be set to tavily, in which case TAVILY_API_KEY becomes required. The CLI flags are --num, --categories, --lang, --urls-only, --json and -e for a comma-separated engine list. The --urls-only flag is the one worth noting for agent pipelines: it emits bare URLs so they can be piped into a fetch step, which is the workflow the README's Agent Workflow section describes.
Search works everywhere; fetching the page is where it breaks
The most useful part of the README is the limitations table, and it is more honest than most. Search through SearxNG succeeds against most sites because SearxNG queries search engines, not the target sites. The engines have already indexed the content, so anti-bot measures on the destination never come into play. The failure appears one step later, when the agent tries to retrieve the full page with curl or a fetch tool.
The README names three cases. Reddit search works, but deep-dive fetches fail because Reddit blocks datacenter IPs, which is exactly what a VPS presents. Zhihu search works, but the page requires browser JavaScript and a login, so a plain HTTP fetch returns a wall. Medium search works, but the fetch returns partial content because of the paywall. The documented workaround is a SOCKS proxy over SSH to a machine on a residential network: ssh -f -N -D 127.0.0.1:1082 user@your-home-machine, then curl -x socks5h://127.0.0.1:1082 against the target. For Reddit specifically, the README suggests appending .json to a post URL to get structured post and comment data. It also shows a systemd unit for persisting the tunnel, though the excerpt cuts off mid-file.
This is the honest boundary of the project. ask-search is a discovery tool, not a retrieval tool. If your agent's task is summarising a page, ask-search gets you the URL and then hands you a problem it does not solve. The proxy workaround is manual, requires a second machine, and is not wired into the CLI or the MCP server as far as the supplied material shows.
Where ask-search is the wrong choice
The clearest case against it is any deployment where you cannot run SearxNG. That includes serverless agent platforms, managed agent products where you do not control the network, and environments where adding a Docker service is not an option. ask-search has no hosted fallback. The Tavily path is the only non-SearxNG backend, and it reintroduces exactly the vendor dependency and per-query cost the project exists to avoid.
A second case is latency-sensitive or high-volume use. SearxNG aggregates multiple upstream engines per query, which means each request waits on the slowest of them, and the README gives no timeout, caching or concurrency guidance. Nothing in the supplied material describes a cache layer, so repeated identical queries will hit the upstream engines again. If your agent issues hundreds of searches per task, that cost lands on the engines you are scraping rather than on your wallet, and rate limiting from those engines is a plausible outcome the README does not address.
A third case is anyone who needs ranked, relevance-tuned results. SearxNG merges engine output; it does not rerank with a model. There is no described scoring, deduplication or freshness weighting in ask-search itself. If result quality is the bottleneck rather than cost, a managed search API with its own ranking is doing work that this stack simply does not do.
Tavily, and what the alternative actually changes
The README builds in its own alternative rather than leaving you to find one. Setting SEARCH_PROVIDER=tavily and TAVILY_API_KEY routes queries to Tavily's API instead of SearxNG, and the MCP server exposes this as a separate web_search_tavily tool. The difference in approach is not cosmetic. SearxNG is a meta search engine you host: it scrapes or queries other engines, you own the infrastructure, the queries never leave your network, and the marginal cost per query is zero. Tavily is a hosted search API built for language models: you send a query and a key, someone else runs the retrieval, and you pay per call.
What Tavily buys is the removal of operational work. No Docker container, no settings.yml edit, no limiter.toml pass_ip entry, no secret to rotate. What it costs is the two properties the project's opening section complains about: per-query billing and queries leaving your machine. The README does not present this as a contradiction, and it is not one, because the Tavily path is opt-in and off by default. But it does mean the project's headline claim of zero API key and full privacy describes the default configuration only. An agent with access to all three MCP tools can choose the one that breaks that property, and nothing in the supplied material constrains that choice.
Maintenance surface, licensing and what to check first
The maintenance burden sits mostly outside ask-search. You maintain a SearxNG container, keep its settings.yml correct across upgrades, and watch for upstream engine changes that break aggregation. SearxNG's own release cadence, which the README does not discuss, will drive most of your upgrade work. ask-search itself is small enough that its own upgrade cost is low: core.py, server.py, install.sh and SKILL.md. The single release listed is v1.0.0 from 2026-03-09, described as a cross-environment SearxNG search skill, with the last push to master on 2026-03-22. That is a young project with one tagged release, and the supplied material contains no changelog, no test suite and no CI configuration, so you cannot infer how regressions would be caught.
The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the extent of what the repository states. It is not legal advice, and if you are embedding this in a product, the licence of SearxNG itself and of the search engines SearxNG queries are separate questions the README does not touch.
Before you install, confirm the JSON format setting, since that is the failure that produces the least obvious error. If you plan to use the MCP server rather than the CLI, note that it requires pip install mcp, a dependency the CLI path does not need. And decide up front whether you need page content, because if you do, ask-search is step one of a two-step pipeline whose second step you have to build yourself.
Editorial conclusion
Adopt ask-search if you already run SearxNG or are willing to run it, and your agent's job is to find URLs and snippets rather than read full pages. Do not adopt it if you need reliable full-page retrieval from Reddit, Zhihu or Medium, because the README itself documents that datacenter IPs and login walls block those fetches, and ask-search has no built-in proxy layer. Before committing, verify three things: that json is enabled under search.formats in your SearxNG settings.yml, that your server IP is listed in pass_ip in limiter.toml, and that the mcp package installs cleanly if you plan to use the MCP server rather than the CLI.
Community notes