web-search-mcp
# web-search-mcp
A Python MCP server that exposes a `WebSearch` tool backed by a self-hosted [SearXNG](https://github.com/searxng/searxng) instance — a free, private web search engine.
Replace Claude's default web search with your own private instance. No API keys, no rate limits, no third-party tracking.
## Quick Start
### 1. Clone and start SearXNG
```bash
git clone https://github.com/LMilazzo/web-search-mcp.git
cd web-search-mcp
```
### 2. I recommend using the SearXNG docker container method as this is a quick easy set up if you already have docker installed.
```
#Pull the image
docker pull searxng/searxng
# Start SearXNG in the background
docker compose -f infra/docker-compose.yml up -d
```
SearXNG will be available at `http://localhost:8080`. This can be configured in /infra/docker-compose.yml.
### 3. Add the MCP server to Claude Code
- You need to replace the --directory flag value with the path to this repo locally.
```bash
uv sync
claude mcp add xngSearch -s user -- uv --directory "path/to/directory/" run --with "mcp[cli]" mcp run "src/web_search_mcp/mcp_server.py"
```
That's it. Restart Claude Code and you'll have a `WebSearch` tool available in your conversations.
### 4. Use it
Ask Claude to perform `WebSearch` and return formatted results:
> "What are the latest developments in quantum computing?"
## Configuration
### SearXNG URL
By default the tool connects to `http://localhost:8080`. If your SearXNG instance runs on a different port or host configured in docker-compose.yml:
- You need to replace the --directory flag value with the path to this repo locally.
```bash
claude mcp add xngSearch -s user \
--env SEARXNG_BASE_URL="http://localhost:8080" \
-- uv --directory "path/to/directory/" \
run --with "mcp[cli]" mcp run "src/web_search_mcp/mcp_server.py"
```
- You can remove the -s user flag if you want this to only apply to a specific project folder.
### Search Engines
Edit `infra/data/searxng/settings.yml` to add or disable search engines:
```yaml
engines:
- name: google
engine: google
- name: wikipedia
engine: wikipedia
- name: duckduckgo
engine: duckduckgo
- name: bing
engine: bing
```
## Restart SearXNG after changes:
- Note that occasional you may be timed out from certain search engines if you make very frequent requests, typically restarting your container resets these timers.
```bash
docker compose -f infra/docker-compose.yml restart
```
## Stopping
```bash
docker compose -f infra/docker-compose.yml down
```
Claude Code (via MCP protocol)
└── web-search-mcp (Python MCP server)
└── SearXNG (self-hosted search frontend)
```
The MCP server registers a single `WebSearch` tool that calls SearXNG's JSON API and returns results as a markdown-formatted string. Claude Code reads the markdown and presents it to you as a normal response.
## Requirements
- [Docker](https://www.docker.com/) (for SearXNG)
- Python 3.14+ (for the MCP server)
- [uv](https://github.com/astral-sh/uv) (for dependency management)
## License
SearXNG is licensed under the GNU Affero General Public License v3. See [searxng/searxng](https://github.com/searxng/searxng) for details.
TDQS
Scored across 1 tool
Only one tool exists, so there is no possibility of confusion between tools. The tool's name and description clearly communicate its single purpose.
With only one tool, naming consistency is trivially satisfied. The camelCase name 'WebSearch' is clear and predictable, though there is no broader set to compare against.
A single tool is slightly lean but appropriate for a focused web-search server. The tool directly fulfills the server's purpose without unnecessary additions, though most servers have more operations.
The server's entire domain is web search, and the single tool covers that capability fully by accepting a query and returning results. No obvious operations like pagination or configuration seem essential to the stated purpose.