web-search-mcp

web-search-mcp

Provides a free web search tool to MCP clients by connecting to a self-hosted SearXNG metasearch instance, enabling users to search the web with customizable parameters like categories and time range.

Category
Visit Server

README

web-search-mcp

A FastMCP server that exposes free web search to any MCP client (Claude Desktop, Claude Code, etc.), backed by a self-hosted SearXNG metasearch instance.

It provides a single tool, web_search, which returns a list of {title, url, content} results.

Why self-host SearXNG?

SearXNG's JSON API (/search?format=json) is disabled by default, and virtually all public instances keep it disabled (they return 403). This repo runs your own instance — natively (no Docker) or via Docker — with the JSON format enabled in searxng/settings.yml.

Prerequisites

  • Python 3.10+ (to run the MCP server)
  • git (to fetch SearXNG for the local run)
  • Optionally uv — handy but not required; you can use plain pip + python instead (see below)

Quickstart (local, no Docker)

1. Install SearXNG (one-time)

cd /home/remon/Documents/web-search-mcp

git clone --depth 1 https://github.com/searxng/searxng.git .searxng-src
python3 -m venv .searxng-src/venv
.searxng-src/venv/bin/pip install -r .searxng-src/requirements.txt
.searxng-src/venv/bin/pip install -e .searxng-src --no-build-isolation

The two-step install matters: SearXNG's build imports the package, so the runtime requirements must be present before the editable install, hence --no-build-isolation.

2. Start SearXNG

./run-searxng.sh

This serves SearXNG on http://127.0.0.1:8080 using searxng/settings.yml (which has the JSON API enabled). Leave it running in its own terminal.

Verify the JSON API in another terminal:

curl -s -o /dev/null -w '%{http_code}\n' 'http://127.0.0.1:8080/search?q=fastmcp&format=json'
# expect: 200

3. Install the MCP server's dependencies

Pick one approach:

# A) plain pip + python (e.g. into your active conda/venv)
pip install -r requirements.txt

# B) uv (creates a managed .venv automatically)
uv sync

4. Run the MCP server

# matches whichever you chose above:
python server.py        # if you used pip
uv run server.py        # if you used uv
# or:  fastmcp run server.py:mcp

It starts on stdio transport and waits for an MCP client — it prints little; that's normal. By default it talks to http://localhost:8080; override with the SEARXNG_URL env var.

The deps are just fastmcp and httpx (see requirements.txt). With them installed in whatever Python is on your PATH, plain python server.py works — uv is optional.

Quick test without an MCP client

With SearXNG running:

python -c "import asyncio, server; print(asyncio.run(server.web_search('claude code', num_results=3)))"

Alternative: Docker

If you prefer Docker, skip the local install and use the bundled compose file:

docker compose up -d

Then run the MCP server (step 3 above). Same searxng/settings.yml is mounted into the container.

Connecting an MCP client

Example client config (e.g. Claude Desktop mcpServers) — using plain python (deps installed via pip install -r requirements.txt):

{
  "mcpServers": {
    "web-search": {
      "command": "python",
      "args": ["/home/remon/Documents/web-search-mcp/server.py"],
      "env": { "SEARXNG_URL": "http://localhost:8080" }
    }
  }
}

Use an absolute path to the python that has the deps (e.g. /home/remon/miniconda3/bin/python) if python on the client's PATH differs. Prefer uv? Swap to "command": "uv", "args": ["run", "--directory", "/home/remon/Documents/web-search-mcp", "server.py"].

For Claude Code (pip/python):

claude mcp add web-search -e SEARXNG_URL=http://localhost:8080 \
  -- python /home/remon/Documents/web-search-mcp/server.py

Connecting coding agents over HTTP (Cursor, Windsurf, …)

Run the server in HTTP mode and point editors at its URL. Two processes must be running (two terminals):

# Terminal 1 — search backend
./run-searxng.sh                 # SearXNG on http://127.0.0.1:8080

# Terminal 2 — MCP server over HTTP
./run-mcp.sh                     # MCP endpoint at http://127.0.0.1:8000/mcp

run-mcp.sh just sets MCP_TRANSPORT=http (port 8000, path /mcp, talking to SEARXNG_URL). Override with MCP_PORT=… ./run-mcp.sh if 8000 is taken.

Cursor — ~/.cursor/mcp.json (global) or .cursor/mcp.json (project)

{
  "mcpServers": {
    "web-search": {
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}

Windsurf — ~/.codeium/windsurf/mcp_config.json

{
  "mcpServers": {
    "web-search": {
      "serverUrl": "http://127.0.0.1:8000/mcp"
    }
  }
}

Other clients (Claude Code, Cline, Zed, …) use the same idea — give them the URL http://127.0.0.1:8000/mcp. For Claude Code: claude mcp add --transport http web-search http://127.0.0.1:8000/mcp. After editing a config, restart / refresh the editor's MCP servers, then ask it to search the web — it should call the web_search tool.

No auth is needed for a localhost endpoint, so no headers block. If you expose it beyond localhost, put it behind a reverse proxy with a bearer token (see DEPLOYMENT.md) and add a matching "headers": {"Authorization": "Bearer …"} to the client config.

Using it in a LangGraph / LangChain agent

Bridge the MCP server into LangChain tools with langchain-mcp-adapters, then hand them to a LangGraph agent. A complete, runnable example is in examples/langgraph_agent.py.

pip install langgraph "langchain[anthropic]" langchain-mcp-adapters
export ANTHROPIC_API_KEY=sk-ant-...     # for the Claude model
./run-searxng.sh                        # SearXNG must be running (separate terminal)

python examples/langgraph_agent.py "what is the model context protocol?"

The essence:

from langchain.chat_models import init_chat_model
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

client = MultiServerMCPClient({
    "web-search": {
        "command": "python",
        "args": ["/home/remon/Documents/web-search-mcp/server.py"],
        "transport": "stdio",                       # adapter launches server.py for you
        "env": {"SEARXNG_URL": "http://localhost:8080"},
    }
})
tools = await client.get_tools()                    # -> [web_search] as a LangChain tool
agent = create_react_agent(init_chat_model("anthropic:claude-opus-4-8"), tools)
result = await agent.ainvoke({"messages": [{"role": "user", "content": "..."}]})

With stdio the adapter spawns server.py itself — you only need SearXNG running. To point at an already-running HTTP server instead (see DEPLOYMENT.md), use {"url": "http://localhost:8000/mcp", "transport": "streamable_http"}.

Deploying on a server

To run this always-on for remote clients (HTTP transport, TLS, systemd), see DEPLOYMENT.md. The server reads MCP_TRANSPORT=http plus MCP_HOST/MCP_PORT/MCP_PATH to switch from local stdio to a remote HTTP endpoint — no code changes required.

The web_search tool

Parameter Type Default Notes
query str — Search terms (required).
num_results int 5 Max results to return.
categories str none e.g. general, news, science, it.
language str none e.g. en, de, all.
time_range str none day, month, or year.
pageno int 1 Result page number.

Point at a remote instance instead

Any JSON-enabled SearXNG works — no local install needed:

SEARXNG_URL=https://my-searxng.example.com uv run server.py

Troubleshooting

  • 403 from the tool / curl — JSON format isn't enabled. Confirm search.formats includes json in searxng/settings.yml, then restart SearXNG (./run-searxng.sh or docker compose restart).
  • Connection refused — SearXNG isn't running, or SEARXNG_URL points to the wrong host/port.
  • ModuleNotFoundError during install — you skipped the requirements step; run pip install -r .searxng-src/requirements.txt first, then the editable install with --no-build-isolation.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured