MCP-WebSearch-SearXNG
Permite que seu modelo (ou agente autônomo) navegue na web, execute pesquisas em vários mecanismos ao mesmo tempo e exiba imagens diretamente no seu front-end.
Documentação
WebSearch SearXNG + Servidor MCP
Um mecanismo de metapesquisa SearXNG auto-hospedado emparelhado com o servidor MCP mcp-searxng, construído para LLMs, agentes e aplicações que usam ferramentas. Permite que seu modelo (ou agente autônomo) navegue na web, execute buscas em vários mecanismos ao mesmo tempo e exiba imagens diretamente no seu front end. Tudo roda inteiramente na sua própria máquina via Docker, acessado pelo seu navegador, e fala MCP sobre transporte HTTP Streamable, então se conecta a qualquer cliente compatível com MCP (Claude Desktop, Cline, Open WebUI, LM Studio, estruturas de agentes personalizadas, etc.). Aprimorado com busca de imagens/vídeos/categorias, paginação por deslocamento e redimensionamento inteligente de imagens base64 para modelos com capacidade de visão. Ambos os serviços permanecem na sua rede local, então nada sai da sua máquina a menos que você peça. Sem anúncios, sem telemetria, sem rastreadores de terceiros, sem contas — o frontend do SearXNG é privado por design e os patches MCP não adicionam nenhum phone-home próprio.
Instalação
Nota rápida sobre privacidade antes de começar. Esta pilha roda inteiramente na sua máquina e respeita a privacidade por design (sem telemetria, sem contas, sem rastreadores de terceiros), mas os padrões são ajustados para "simplesmente funcionar", não para máxima privacidade. Antes de expor além do seu próprio computador, para sua LAN, internet ou qualquer outra pessoa, leia ADVANCED.md
Pré-requisitos
- Docker e Docker Compose devem estar instalados (Node.js não é necessário no host: o servidor MCP roda dentro da sua imagem Docker)
Passo 1: Clonar o Repositório
git clone https://github.com/hypersniper05/MCP-WebSearch-SearXNG.git
cd MCP-WebSearch-SearXNG
Isso fornece o docker-compose.yml, o settings.yml do SearXNG, os patches MCP e o Dockerfile personalizado já organizados — então o próximo passo é direto para a configuração.
Prefere configurar tudo manualmente em vez de clonar? Veja Construindo do zero (sem clonar) em ADVANCED.md.
Passo 2: Configurar as Configurações do SearXNG
O searxng/config/settings.yml incluído já está pré-configurado para esta pilha — saída JSON habilitada, limitador de taxa desativado, um conjunto selecionado de mecanismos que respondem a instâncias auto-hospedadas e longos tempos de suspensão de mecanismos para que um mecanismo bloqueado não seja tentado novamente a cada consulta. Ele contém apenas substituições: o SearXNG mescla isso sobre as configurações padrão dentro da imagem (fixada). A única coisa que você precisa definir é a chave secreta.
Quer mudar quais mecanismos estão habilitados, o tempo limite de solicitação ou qualquer outro padrão do SearXNG? Veja Modificando as configurações padrão em ADVANCED.md.
Definir o secret_key (ou usar a variável de ambiente)
O SearXNG iniciará sem uma chave, então para uma instância pessoal somente localhost você pode voltar a isso mais tarde. Mas se você vincular a 0.0.0.0, expor isso à sua LAN ou compartilhar com qualquer pessoa, defina uma chave real — caso contrário, qualquer pessoa pode forjar o HMAC que o endpoint /image_proxy do SearXNG verifica e usar sua instância como um proxy de imagem aberto.
Defina em um arquivo .env ao lado de docker-compose.yml:
SEARXNG_SECRET=<paste your generated 64-char hex string here>
docker-compose.yml sempre passa SEARXNG_SECRET para o contêiner, e o SearXNG permite que essa variável substitua settings.yml mesmo quando vazia. Portanto, o espaço reservado secret_key: "CHANGE_ME_BEFORE_RUNNING" em settings.yml nunca é usado, e editá-lo não tem efeito — sem um valor .env, a instância roda com uma chave vazia. Use .env (está no gitignore, então a chave nunca chega ao repositório).
Gere uma chave com qualquer ferramenta que você tiver instalada:
# PowerShell (Windows PowerShell 5.1 and PowerShell 7 — built in)
$b = New-Object byte[] 32; [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($b); -join ($b | ForEach-Object { $_.ToString('x2') })
# Node.js (if you have it)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Docker (works anywhere this stack does)
docker run --rm alpine sh -c "apk add --no-cache openssl > /dev/null && openssl rand -hex 32"
# Git Bash / Linux / macOS
openssl rand -hex 32
# Python
python -c "import secrets; print(secrets.token_hex(32))"
Para o restante das compensações de privacidade/endurecimento (exposição LAN, autenticação MCP, roteamento Tor), veja ADVANCED.md.
Passo 3: Construir e Iniciar Tudo
docker compose build
docker compose up -d
Passo 4: Verificar Serviços
Verificação de saúde:
curl -s http://localhost:3001/health
Esperado: {"status":"healthy","server":"ihor-sokoliuk/mcp-searxng","version":"2.4.0-enhanced","transport":"http"}
Busca de teste:
curl -s "http://localhost:8888/search?q=test&format=json" | head -c 200
Passo 5 (somente se acessar de outra máquina): Abrir os vínculos para sua LAN / Tailscale
Por padrão, o docker-compose.yml incluído vincula o SearXNG a 127.0.0.1 (somente esta máquina) e o servidor MCP a 0.0.0.0 (já acessível da sua LAN / tailnet Tailscale). Ambos vêm de .env: SEARXNG_BIND (padrão 127.0.0.1) e MCP_BIND (padrão 0.0.0.0).
Diagnóstico rápido para identificar isso:
docker compose ps
Observe a coluna PORTS. Se você vir:
| O que você vê | O que significa |
|---|---|
0.0.0.0:8888->8080/tcp | Acessível de qualquer lugar na rede ✓ |
127.0.0.1:8888->8080/tcp | Somente localhost — o exato sintoma que faz o acesso externo "expirar" |
Se uma linha mostrar 127.0.0.1: e você precisar que seja acessível fora do host, defina o vínculo em .env (ao lado de docker-compose.yml). Não edite docker-compose.yml em si: .env está no gitignore, então git pull nunca conflita com sua escolha.
SEARXNG_BIND=0.0.0.0 # default 127.0.0.1
MCP_BIND=0.0.0.0 # already the default; 127.0.0.1 keeps the MCP endpoint on this machine
Em seguida, recrie os contêineres (mudanças de porta não se aplicam em um simples restart):
docker compose down
docker compose up -d
docker compose ps
As linhas alteradas agora devem mostrar 0.0.0.0:....
Se docker compose ps já mostra 0.0.0.0 e o acesso externo ainda falha, é o firewall do sistema operacional. No Windows, permita as portas de um PowerShell administrativo:
New-NetFirewallRule -DisplayName "MCP SearXNG (8888)" -Direction Inbound -Protocol TCP -LocalPort 8888 -Action Allow
New-NetFirewallRule -DisplayName "MCP Server (3001)" -Direction Inbound -Protocol TCP -LocalPort 3001 -Action Allow
Clientes MCP baseados em navegador (qualquer coisa que envie um cabeçalho Origin, como uma interface web ou o MCP Inspector) são recusados com HTTP 403, a menos que sua origem esteja listada. Adicione as origens exatas, com esquema e porta, a .env, por exemplo, MCP_ALLOWED_ORIGINS=http://localhost:3001,http://100.x.y.z:3001. A lista substitui o padrão localhost, então inclua-os também se precisar. Clientes que não enviam Origin (Claude Code, clientes SDK, LM Studio, curl) não são afetados.
Nota de segurança:
0.0.0.0expõe um serviço a qualquer pessoa que possa alcançar sua máquina nessa porta, e o servidor MCP está vinculado a0.0.0.0por padrão (definaMCP_BIND=127.0.0.1em.envpara mantê-lo local). O servidor MCP não tem autenticação por padrão. O upstream pode exigir um token bearer estático em seu modo endurecido, ou tokens de acesso OAuth; se você for além de uma rede doméstica/Tailscale confiável, leia ADVANCED.md → Nível 2.
Resumo de Endpoints
| Serviço | URL | Propósito |
|---|---|---|
| Interface SearXNG | http://localhost:8888 | Interface de busca web |
| API SearXNG | http://localhost:8888/search | API de busca JSON |
| Servidor MCP | http://localhost:3001/mcp | MCP Streamable HTTP |
| Saúde MCP | http://localhost:3001/health | Endpoint de verificação de saúde |
Precisa de TLS para um cliente somente HTTPS? O caminho mais limpo é Tailscale Serve se ambas as extremidades estiverem em uma tailnet (certificado real confiável pela Let's Encrypt, zero configuração por cliente), ou um proxy reverso como Caddy / nginx com seu próprio certificado caso contrário. Qualquer um é adicionado na frente do endpoint MCP HTTP existente sem nenhuma alteração nesta pilha.
Ferramentas MCP
1. searxng_web_search
Busca web com suporte a categoria, paginação e filtragem. Retorna JSON estruturado: results (título, url, descrição, data de publicação, fonte engines, score), suggestions, corrections, answers, infoboxes, unresponsive_engines, engine_coverage (answered mecanismos e failed_count) e pagination.
Separe consultas com | para executar várias buscas em uma única chamada ("CFM LEAP engine | A320neo sharklet") — até 10, duas por vez.
| Parâmetro | Tipo | Descrição |
|---|---|---|
query | string | Consulta de busca (obrigatório). Operadores: "exact phrase", site:, filetype:, +required -excluded, OR |
categories | string | general (padrão), images, videos, news, science, music, files (torrents), it (sites de desenvolvedores/TI), social media; separados por vírgula para vários |
max_results | número | Resultados por chamada, 1-50 (padrão: 20 gerais/notícias, 10 imagens/vídeos) |
offset | número | Pular N resultados para paginação (ex.: 10 para resultados 11-20) |
pageno | número | Número da página do SearXNG (um novo lote dos mecanismos) |
time_range | string | day, week, month, year |
language | string | Código de idioma (ex.: en, fr); all = sem filtro (padrão) |
safesearch | número | 0 (nenhum, padrão), 1 (moderado), 2 (estrito) |
engines | string | Nomes de mecanismos separados por vírgula para usar em vez dos mecanismos da categoria (ex.: bing,yahoo) |
min_score | número | Descarta resultados abaixo desta pontuação de relevância (0.0-1.0) |
Argumentos opcionais podem ser null ou ""; eles são tratados como não definidos.
2. web_url_read
Lê páginas web (como markdown), PDFs (até 16 MB) e imagens. URLs de imagens são detectadas automaticamente e retornadas como blocos de imagem base64 redimensionados.
| Parâmetro | Tipo | Descrição |
|---|---|---|
url | string | URL para ler (obrigatório) |
detail | string | Nível de redimensionamento de imagem: low (448px, ~256 tokens), medium (768px, ~756 tokens, padrão), high (1280px, ~2048 tokens) |
startChar | number | Deslocamento de caractere para paginação de texto |
maxLength | number | Máximo de caracteres a retornar |
section | string | Extrair conteúdo sob um título |
paragraphRange | string | Intervalo de parágrafos (ex.: 1-5) |
readHeadings | boolean | Retornar apenas títulos |
web_url_read recusa endereços privados — localhost, LAN (RFC1918), Tailscale (100.64.0.0/10), link-local e nomes de host Docker — na primeira solicitação e em cada redirecionamento. Defina MCP_HTTP_ALLOW_PRIVATE_URLS=true no serviço mcp-searxng somente se quiser que ele leia serviços internos.
3. searxng_instance_info e searxng_search_suggestions
Do upstream. searxng_instance_info lista as categorias e mecanismos da instância. searxng_search_suggestions não retorna sugestões de consulta aqui, porque o autocompletar está desativado no settings.yml (a interface web, caso contrário, enviaria cada tecla pressionada a um serviço de sugestão de terceiros). Ele apenas completa os prefixos !bang do SearXNG, ex.: !bi → !bing.
Fluxo de Pesquisa de Imagens
searxng_web_search({query: "sunset", categories: "images"})-> retorna URLs de imagens + metadados- Escolha uma imagem ->
web_url_read({url: "https://example.com/sunset.jpg", detail: "medium"})-> retorna imagem base64 redimensionada - Para ver mais resultados ->
searxng_web_search({query: "sunset", categories: "images", offset: 10})-> resultados 11-20
Imagens SVG são renderizadas como PNG. Imagens acima de 100 megapixels são recusadas, e no máximo dois redimensionamentos raster e duas renderizações SVG são executados por vez (imagens JPEG/PNG/GIF/WebP pequenas que não precisam de redimensionamento passam direto).
Arquivos de Patch Personalizados
O servidor MCP é o upstream mcp-searxng 2.4.0 com alguns arquivos montados somente leitura sobre sua pasta dist/. Todos os outros arquivos upstream (incluindo sua segurança de URL, segurança HTTP e leitura de PDF) são executados sem modificação.
| Arquivo | Propósito |
|---|---|
Dockerfile | isokoliuk/mcp-searxng:2.4.0 upstream + sharp (redimensionamento de imagem) + fontes DejaVu (texto em SVGs) |
index.js | Arquivo upstream com pequenas edições marcadas como // ENHANCED: — roteia pesquisas e leituras de imagem para os módulos abaixo |
version.js | Relata 2.4.0-enhanced |
enhanced-search.js | Saída JSON estruturada, ` |
image-reader.js | Busca de imagens (com a proteção SSRF do upstream), redimensionamento sharp com os 3 presets de detalhe, renderização SVG em um processo filho com limite de memória e tempo |
Atualizando o SearXNG
O SearXNG está fixado em uma tag datada em docker-compose.yml (atualmente 2026.9.23-3cd69d30e). settings.yml contém apenas substituições sobre as configurações padrão dentro da imagem, então uma nova imagem pode silenciosamente habilitar, desabilitar ou remover mecanismos — por isso as atualizações são um aumento deliberado de tag em vez de um pull de :latest.
# 1. Edit docker-compose.yml: set the new tag from https://hub.docker.com/r/searxng/searxng/tags
docker compose up -d searxng # pulls the tag, recreates the container
docker compose logs searxng --tail 100 # look for "can't register engine" (unknown settings keys are mostly ignored silently)
curl.exe -s http://localhost:8888/config > config-new.json # compare categories/engines with the old version
curl.exe -s http://localhost:8888/stats/errors # after a few searches: which engines fail
Compare também a lista plugins: em settings.yml com o /usr/local/searxng/searx/settings.yml da própria imagem: a sobreposição substitui a lista completa de plugins, então um novo plugin upstream não é carregado até que você o adicione. O SearXNG não publica releases no GitHub; a parte após a data em uma tag é um hash de commit, então revise as alterações entre as duas tags em https://github.com/searxng/searxng/compare/3cd69d30e...<new-hash>. Para reverter, defina a tag antiga novamente.
Um meio-termo razoável para se manter atualizado: agende um trabalho semanal que verifique no Docker Hub se há uma tag mais recente e o reporte, mas não a aplique.
Atualizando o servidor MCP
mcp-searxng é construído localmente a partir de mcp-searxng-patches/Dockerfile, que está fixado em isokoliuk/mcp-searxng:2.4.0. Após puxar este repositório em outra máquina, ou após alterar o Dockerfile:
docker compose build mcp-searxng
docker compose up -d --force-recreate mcp-searxng
curl -s http://localhost:3001/health # version must be 2.4.0-enhanced
--force-recreate não é opcional. Um docker compose up -d simples reconstrói a imagem, mas deixa o contêiner existente em execução na imagem antiga, então a atualização silenciosamente não faz nada. Confirme que o contêiner está na imagem recém-construída — esses dois IDs devem corresponder:
docker inspect mcp-searxng --format '{{.Image}}' && docker images --no-trunc --format '{{.ID}}' mcp-searxng-enhanced:latest
Para mover para uma versão upstream mais recente: aumente a tag FROM, copie os novos dist/index.js e dist/version.js da imagem (docker run --rm --entrypoint cat isokoliuk/mcp-searxng:<tag> /app/dist/index.js), reaplique as edições // ENHANCED: e reconstrua. enhanced-search.js e image-reader.js importam módulos upstream, então verifique-os quanto a exports renomeados.
Testado Com
- Qwen3.6 35B A3B — executa tanto
searxng_web_search(incluindo multi-consulta e filtros de categoria) quantoweb_url_read(modos texto + imagem) de forma confiável. Seleção de ferramentas, inferência de parâmetros e interpretação de resultados funcionam bem com este modelo.
Notas
- O servidor MCP usa transporte HTTP Streamable (não stdio ou somente SSE)
- O SearXNG se conecta internamente via nome de host Docker
searxng:8080 - Nenhuma chave de API externa necessária. As consultas vão do seu IP para os mecanismos de busca; um mecanismo, findborg, é um proxy sem chave de terceiros do índice do Brave (desative-o em
settings.ymlse não quiser isso). - Os patches personalizados são licenciados sob MIT e não adicionam telemetria. Seu único acesso a processos/arquivos:
image-reader.jsinicia seu renderizador SVG através de/bin/sh -c 'ulimit -v … && exec node …'(com um ambiente vazio) e escreve o/proc/<pid>/oom_score_adjdesse filho - Mecanismos de busca (web geral): Bing, Yahoo, DuckDuckGo (via seu endpoint web), Google (via um endpoint Custom Search sem chave), Yandex, Keenable, Swisscows, mwmbl e findborg, além de infoboxes da Wikipedia. Normalmente 6-8 deles respondem a cada consulta, e resultados que vários mecanismos concordam são classificados primeiro.
- Se os resultados parecerem escassos, verifique seu IP de saída primeiro. Brave (HTTP 429), o endpoint html do DuckDuckGo, Google web, Qwant web/imagens e GMX (CAPTCHA), e Yep (HTTP 403) rejeitam instâncias auto-hospedadas em endereços compartilhados ou sinalizados — saídas de VPN, CGNAT e faixas de datacenter são as causas comuns. Eles falham na primeira consulta de um contêiner frio, então não é um problema de limite de taxa que você pode ajustar, e eles estão desabilitados na configuração enviada. Startpage também está desligado: seu desafio de prova de trabalho fica mais difícil para seu IP após uma consulta. (Qwant News e Qwant Videos ainda respondem e permanecem habilitados.) Verifique o que o SearXNG relata:
Opções, aproximadamente em ordem de esforço: pesquise de um IP residencial sem VPN, coloque as solicitações de saída atrás de proxies (curl -s "http://localhost:8888/search?q=test&format=json" | jq .unresponsive_engines curl -s http://localhost:8888/stats/errorsoutgoing.proxiesemsearxng/config/settings.yml), ou forneça uma chave de API para um mecanismo que venda uma (braveapi). Habilitar mais mecanismos bloqueados não ajuda. - Algumas falhas são normais e autolimitadas: Swisscows recusa algumas consultas com HTTP 450 ("Unavailable For Legal Reasons"), Yahoo recusa rajadas de consultas por um curto período, e o endpoint Custom Search do Google responde "unusual traffic from your network" quando seu IP de saída está sinalizado, às vezes na primeira consulta. O SearXNG suspende o mecanismo (15 minutos para o Google) e os outros carregam a pesquisa.