# How Agent Zero Uses SearXNG Integration for Private Web Searches

> Agent Zero integrates SearXNG for private web searches. Discover how it routes queries through SearXNG for normalized, LLM-ready results, ensuring your privacy.

- Repository: [Agent Zero/agent-zero](https://github.com/agent0ai/agent-zero)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Agent Zero routes web search queries through a local SearXNG instance via an async HTTP client wrapped in a development-mode RPC bridge, normalizing results through the SearchEngine tool for LLM consumption.**

The agent0ai/agent-zero repository implements privacy-preserving web search by integrating a local SearXNG instance rather than relying on external APIs. This architecture ensures that search queries never leave the local environment while providing the LLM with real-time internet access. The implementation follows a three-layer design that separates low-level HTTP communication, tool abstraction, and secure execution environments.

## Architecture of the Agent Zero SearXNG Integration

### Low-Level HTTP Client ([`python/helpers/searxng.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/searxng.py))

The foundation resides in [`python/helpers/searxng.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/searxng.py), which defines the asynchronous `search(query: str)` function. This helper uses **aiohttp** to POST requests to `http://localhost:55510/search` with parameters `q` and `format=json`, returning the raw JSON payload from the SearXNG server. The actual HTTP logic lives in the private `_search` function, which the public `search` function invokes through the runtime bridge.

### Agent Tool Interface ([`python/tools/search_engine.py`](https://github.com/agent0ai/agent-zero/blob/main/python/tools/search_engine.py))

The `SearchEngine` class in [`python/tools/search_engine.py`](https://github.com/agent0ai/agent-zero/blob/main/python/tools/search_engine.py) exposes web search as a standard Agent Zero tool. When the LLM invokes this tool, the `execute()` method delegates to `searxng_search()`, which internally calls `helpers.searxng.search`. The class then normalizes the raw SearXNG response through `format_result_searxng()`, extracting titles, URLs, and snippets from the first 10 results into a formatted string optimized for LLM context windows.

### Secure Execution Bridge ([`python/helpers/runtime.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/runtime.py))

To safely execute arbitrary Python code during development, [`python/helpers/runtime.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/runtime.py) provides `call_development_function`. In development mode, this wraps the SearXNG call in an internal **RFC** (Remote Function Call) protocol that sends the request to the host process, preventing the LLM-controlled agent from directly executing network calls. In production deployments, the function is simply awaited locally without the RPC overhead.

## Step-by-Step Search Execution Flow

1. The LLM issues a search request via the `SearchEngine` tool (e.g., `search "latest AI news"`).

2. `SearchEngine.execute()` invokes `self.searxng_search(query)`.

3. `searxng_search()` executes `await searxng(question)`.

4. `helpers.searxng.search` enters `runtime.call_development_function(_search, query)`.

5. In development mode, `runtime.call_development_function` sends an RFC to the host process.

6. The host process executes `_search`, which performs an HTTP POST to `http://localhost:55510/search`.

7. The local SearXNG server returns a JSON payload containing result objects with `title`, `url`, and `content` fields.

8. `_search` returns the JSON through the runtime bridge.

9. `SearchEngine.format_result_searxng()` extracts and formats the top 10 results.

10. The Agent receives the formatted string and incorporates it into its reasoning context.

## Implementation Examples

### Using the SearchEngine Tool

```python
from python.tools.search_engine import SearchEngine
from python.helpers.agent import Agent

async def run_example():
    agent = Agent()
    agent.register_tool(SearchEngine())
    
    result = await agent.invoke_tool(
        tool_name="SearchEngine",
        query="latest developments in quantum computing"
    )
    print(result.message)

```

### Direct Helper Invocation

```python
import asyncio
from python.helpers.searxng import search

async def raw_search():
    json_result = await search("open-source LLM frameworks")
    print(json_result)

# asyncio.run(raw_search())

```

### Runtime Bridge Mechanics

```python

# Inside python/helpers/searxng.py

async def search(query: str):
    return await runtime.call_development_function(_search, query=query)

async def _search(query: str):
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "http://localhost:55510/search",
            data={"q": query, "format": "json"}
        ) as response:
            return await response.json()

```

## Deployment Configuration

Agent Zero includes Docker scripts to manage the SearXNG lifecycle. The installation script at [`docker/base/fs/ins/install_searxng.sh`](https://github.com/agent0ai/agent-zero/blob/main/docker/base/fs/ins/install_searxng.sh) configures the server inside the container, while [`docker/run/fs/exe/run_searxng.sh`](https://github.com/agent0ai/agent-zero/blob/main/docker/run/fs/exe/run_searxng.sh) initializes the service on port 55510. This containerized approach ensures the search backend starts automatically with the agent environment.

## Summary

- **Local Privacy**: All searches route through a local SearXNG instance at `localhost:55510`, preventing data leakage to third-party search APIs.
- **Three-Layer Architecture**: The system separates concerns between HTTP client ([`searxng.py`](https://github.com/agent0ai/agent-zero/blob/main/searxng.py)), tool abstraction ([`search_engine.py`](https://github.com/agent0ai/agent-zero/blob/main/search_engine.py)), and execution safety ([`runtime.py`](https://github.com/agent0ai/agent-zero/blob/main/runtime.py)).
- **Development Security**: The RFC bridge in [`runtime.py`](https://github.com/agent0ai/agent-zero/blob/main/runtime.py) isolates network calls from the LLM-controlled process during development.
- **Standardized Output**: The `SearchEngine` tool normalizes raw JSON into consistent, context-optimized strings for LLM consumption.

## Frequently Asked Questions

### What port does Agent Zero use for SearXNG communication?

Agent Zero communicates with the local SearXNG instance via HTTP POST requests to port **55510** on localhost (`http://localhost:55510/search`). This endpoint is hardcoded in [`python/helpers/searxng.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/searxng.py) and initialized through the Docker scripts [`docker/run/fs/exe/run_searxng.sh`](https://github.com/agent0ai/agent-zero/blob/main/docker/run/fs/exe/run_searxng.sh).

### How does Agent Zero secure web search execution in development mode?

During development, Agent Zero wraps SearXNG calls using `runtime.call_development_function` from [`python/helpers/runtime.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/runtime.py). This implements an internal RFC protocol that routes the HTTP request to the host process, ensuring the LLM-controlled agent cannot directly execute arbitrary network operations.

### Can I use the SearXNG helper without the SearchEngine tool?

Yes. You can import and call `search()` directly from [`python/helpers/searxng.py`](https://github.com/agent0ai/agent-zero/blob/main/python/helpers/searxng.py) to receive raw JSON responses from the local SearXNG instance. However, using the `SearchEngine` tool is recommended as it handles result formatting through `format_result_searxng()` and integrates with Agent Zero's tool registry.

### What search result fields does Agent Zero extract from SearXNG?

The `format_result_searxng()` method in [`python/tools/search_engine.py`](https://github.com/agent0ai/agent-zero/blob/main/python/tools/search_engine.py) extracts the `title`, `url`, and `content` (snippet) fields from the first 10 results in the SearXNG JSON response, concatenating them into a formatted string suitable for LLM context windows.