mcp-searxng-local

mcp-searxng-local

MCP server for local web search via SearXNG, providing unlimited queries without API keys or cost, with automatic fallback to public instances.

Category
Visit Server

README

mcp-searxng-local

License: MIT Node tests

MCP server for web search via SearXNGzero API keys, zero cost, 100% local.

Why not Exa? Costs money. Why not Brave? Requires API key. This: self-hosted, unlimited queries, your data never leaves your machine.

Rate Limit Handling & Fallback

Search engines (Google, DuckDuckGo, Brave) frequently block server IPs with CAPTCHAs or rate limits. mcp-searxng-local handles this automatically:

  1. Local query — queries your self-hosted SearXNG with configured engines
  2. Detection — if all engines return 0 results and are marked unresponsive, triggers fallback
  3. Fallback — automatically retries against public SearXNG instances in order
  4. Transparent — response always includes ## Unresponsive Engines section showing what failed and why
# Configure fallback instances (comma-separated, tried in order)
export SEARXNG_FALLBACK_URLS="https://search.rhscz.eu,https://searx.tiekoetter.com,https://searxng.website"

Pre-configured in opencode.json with 3 public instances. Works out of the box — no setup needed.

Prerequisites

  • Node.js >= 20
  • One of:
    • Docker + Docker Compose v2 (recommended)
    • Python 3.10+ on Termux (Android, no Docker needed)

Quick Start

Option A: Docker (recommended)

git clone https://github.com/dduartee/mcp-searxng-local
cd mcp-searxng-local
npm install && npm run build
docker compose up -d

# Verify SearXNG is responding
curl -s "http://localhost:4000/search?q=test&format=json" | python3 -c "import sys,json; print(len(json.load(sys.stdin).get('results',[])), 'results')"

# Verify MCP server works
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
# Expected: {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}

Option B: Termux (Android, no Docker)

Install SearXNG natively — no Docker required. See Termux Install Guide.

git clone https://github.com/dduartee/mcp-searxng-local ~/mcp-searxng-local
cd ~/mcp-searxng-local
npm install && npm run build

# Install SearXNG natively (see full guide)
pkg install -y libxslt binutils
# ... full steps in the guide ...
./start-searxng.sh

To install opencode itself on Termux, see opencode-termux.

Then add to your MCP client config below. Restart your client for the tools to appear.

Path note: replace /home/user/mcp-searxng-local in examples below with your actual clone path.

Why mcp-searxng-local?

Exa MCP Brave MCP mcp-searxng-local
API key Required Required None
Cost Paid (limited free) 2k/mo free Unlimited
Privacy Cloud (USA) Cloud 100% local
Engines Proprietary index Brave only Google, DDG, Brave, Wikipedia, arXiv
Highlights AI (paid) No Keyword matching (free)
GitHub fetch Generic HTML Generic HTML Optimized: raw content + API metadata
Cache Server-side No LRU local (5min TTL)

Tools

web_search / web_search_advanced

Parameter Type Default Description
query string (required) Search query
count number 10 Results (1-50)
pageno number 1 Page number
categories enum general, news, images, files, video, music
time_range enum day, month, year
language string pt-BR, en-US, etc.
includeDomains string[] Only results from these domains
excludeDomains string[] Exclude these domains
engines string google,duckduckgo,brave,wikipedia,arxiv,bing
safesearch number 0=off, 1=moderate, 2=strict
startPublishedDate string ISO date: "2025-01-01" (client-side filter)
endPublishedDate string ISO date: "2025-12-31" (client-side filter)

Response includes: results + direct answers, infoboxes, spelling suggestions, search suggestions, and unresponsive engine diagnostics.

web_fetch

Parameter Type Default Description
url string (required) Full URL
maxChars number 5000 Character limit (100-50000)
mode enum text text (full page) or highlights (relevant excerpts)
query string Required for highlights mode

Highlights tip: Results are typically ~98% smaller than full page text. Use mode=highlights with the same query that led you to the URL.

GitHub URL optimization

When web_fetch detects a GitHub URL, it bypasses HTML parsing and uses optimized endpoints:

GitHub URL pattern Route Result
github.com/user/repo GitHub API (api.github.com) Enriched response: metadata + file tree + README (3 parallel API calls)
github.com/user/repo/blob/... raw.githubusercontent.com Clean raw file content (no HTML)
github.com/user/repo/raw/... raw.githubusercontent.com Same — already raw
/issues, /pulls, etc. Falls back to generic HTML fetch Normal web_fetch behavior

Benefits: Blob/raw URLs return ~99% less noise vs HTML parsing. Repo root URLs fetch metadata, file tree, and README in parallel — structured data that is hard to extract from rendered HTML. GitHub API responses are cached with a 30-minute TTL.

Setup

After adding the config, restart your MCP client for the tools to appear.

Replace /home/user/mcp-searxng-local with your actual clone path.

OpenCode

# CLI (adds to global config)
opencode mcp add mcp-searxng-local -- node /home/user/mcp-searxng-local/dist/index.js
// Project config: ./opencode.json (relative path)
{ "mcp": { "mcp-searxng-local": { "type": "local", "command": ["node", "dist/index.js"] } } }

