@voidog/searxng-mcp
v1.0.0
Published
MCP server providing web_search and web_fetch tools via a local SearXNG instance
Maintainers
Readme
@voidog/searxng-mcp
An MCP (Model Context Protocol) server that provides web_search and web_fetch tools via a local SearXNG instance. Designed for privacy-focused web search and page fetching from AI assistants like Claude.
Features
web_search— Search the web through SearXNG meta-search engine with support for categories, language filtering, and result limitsweb_fetch— Fetch any web page and convert it to clean Markdown using Mozilla Readability and Turndown- Privacy-first — All searches go through your own SearXNG instance, no data sent to third parties
- SSRF protection — Comprehensive private/reserved IP blocking (RFC 1918, loopback, link-local, IPv6 ULA, and more)
- Input validation — Strict URL protocol whitelist, query length limits, and Zod runtime response validation
Prerequisites
- Node.js >= 20
- A running SearXNG instance with JSON format enabled
If you don't have SearXNG yet, the quickest way to get started:
docker run -d -p 4000:8080 searxng/searxngMake sure JSON output is enabled in your SearXNG settings (search.formats: [html, json]).
Installation
Using npx (no install required)
npx @voidog/searxng-mcpGlobal install
npm install -g @voidog/searxng-mcpConfiguration
Claude Code
claude mcp add searxng-mcp -- npx @voidog/searxng-mcpOr if installed globally:
claude mcp add searxng-mcp -- searxng-mcpOr with user settings.json (~/.claude/settings.json):
{
"mcpServers": {
"searxng-mcp": {
"command": "npx",
"args": ["@voidog/searxng-mcp"]
}
}
}Or with project-level .mcp.json:
{
"mcpServers": {
"searxng-mcp": {
"command": "npx",
"args": ["@voidog/searxng-mcp"]
}
}
}Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"searxng-mcp": {
"command": "npx",
"args": ["@voidog/searxng-mcp"],
"env": {
"SEARXNG_URL": "http://127.0.0.1:4000"
}
}
}
}Cursor / VS Code (Copilot)
Add to .cursor/mcp.json or .vscode/mcp.json:
{
"servers": {
"searxng-mcp": {
"command": "npx",
"args": ["@voidog/searxng-mcp"],
"env": {
"SEARXNG_URL": "http://127.0.0.1:4000"
}
}
}
}Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| SEARXNG_URL | http://127.0.0.1:4000 | URL of your SearXNG instance |
Tools
web_search
Search the web using SearXNG meta-search engine. Returns results with titles, URLs, and snippets.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| query | string | Yes | Search query (1-2000 chars) |
| max_results | number | No | Maximum results to return (1-50, default: 10) |
| categories | string | No | Search category: general, news, images, it, science, files, music, videos, social media |
| language | string | No | Language code (e.g., en, ja, de, en-US) |
web_fetch
Fetch a web page and convert its content to Markdown.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| url | string | Yes | URL to fetch (http/https only) |
| max_length | number | No | Max content length in chars (100-200000, default: 20000) |
| extract_main | boolean | No | Use Readability to extract main article content (default: true) |
Security
This server includes multiple layers of security hardening:
- SSRF Protection — Blocks all private/reserved IP ranges: RFC 1918 (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16), loopback (127.0.0.0/8), link-local (169.254.0.0/16), CGNAT (100.64.0.0/10), TEST-NET (192.0.2.0/24,198.51.100.0/24,203.0.113.0/24), multicast (224.0.0.0/4), IPv6 loopback/ULA/link-local, and IPv4-mapped IPv6 addresses - Redirect Validation — Manual redirect following (max 5 hops) with SSRF check on every hop to prevent redirect-based bypass
- URL Validation — Protocol whitelist (http/https only) via Zod
.url()+.refine();file:,data:,javascript:, etc. are rejected - Response Validation — SearXNG API responses validated with Zod runtime schemas via
.safeParse() - Content-Type Whitelist — Only
text/html,application/xhtml+xml,application/xmlare processed - Input Validation — Query length limit (2000 chars), regex validation for categories and language parameters
- Dangerous Element Removal — Strips
<script>,<iframe>,<object>,<embed>,<applet>,<form>,<input>,<base>,<meta>,<svg>from fetched content - Error Sanitization — Generic user-facing errors; detailed information logged to stderr only
- Shutdown Timeout — 5-second fallback on graceful shutdown to prevent process hanging
Project Structure
searxng-mcp/
├── src/
│ ├── index.ts # Entry point (stdio transport + graceful shutdown)
│ ├── server.ts # McpServer + tool registration (web_search, web_fetch)
│ ├── searxng-client.ts # SearXNG JSON API client + result formatting
│ ├── web-fetcher.ts # URL fetch + HTML→Markdown (Readability + Turndown)
│ ├── types.ts # TypeScript interfaces
│ └── constants.ts # Configuration constants (URLs, timeouts, defaults)
├── package.json
├── tsconfig.json
└── .gitignoreDevelopment
git clone https://github.com/voidog/searxng-mcp.git
cd searxng-mcp
npm install
npm run build
npm run typecheck
npm test