All environment variables for mcp-searxng, organized by concern. All variables are optional unless marked required.
| Variable | Required | Default | Description |
|---|---|---|---|
SEARXNG_URL |
Yes | — | URL of your SearXNG instance. Format: <protocol>://<hostname>[:<port>] (e.g. http://localhost:8080) |
| Variable | Required | Default | Description |
|---|---|---|---|
AUTH_USERNAME |
No | — | HTTP Basic Auth username for password-protected SearXNG instances |
AUTH_PASSWORD |
No | — | HTTP Basic Auth password for password-protected SearXNG instances |
| Variable | Required | Default | Description |
|---|---|---|---|
SEARXNG_TIMEOUT_MS |
No | 10000 |
Maximum time in milliseconds to wait for a SearXNG search response. The request is aborted and a network error is returned if the server does not respond within this window. |
FETCH_TIMEOUT_MS |
No | 10000 |
Maximum time in milliseconds to wait for a web_url_read fetch. The request is aborted and an error is returned if the server does not respond within this window. |
| Variable | Required | Default | Description |
|---|---|---|---|
SEARXNG_LITE_TOOLS |
No | false |
Set to true to register minimal tool schemas with only query / url parameters. Reduces per-call token overhead for local models with small context windows. Extra parameters (e.g. language, maxLength) passed by the caller are still accepted and forwarded. |
Operator-level defaults applied when the caller omits the corresponding per-call parameter.
| Variable | Required | Default | Description |
|---|---|---|---|
SEARXNG_DEFAULT_LANGUAGE |
No | all |
Default language for all searches when language is not passed per call (e.g. en, fr, de). |
SEARXNG_DEFAULT_SAFESEARCH |
No | — | Default safe-search level: 0 (off), 1 (moderate), 2 (strict). Invalid values are ignored with a warning. When unset, the SearXNG instance default applies. |
| Variable | Required | Default | Description |
|---|---|---|---|
SEARXNG_MAX_RESULTS |
No | — | Operator-level maximum number of search results to return per call (1-20). Invalid values are ignored. Recommended: 10 for smaller context windows. |
SEARXNG_MAX_RESULT_CHARS |
No | — | Maximum characters to include in each search result snippet. Longer snippets are truncated and marked with …. Invalid values are ignored. Recommended: 500 for smaller context windows. |
Self-hosting SearXNG with JSON output enabled remains the recommended setup. The HTML fallback is best-effort for public instances that reject format=json; HTML theme differences may limit parsed metadata.
| Variable | Required | Default | Description |
|---|---|---|---|
SEARXNG_HTML_FALLBACK |
No | false |
Set to true to retry 403/404 or non-JSON search responses as an HTML search page and parse title, URL, and snippet only. HTML fallback results are marked with sourceFormat: "html" in JSON output. |
| Variable | Required | Default | Description |
|---|---|---|---|
URL_READ_MAX_CHARS |
No | — | Default maximum characters returned by web_url_read when the caller omits maxLength. Explicit maxLength always wins. Invalid values are ignored. |
URL_READ_MAX_CONTENT_LENGTH_BYTES |
No | 5242880 |
Maximum decompressed response-body bytes web_url_read will read while streaming a page. A HEAD Content-Length preflight may reject oversized pages before GET, but the streaming cap is authoritative. Invalid values fall back to the default. |
CACHE_TTL_MS |
No | 86400000 |
URL cache TTL in milliseconds. Invalid or non-positive values fall back to the default (24 hours). |
CACHE_MAX_ENTRIES |
No | 500 |
Maximum number of cached URLs. When the cache exceeds this size, the least frequently used entry is evicted, with oldest entry used as the tie-breaker. Invalid or non-positive values fall back to the default. |
| Variable | Required | Default | Description |
|---|---|---|---|
USER_AGENT |
No | — | Global User-Agent header for all outgoing requests (e.g. MyBot/1.0) |
URL_READER_USER_AGENT |
No | — | User-Agent for web_url_read only — overrides USER_AGENT for URL reads |
Interface-specific proxies take priority over global proxies for their respective tools.
| Variable | Required | Default | Description |
|---|---|---|---|
HTTP_PROXY / HTTPS_PROXY |
No | — | Global proxy for all traffic. Format: http://[user:pass@]host:port |
SEARCH_HTTP_PROXY / SEARCH_HTTPS_PROXY |
No | — | Proxy for searxng_web_search only |
URL_READER_HTTP_PROXY / URL_READER_HTTPS_PROXY |
No | — | Proxy for web_url_read only |
NO_PROXY |
No | — | Comma-separated bypass list (e.g. localhost,.internal,example.com) |
By default the server communicates over STDIO. Set MCP_HTTP_PORT to enable HTTP mode instead.
| Variable | Required | Default | Description |
|---|---|---|---|
MCP_HTTP_PORT |
No | — | Port number to enable HTTP transport (e.g. 3000) |
MCP_HTTP_HOST |
No | 127.0.0.1 |
Interface address to bind to. Defaults to localhost-only for security. Set 0.0.0.0 for all interfaces (required for Docker and remote deployments), or a specific IP. Breaking change from v1.2.1: previous default was 0.0.0.0. |
HTTP endpoints (when HTTP mode is active):
POST/GET/DELETE /mcp— MCP protocolGET /health— health check
Rate limiting is always active in HTTP mode to prevent resource exhaustion. Two separate limits protect different request types.
| Variable | Required | Default | Description |
|---|---|---|---|
MCP_RATE_WINDOW_MS |
No | 60000 |
Sliding window duration in milliseconds for all rate limits |
MCP_RATE_INIT_MAX |
No | 20 |
Max POST /mcp requests per window (applied to all POSTs, guards against session-init flooding) |
MCP_RATE_SESSION_MAX |
No | 300 |
Max GET/DELETE /mcp requests per window (per-session calls; intentionally generous for AI agents) |
Requests exceeding a limit receive HTTP 429 with a JSON-RPC error body (code: -32029). /health has a fixed limit of 60 requests per minute. Standard RateLimit-* headers are included on all responses.
The in-memory store is per-process; for horizontally scaled deployments replace it with a shared Redis store via express-rate-limit's store option.
Opt-in security layer for when you expose the HTTP transport on a network. Default HTTP behavior is unchanged — hardening must be explicitly enabled with MCP_HTTP_HARDEN=true.
| Variable | Required | Default | Description |
|---|---|---|---|
MCP_HTTP_HARDEN |
No | false |
Set to true to enable all hardening features |
MCP_HTTP_AUTH_TOKEN |
No | — | Required bearer token for all HTTP requests in hardened mode |
MCP_HTTP_ALLOWED_ORIGINS |
No | — | Comma-separated CORS origin allowlist (e.g. https://app.example.com) |
MCP_HTTP_ALLOWED_HOSTS |
No | — | Comma-separated DNS rebinding protection allowlist override |
MCP_HTTP_ALLOW_PRIVATE_URLS |
No | false |
Allow web_url_read to fetch internal/private URLs, including hostnames that DNS-resolve to private/internal addresses. Private URL reads are blocked by default in all modes. |
MCP_HTTP_EXPOSE_FULL_CONFIG |
No | false |
Expose full config details in /health response (for debugging) |
web_url_read blocks private/internal URLs by default in all transport modes. This includes localhost, loopback addresses, private IPv4 ranges, link-local addresses, 0.0.0.0/8, IPv6 loopback/ULA/link-local addresses, and IPv4-mapped IPv6 private addresses.
Redirects are also checked before they are followed. A public URL that redirects to a private/internal URL is blocked.
For direct URL-reader requests without a proxy, DNS answers are validated before connecting. A public-looking hostname that resolves to a private/internal address is blocked, and the connection is pinned to the validated DNS answer to prevent DNS rebinding between validation and connection.
When a URL-reader proxy is configured (URL_READER_HTTP_PROXY, URL_READER_HTTPS_PROXY, HTTP_PROXY, or HTTPS_PROXY), the proxy performs DNS resolution. Client-side DNS-answer validation cannot inspect proxied resolutions, so proxied deployments should rely on proxy, firewall, and egress controls.
URL_READ_MAX_CONTENT_LENGTH_BYTES is enforced while streaming the response body, including chunked responses and responses whose GET body is larger than the HEAD Content-Length value. The limit is measured after transparent response decompression.
Set MCP_HTTP_ALLOW_PRIVATE_URLS=true only when internal URL reads are intentional for your deployment. This also allows hostnames that DNS-resolve to private/internal addresses.
Complete MCP client configuration with every variable. Mix and match as needed — all optional variables can be used independently or together.
{
"mcpServers": {
"searxng": {
"command": "npx",
"args": ["-y", "mcp-searxng"],
"env": {
"SEARXNG_URL": "YOUR_SEARXNG_INSTANCE_URL",
"SEARXNG_TIMEOUT_MS": "10000",
"FETCH_TIMEOUT_MS": "10000",
"SEARXNG_LITE_TOOLS": "false",
"SEARXNG_DEFAULT_LANGUAGE": "en",
"SEARXNG_DEFAULT_SAFESEARCH": "0",
"SEARXNG_MAX_RESULTS": "10",
"SEARXNG_MAX_RESULT_CHARS": "500",
"SEARXNG_HTML_FALLBACK": "false",
"URL_READ_MAX_CHARS": "2000",
"URL_READ_MAX_CONTENT_LENGTH_BYTES": "5242880",
"CACHE_TTL_MS": "86400000",
"CACHE_MAX_ENTRIES": "500",
"AUTH_USERNAME": "your_username",
"AUTH_PASSWORD": "your_password",
"USER_AGENT": "MyBot/1.0",
"URL_READER_USER_AGENT": "Mozilla/5.0 (compatible; MyBot/1.0)",
"SEARCH_HTTP_PROXY": "http://search-proxy.company.com:8080",
"SEARCH_HTTPS_PROXY": "http://search-proxy.company.com:8080",
"URL_READER_HTTP_PROXY": "http://reader-proxy.company.com:8080",
"URL_READER_HTTPS_PROXY": "http://reader-proxy.company.com:8080",
"HTTP_PROXY": "http://global-proxy.company.com:8080",
"HTTPS_PROXY": "http://global-proxy.company.com:8080",
"NO_PROXY": "localhost,127.0.0.1,.local,.internal",
"MCP_HTTP_PORT": "3000",
"MCP_HTTP_HOST": "0.0.0.0",
"MCP_HTTP_HARDEN": "true",
"MCP_HTTP_AUTH_TOKEN": "replace-me",
"MCP_HTTP_ALLOWED_ORIGINS": "https://app.example.com",
"MCP_HTTP_ALLOWED_HOSTS": "app.example.com",
"MCP_HTTP_ALLOW_PRIVATE_URLS": "false",
"MCP_HTTP_EXPOSE_FULL_CONFIG": "false"
}
}
}
}