// Global config: ~/.config/opencode/opencode.json (absolute path)
{ "mcp": { "mcp-searxng-local": { "type": "local", "command": ["node", "/home/user/mcp-searxng-local/dist/index.js"] } } }

Claude Code

{
  "mcpServers": {
    "mcp-searxng-local": {
      "command": "node",
      "args": ["/home/user/mcp-searxng-local/dist/index.js"]
    }
  }
}

Cursor

// .cursor/mcp.json
{
  "mcpServers": {
    "mcp-searxng-local": {
      "command": "node",
      "args": ["/home/user/mcp-searxng-local/dist/index.js"]
    }
  }
}

VS Code

// .vscode/mcp.json
{
  "servers": {
    "mcp-searxng-local": {
      "command": "node",
      "args": ["/home/user/mcp-searxng-local/dist/index.js"]
    }
  }
}

Windsurf

// ~/.windsurf/mcp.json
{
  "mcpServers": {
    "mcp-searxng-local": {
      "command": "node",
      "args": ["/home/user/mcp-searxng-local/dist/index.js"]
    }
  }
}

Zed

// settings.json → "context_servers"
{
  "context_servers": {
    "mcp-searxng-local": {
      "command": "node",
      "args": ["/home/user/mcp-searxng-local/dist/index.js"]
    }
  }
}

Codex / Antigravity

See Install Guide for all client configs.

Termux (Android)

See Install Guide — Termux for MCP config and Termux Install Guide for full SearXNG setup.

Configuration

All env vars are optional — defaults work for local SearXNG on port 4000.

Env var Default Description
SEARXNG_HOST localhost SearXNG host
SEARXNG_PORT 4000 SearXNG port
SEARXNG_TIMEOUT 10000 HTTP timeout (ms)
SEARXNG_FALLBACK_URLS Comma-separated public SearXNG URLs (auto-retry when local engines are rate-limited or blocked)
GITHUB_TOKEN GitHub personal access token — raises API rate limit from 60 to 5000 req/h. When set, GitHub repo root fetches use authenticated API; falls back to generic HTML on 403
DEBUG false Enable verbose logging

Also accepts MCP_SEARCH_LOCAL_ prefix: MCP_SEARCH_LOCAL_SEARXNG_HOST, MCP_SEARCH_LOCAL_SEARXNG_PORT, MCP_SEARCH_LOCAL_TIMEOUT, MCP_SEARCH_LOCAL_DEBUG.

.env support

The server loads environment variables from a .env file automatically (via dotenv). Create a .env file in the project root:

SEARXNG_HOST=localhost
SEARXNG_PORT=4000
GITHUB_TOKEN=ghp_xxxxxxxxxxxx
DEBUG=false

Troubleshooting

Symptom Cause Fix
Tools don't appear Path wrong or build missing Run npm run build, verify dist/index.js exists
web_search connection error SearXNG not running Docker: docker compose up -d. Termux: ./start-searxng.sh
## Unresponsive Engines with brave: too many requests Engine blocked/rate-limited Auto-fallback handles this — no action needed. Add SEARXNG_FALLBACK_URLS for more options
All engines return 0 results + all unresponsive Server IP blocked by search providers Set SEARXNG_FALLBACK_URLS to public instances. Fallback retries automatically
Fallback returns 0 results too Public instances also blocked or down Try different instances in SEARXNG_FALLBACK_URLS, or wait and retry later
Highlights returns full page Page has no paragraph breaks or all text matches query Use mode=text with smaller maxChars
web_fetch timeout (15s) Page is slow or .js-heavy SPA Reduce maxChars, try a different URL
Termux: bilibili: can't register Timezone data missing pip install tzdata in the SearXNG venv
Termux: server dies after a few seconds Process not detached from shell Use setsid (handled by start-searxng.sh)

Testing

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"web_search","arguments":{"query":"test"}}}' | node dist/index.js

npm test             # 48 unit tests
npm run inspector    # MCP Inspector UI

Architecture

MCP Client (OpenCode, Claude Code, Cursor...)
  │ stdio or Streamable HTTP
  ▼
mcp-searxng-local (Node.js + TypeScript)
  │ HTTP + LRU cache + exponential backoff retry
  ▼
SearXNG (Docker or Termux native) ← Google, DDG, Brave, Wikipedia, arXiv
  │ if all engines unresponsive → auto-fallback
  ▼
Public SearXNG instances (search.rhscz.eu, searx.tiekoetter.com, ...)

Documentation

Doc Description
Install Guide Project, global, and plugin-based setup
Termux Install SearXNG native install on Android/Termux
Examples Real agent workflows and CLI usage
Architecture Internal design, data flow, decisions
Search Insights What AI agents actually need from search
Comparison vs Exa, Brave, SearXNG raw, Chrome DevTools
GitHub Fetch Optimized GitHub URL handling in web_fetch
CI GitHub Actions: build + test on push/PR

License

MIT

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