Skip to main content
Glama
remon-rakibul

web-search-mcp

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.

Related MCP server: SearXNG MCP Server

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.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/remon-rakibul/web-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server