- Go 99.3%
- Dockerfile 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
Живой прогон (2026-09-26) показал: из рабочей сети Yandex иногда отдаёт страницу без единого
органического результата, при этом маркеры smartcaptcha/«Are you not a robot?» могут отсутствовать —
Classify такой ответ принимает как StatusOK, и yandex.Search возвращал пустой searchResult с nil error.
Оркестратор (internal/handler/search.go) по nil-error записывал провайдера в enginesOk — получалось
ложное «ok» при фактической деградации: три разных запроса подряд давали {"searchResult":[],"enginesOk":["yandex"]}.
Добавлен case len(res)==0 → BlockError{StatusBlocked} в yandex.Search, ровно как уже сделано для
JS-оболочки Google (internal/providers/google.go): честный failure + эскалация cooldown'а через
AsBlockErr в оркестраторе, а не молчаливое пустое «успешное» попадание.
|
||
| cmd/mcp-searxng | ||
| docs | ||
| http | ||
| internal | ||
| .dockerignore | ||
| .gitignore | ||
| .woodpecker.yml | ||
| AGENTS.md | ||
| bugs.txt | ||
| config.example.yml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
MCP SearXNG
MCP (Model Context Protocol) сервер для приватного поиска, извлечения контента и интеллектуального анализа веб-страниц с использованием SearXNG и LLM.
Описание
Этот проект представляет собой сервер Model Context Protocol (MCP), который предоставляет три основных инструмента:
web/search— Приватный поиск в интернете через SearXNG.web/fetch— Получение и очистка содержимого веб-страниц (HTML → Markdown).web/research— Интеллектуальный анализ страницы с помощью LLM (саммаризация, извлечение фактов, перевод).web/deep_research— Генерация нескольких поисковых запросов с помощью LLM, получение найденных релевантных страниц, их интеллектуальный анализ и в конце общий интеллектуальный анализ всех страниц вместе с помощью LLM (саммаризация, извлечение фактов, перевод).
Документация
Подробная документация проекта находится в каталоге docs/:
- Архитектура поиска — пайплайн запроса (кэш → глобальная FIFO-очередь → параллельный fan-out по провайдерам → агрегация), частичные сбои, cooldown заблокированных источников, добавление новых движков.
- Конфигурация — полный справочник флагов и переменных окружения с примерами
.env. - Диагностика — капчи/rate-limit'ы, кэш, очереди, Chromium: симптомы и решения.
- ROADMAP — детальный план развития с отметкой выполненных пунктов.
Особенности
- Приватность: Поиск через SearXNG без трекинга.
- Интеллектуальный анализ: Интеграция с любой OpenAI-compatible LLM (Ollama, vLLM, LM Studio) для глубокого анализа контента.
- Гибкий парсинг: Поддержка легкого режима (
net/http) и тяжелого режима (Chromium/Headless Chrome) для сложных JS-сайтов. - Чистый контент: Автоматическая очистка от рекламы и навигации через
go-readability(отключается параметромclean). - Кэширование: Встроенный in-memory кэш сырых HTML-страниц (TTL по последнему использованию) + отдельный кэш агрегированных ответов поиска (по умолчанию неделя). Очистка просроченных записей — в фоновом режиме.
- Устойчивость к сбоям движков: Поиск идёт параллельно во все включённые провайдеры; сбой или капча одного не роняет ответ (частичные результаты +
enginesOk/engineFailures). Заблокированные источники переводятся в cooldown (15 мин → ×2 до 2 ч), обычные сетевые ошибки — без повторных попыток. - Глобальная FIFO-очередь: Поиск сериализуется одним слотом на процесс, что сглаживает нагрузку и rate-limit'ы; попадание в кэш не занимает очередь.
- Два режима работы: streamable HTTP и stdio — для Claude Desktop, Open WebUI и других MCP-клиентов.
- Graceful Shutdown: Корректное завершение при SIGINT/SIGTERM.
- Наблюдаемость: Встроенные метрики Prometheus для мониторинга производительности.
Установка
- Убедитесь, что у вас установлен Go 1.27.1 или выше.
- Клонируйте репозиторий:
git clone https://git.ymnuktech.ru/ymnuk/mcp-searxng.git
cd mcp-searxng
Установите зависимости:
go mod download
Соберите проект:
bash go build .
Конфигурация
Сервер настраивается через аргументы командной строки или переменные окружения.
| Параметр | Флаг | Переменная окружения | По умолчанию | Описание |
|---|---|---|---|---|
| Mode | --mode |
MODE |
http |
Режим работы: http или stdio |
| Port | -p, --port |
WEB_PORT |
3000 |
Порт для входящих соединений |
| HttpTimeout | --http-timeout |
HTTP_TIMEOUT |
60 |
Таймаут HTTP-запросов (сек) |
| TlsVerify | --tls-verify |
TLS_VERIFY |
true |
Проверка TLS-сертификатов |
| UserAgent | --user-agent |
USER_AGENT |
Mozilla/5.0... |
User Agent для запросов |
| LogLevel | --log-level |
LOG_LEVEL |
info |
Уровень логов: error, warn, info, debug, off (формат JSONL) |
| LogFile | --log-file |
LOG_FILE |
(пусто) | Файл для JSONL-логов; иначе stdout (http) / stderr (stdio) |
| Providers | --providers(повторяемый) |
PROVIDERS |
(пусто — встроенный набор) | Имена провайдеров через запятую; порядок = приоритет дедупликации. Пусто: duckduckgo,bing,baidu,yandex,google с предупреждением в лог |
| ProviderTimeout | --provider-timeout |
PROVIDER_TIMEOUT |
20 |
Таймаут одного запроса к провайдеру (сек) |
| SearchMaxResults | --search-max-results |
SEARCH_MAX_RESULTS |
30 |
Максимум агрегированных результатов в web/search; 0 — без ограничения |
| SearchCacheTTLHours | --search-cache-ttl-hours |
SEARCH_CACHE_TTL_HOURS |
168 |
Время жизни кэша ответов поиска (часы); обновляется при каждом попадании |
| SearXNGUrl | --searxng-url |
SEARXNG_URL |
http://localhost:8099 |
URL собственного экземпляра SearXNG; пусто — этот источник не участвует в поиске |
| SearXNGMinScore | --searxng-min-score |
SEARXNG_MIN_SCORE |
0.8 |
deprecated: фильтр по score теперь опция minScore самого web/search (см. ниже); поле сохранено для совместимости конфига |
| UseChromium | --use-chromium |
USE_CHROMIUM |
false |
Использовать Chromium для рендеринга |
| ChromiumPath | --chromium-path |
CHROMIUM_PATH |
/usr/bin/chromium |
Путь к бинарнику Chromium |
| ChromiumTimeout | --chromium-timeout |
CHROMIUM_TIMEOUT |
30 |
Таймаут Chromium (сек) |
| LLMUrl | --llm-url |
LLM_URL |
(пусто) | URL LLM-сервера (OpenAI-compatible) |
| LLMToken | --llm-token |
LLM_TOKEN |
(пусто) | API Key для LLM |
| LLMModel | --llm-model |
LLM_MODEL |
gpt-4o-mini |
Модель по умолчанию |
| LLMTimeout | --llm-timeout |
LLM_TIMEOUT |
1m |
Таймаут запроса к LLM |
| LLMLang | --llm-lang |
LLM_LANG |
ru |
Язык для LLM |
| CacheDefaultTTL | --cache-ttl |
CACHE_TTL |
24 |
Время жизни кэша страниц (часы) |
| CacheCleanupMinutes | --cache-cleanup |
CACHE_CLEANUP |
10 |
Интервал очистки просроченного кэша (минуты) |
Использование
Базовый запуск (HTTP режим)
./mcp-searxng --searxng-url https://your-searxng-instance.com
Запуск в stdio режиме (для Claude Desktop)
./mcp-searxng --mode=stdio
Запуск с поддержкой Research (LLM) и Chromium
export SEARXNG_URL=http://my-server:8099
export USE_CHROMIUM=true
export CHROMIUM_PATH=/usr/bin/chromium
export LLM_URL=http://localhost:1234/v1
export LLM_MODEL=gemma-4-26b-a4b-it
./mcp-searxng
Инструменты (Tools)
web/search
Поиск информации в интернете: запрос параллельно отправляется во все включённые провайдеры (PROVIDERS, по умолчанию — встроенный набор из пяти движков), результаты агрегируются, дедуплицируются по URL (приоритет = порядок списка) и ограничиваются SEARCH_MAX_RESULTS. Сбой одного провайдера не роняет ответ.
Форма ответа:
searchResult— агрегированные результаты (заголовки, ссылки, сниппеты); сериализуется как[], если ни один движок не отдал данных;enginesOk— имена провайдеров, вернувших результаты;engineFailures—{name,error}по каждому отказавшему/охлаждающемуся провайдеру.
Параметры:
query(required) — поисковый запрос (лишние пробелы нормализуются перед кэшированием и отправкой; регистр сохраняется)provider(optional) — ограничить поиск ОДНИМ провайдером по имени; пусто — все включённые. Неизвестное имя → явная ошибка со списком доступных. «Все» и конкретный провайдер кэшируются в разные ячейки. Актуальный список движков этого сервера подставляется в описание инструмента динамически (вместе с заметками про скорость/транспорт) — LLM-клиент видит его без отдельного запросаminScore(optional) — фильтр по оценке, применяется только к источникам с числовым скорингом (сейчас SearXNG), игнорируется остальными; не передан — фильтра нет вовсеuseHttp(optional) — использоватьnet/httpвместо Chromium для последующего получения страниц (только если Chromium не справляется)
Кэширование: успешный агрегированный ответ кэшируется на
SEARCH_CACHE_TTL_HOURS(по умолчанию неделя); повторный идентичный запрос возвращается из кэша без нагрузки на движки и без занятия очереди. Все down — в кэш НЕ пишется, чтобы пустой ответ не «отравлял» ячейку.
- Использовать когда: Нужно найти источники, новости или ответы на вопросы.
web/fetch
Получение содержимого страницы по URL. По умолчанию очищает HTML от мусора и конвертирует в Markdown.
Параметры:
url(required) — URL страницыto_markdown(optional) — конвертировать в Markdownclean(optional) — очищать страницу от рекламы и навигации. Приclean: falseвозвращается сырой контентuseHttp(optional) — использоватьnet/httpвместо Chromium (только если Chromium не справляется)
Кэширование: при успешном получении страницы raw HTML кэшируется. Последующая обработка (clean/toMarkdown) всегда применяется поверх. TTL кэша сбрасывается при каждом обращении к странице.
- Использовать когда: Нужно прочитать статью целиком или получить сырые данные для самостоятельного анализа.
web/research
Комбинированный инструмент: скачивает страницу, очищает её и отправляет в LLM с инструкцией пользователя.
Параметры:
url(required) — URL страницыprompt(optional) — инструкция для LLM (по умолчанию: "Сделай краткую выжимку основных фактов и тезисов")clean(optional) — очищать страницу от рекламы и навигацииuseHttp(optional) — использоватьnet/httpвместо Chromium (только если Chromium не справляется)
web/deep_research
Комбинированный инструмент: формирование поисковых запросов, поиск источников, скачивает страницы, очищает их и отправляет в LLM с инструкцией пользователя, после собирает по каждой страницы результаты и отправляет уже все страницы вместе в LLM для более общего исследования.
Параметры:
prompt(required) — тема исследования и инструкция для LLMclean(optional) — очищать страницы от рекламы и навигацииuseHttp(optional) — использоватьnet/httpвместо Chromium для получения страниц (только если Chromium не справляется)
Использовать когда:
- Нужна краткая выжимка (summary) длинной статьи.
- Нужно извлечь конкретные факты, код или данные.
- Нужно перевести контент или структурировать его.
Мониторинг
Сервер отдает метрики Prometheus по адресу /metrics.
Ключевые метрики:
mcp_tool_calls_total{tool="search|fetch|research|deep_research", status="success|error"}— количество вызовов инструментов.mcp_tool_call_duration_seconds— время выполнения операций.http_requests_total— общие HTTP-запросы к серверу.
Endpoints
/mcp— Точка входа для MCP-клиентов: streamable HTTP в режимеhttp; stdio-режим работает без HTTP вообще./metrics— Метрики Prometheus./health— Health-check (возвращает200 OK).
🚀 Запуск и подключение
1. Быстрый старт с Docker
Самый простой способ запустить сервер — использовать Docker. Убедитесь, что у вас установлен Docker и Docker Compose.
Создайте файл docker-compose.yml:
version: '3.8'
services:
mcp-searxng:
image: git.ymnuktech.ru/ymnuk/mcp-searxng:latest
container_name: mcp-searxng
restart: unless-stopped
ports:
- "3000:3000"
environment:
# Основные настройки
- WEB_PORT=3000
- SEARXNG_URL=http://searxng:8080
- LLM_URL=http://host.docker.internal:1234/v1 # Для локального LLM (Ollama/LM Studio)
- LLM_MODEL=gemma-4-26b-a4b-it
# Настройки Chromium (для рендеринга сложных сайтов)
- USE_CHROMIUM=true
- CHROMIUM_PATH=/usr/bin/chromium
- CHROMIUM_TIMEOUT=60
# Опционально: токен для LLM, если требуется
# - LLM_TOKEN=your-token-here
depends_on:
- searxng
searxng:
image: searxng/searxng:latest
container_name: searxng
restart: unless-stopped
volumes:
- ./searxng:/etc/searxng:rw
environment:
- BASE_URL=http://localhost:8099
- INSTANCE_NAME=my-searxng
ports:
- "8099:8080"
Примечание: Если вы используете Linux, замените
host.docker.internalна IP-адрес вашего хоста (например,172.17.0.1) или используйте сетьhostдля доступа к локальному LLM-серверу.
Запустите сервисы:
docker compose up -d
Проверьте работоспособность:
curl http://localhost:3000/health
2. Подключение к VS Code (и другим редакторам)
Для использования инструментов в VS Code вам потребуется расширение Model Context Protocol (или аналогичное, поддерживающее Streamable-HTTP-транспорт MCP; SSE-транспорт устарел и сервером не используется).
Шаг 1: Настройка MCP Client
Откройте настройки MCP в VS Code (Ctrl+Shift+P -> MCP: Open Configuration) или отредактируйте файл mcp.json в вашем проекте/глобально.
Добавьте конфигурацию для вашего сервера:
{
"mcpServers": {
"searxng-research": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer optional-token-if-needed"
}
}
}
}
Шаг 2: Использование
После перезагрузки окна VS Code или перезапуска расширения, инструменты web/search, web/fetch, web/research и web/deep_research станут доступны агенту (например, Copilot Chat, Cursor или другому AI-ассистенту, интегрированному в IDE).
3. Подключение к другим агентам
Cursor / Windsurf
В настройках агента найдите раздел MCP Servers и добавьте новый сервер с типом HTTP (Streamable-HTTP MCP; в старых версиях интерфейса пункт так и называется «SSE»):
- Name:
Search Research - URL:
http://localhost:3000/mcp
Open WebUI
- Перейдите в Admin Panel -> Settings -> Connections.
- В разделе MCP Servers добавьте новый endpoint:
- Name:
SearXNG - URL:
http://host.docker.internal:3000/mcp(или IP вашего сервера)
- Name:
- Сохраните настройки и перезагрузите страницу. Теперь вы можете выбирать инструменты поиска прямо в чате.
Claude Desktop
Сервер поддерживает режим stdio для прямого подключения без мостов:
./mcp-searxng --mode=stdio
В Claude Desktop добавьте в mcp_settings.json:
{
"mcpServers": {
"searxng": {
"command": "/path/to/mcp-searxng",
"args": ["--mode=stdio"]
}
}
}
🔧 Troubleshooting
- Ошибка подключения к LLM: Убедитесь, что контейнер имеет доступ к хост-машине. Для Docker Desktop на Mac/Windows используйте
host.docker.internal. На Linux может потребоваться запуск с--network hostили указание конкретного IP. - Chromium падает: Проверьте логи контейнера (
docker logs mcp-searxng). Убедитесь, что переменнаяCHROMIUM_PATHуказывает на существующий бинарник внутри контейнера (в официальном образе он обычно уже есть, если вы используете кастомный Dockerfile). - Таймауты поиска: Если SearXNG отвечает медленно, увеличьте
HTTP_TIMEOUTв переменных окружения.
Лицензия
Этот проект распространяется под лицензией MIT, подробности см. в файле LICENSE.