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.
README
mcp-searxng-local
MCP server for web search via SearXNG — zero 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:
- Local query — queries your self-hosted SearXNG with configured engines
- Detection — if all engines return 0 results and are marked unresponsive, triggers fallback
- Fallback — automatically retries against public SearXNG instances in order
- Transparent — response always includes
## Unresponsive Enginessection 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)
- Install opencode: see opencode-termux for pre-built binaries
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-localin 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-localwith 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。