Atlas / MCP servers / ihor-sokoliuk / mcp-searxng

mcp-searxngSAFE

mcp/ihor-sokoliuk/mcp-searxng

Private web search for AI assistants via SearXNG — supports Claude, Cursor, and any MCP client

Verdict
SAFE
Grade
B
Trust score
86 /100
Exposed tools
6 6r · 0w · 0d
Transport
stdio · streamable-http
License
MIT
Stars
1,284
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Privacy-respecting web search for AI assistants — use an operator-controlled or trusted SearXNG instance with Claude, Cursor, and more.

[](https://github.com/ihor-sokoliuk/mcp-searxng/stargazers) [](https://www.npmjs.com/package/mcp-searxng) [](https://www.npmjs.com/package/mcp-searxng) [](https://hub.docker.com/r/isokoliuk/mcp-searxng) [](LICENSE) [](https://scorecard.dev/viewer/?uri=github.com/ihor-sokoliuk/mcp-searxng) [](https://www.bestpractices.dev/projects/13143) [](https://glama.ai/mcp/servers/ihor-sokoliuk/mcp-searxng) [](https://github.com/mcp/ihor-sokoliuk/mcp-searxng)

An MCP server that integrates the SearXNG API, giving AI assistants web search capabilities.

✨ Featured in the GitHub MCP Registry.

Quick Start

You need an existing SearXNG instance with JSON search enabled. This project connects an MCP client to SearXNG; it does not install SearXNG. Use an instance you operate or

Read from source at commit 5f7e4e66dc6cOBSERVED · 2026-10-07
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (npm)
claude mcp add mcp-searxng --env SEARXNG_URL=${SEARXNG_URL} --env AUTH_USERNAME=${AUTH_USERNAME} --env AUTH_PASSWORD=${AUTH_PASSWORD} -- npx -y [email protected]
03

Exposed tools (6)

6 read · 0 write · 0 destructive.

ToolRiskDescription
header_proberead
searxng_instance_inforeadDiscovers capabilities from all reachable configured SearXNG instances via /config, including categories.common/available, engines.common/available, defaults, locales, and plugins.
searxng_search_suggestionsreadReturns autocomplete suggestions from the configured SearXNG instance.
searxng_web_searchreadSearches the web using SearXNG and returns a list of results, each with a title, URL, and content snippet.
slowread
web_url_readreadFetches a URL and returns readable content as markdown.
04

Trust audit

SAFEgrade B · trust 86/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
not all pinned
Secrets in source
none-found

Findings (24)

MEDIUMObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
scripts/verify-packed-consumer.mjs:171
'JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDA
LOWInventory / provenance · inv.hidden_file · CWE-1104
.env.e2e.example
.env.e2e.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
__tests__/e2e/http-transport.e2e.ts:9
import { packageVersion } from '../../src/version.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
__tests__/fuzz/search-params.fuzz.ts:4
import { isWebUrlReadArgs } from "../../src/index.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
__tests__/fuzz/search-params.fuzz.ts:5
import { isSearXNGWebSearchArgs } from "../../src/types.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
__tests__/helpers/mock-fetch.ts:7
import { searchCache } from '../../src/search-cache.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
__tests__/helpers/mock-fetch.ts:8
import { setSearxngFetchForTesting } from '../../src/proxy.js';
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
CHANGELOG.md:381
- **DNS-resolved private-address SSRF in `web_url_read` blocked (GHSA-mrvx-jmjw-vggc):** The URL reader previously validated only the literal hostname string, so a public-looking hostname that DNS-res
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
__tests__/unit/url-reader.test.ts:2371
'metadata.example': [{ address: '169.254.169.254', family: 4 }],
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
__tests__/unit/url-security.test.ts:65
assert.equal(isPrivateIpv4('169.254.169.254'), true);
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
__tests__/unit/url-security.test.ts:95
'0.0.0.0', '10.0.0.1', '100.64.0.1', '127.0.0.1', '169.254.169.254',
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
CONFIGURATION.md:488
Every present `Origin` on `/mcp` is validated in all modes; an absent `Origin` remains valid for non-browser clients. In non-hardened mode, an unset `MCP_HTTP_ALLOWED_ORIGINS` defaults to the exact HT
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
SECURITY.md:217
When an `/mcp` request includes an `Origin`, the server validates it against the applicable allowlist in hardened and non-hardened modes; requests without `Origin` follow the accepted non-browser path
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
__tests__/e2e/browser-solver.e2e.ts:38
url: `http://127.0.0.1:${address.port}`,
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
__tests__/e2e/helpers/spawn-server.ts:120
SEARXNG_URL: 'http://127.0.0.1:1',
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
__tests__/e2e/helpers/spawn-server.ts:252
return { child, url: new URL(`http://127.0.0.1:${port}/mcp`), output, close: createChildCloser(child, output) };
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
__tests__/helpers/pdf-fixtures.ts:49
"JVBERi0xLjMKJeLjz9MKMSAwIG9iago8PAovUHJvZHVjZXIgPDM1YzY5Y2I1ZTA+Cj4+CmVuZG9iagoyIDAgb2JqCjw8Ci9UeXBlIC9QYWdlcwovQ291bnQgMQovS2lkcyBbIDQgMCBSIF0KPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1R5cGUgL0NhdGFsb2cKL1BhZ2V
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@types/cors, @types/express, cors, express, node-html-markdown, @types/supertest, cross-env, shx
Why it matters. 8 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:37
- Add opt-in idle expiry for legacy stateful HTTP sessions with `MCP_HTTP_SESSION_IDLE_TTL_MS` (default `0`, disabled). Expiry uses monotonic activity, protects initialization and active POST work, co
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:147
- **Modern MCP protocol serving with the official split SDK v2 packages:** HTTP and STDIO now support the modern `2026-07-28` protocol while retaining the documented legacy transports, tool and resour
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:161
- **Bounded SearXNG response-body consumption:** Search JSON and HTML fallback, `/config`, and suggestions now share a streaming response reader with a configurable `SEARXNG_MAX_RESPONSE_BYTES` ceilin
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CHANGELOG.md:260
- **Established HTTP sessions now receive the configured session rate limit:** Each `POST /mcp` request now passes through exactly one limiter. Requests with a currently live `mcp-session-id` use the
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
CONFIGURATION.md:400
In stateless mode, every POST creates a fresh MCP server and transport, ignores incoming `mcp-session-id` headers, and never emits a response session ID. A POST can return negotiated JSON or an SSE st
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/browser-solver-deployment.md:262
Read logs privately and redact credentials, cookies, target query strings and
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 5f7e4e66dc6cfull audit observations/trust-audit/mcp-server/ihor-sokoliuk__mcp-searxng.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-075f7e4e66dc6cSAFEB86first audit
06

Questions

What is the mcp-searxng MCP server?

Private web search for AI assistants via SearXNG — supports Claude, Cursor, and any MCP client

What tools does mcp-searxng expose?

6 in total: 6 read-only, 0 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is mcp-searxng safe to connect to an agent?

The audit found nothing in the source that contradicts what it says it does, and graded it B (86/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B.

What credentials does mcp-searxng need?

It reads AUTH_PASSWORD, AUTH_USERNAME, MCP_HTTP_AUTH_MODE, MCP_HTTP_AUTH_TOKEN, MCP_HTTP_OAUTH_ISSUER, MCP_HTTP_OAUTH_SCOPES and SEARXNG_URL from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does mcp-searxng run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as mcp-searxng at 2.5.1.

How current is this page?

The grade is for one exact copy of the source (5f7e4e66dc6c), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement