No description
  • Go 99.3%
  • Dockerfile 0.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
ymnuk c453ca52c8
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
fix: yandex — пустая SERP без внешних ссылок теперь честно в engineFailures, а не ложное ok
Живой прогон (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 в оркестраторе, а не молчаливое пустое «успешное» попадание.
2026-09-26 13:41:47 +03:00
cmd/mcp-searxng feat: динамическое описание web/search — модель видит включённые движки без отдельного запроса 2026-09-26 12:53:42 +03:00
docs feat: динамическое описание web/search — модель видит включённые движки без отдельного запроса 2026-09-26 12:53:42 +03:00
http Добавление метода research 2026-04-28 21:57:55 +03:00
internal fix: yandex — пустая SERP без внешних ссылок теперь честно в engineFailures, а не ложное ok 2026-09-26 13:41:47 +03:00
.dockerignore Исправление в Dockerfile переменных окружения 2026-05-06 10:27:37 +03:00
.gitignore chore: каталог tmp/ в .gitignore 2026-09-24 23:40:08 +03:00
.woodpecker.yml fix: CI 2026-09-26 13:06:18 +03:00
AGENTS.md doc: разведка провайдеров (0.5), синхронизация архитектуры и правила агентов 2026-09-24 00:39:04 +03:00
bugs.txt update: go-simple-args v0.2.1 — slice из env и повторяемых CLI-флагов 2026-09-24 23:39:48 +03:00
config.example.yml doc: синхронизация документации с мультипровайдерной архитектурой и закрытие пунктов ROADMAP фазы 6 (кроме 6.3 — клиентская проверка остаётся за пользователем) 2026-09-26 11:18:05 +03:00
Dockerfile refactor: cmd/+internal layout, slog JSONL logging и YAML config (CONFIG_FILE) 2026-09-14 23:41:09 +03:00
go.mod feat: оркестрация поиска — fan-out по провайдерам, очередь, кэш и cooldown (фаза 2) 2026-09-26 09:26:08 +03:00
go.sum feat: оркестрация поиска — fan-out по провайдерам, очередь, кэш и cooldown (фаза 2) 2026-09-26 09:26:08 +03:00
LICENSE first commit 2025-11-24 19:09:56 +03:00
README.md feat: динамическое описание web/search — модель видит включённые движки без отдельного запроса 2026-09-26 12:53:42 +03:00

MCP SearXNG

MCP (Model Context Protocol) сервер для приватного поиска, извлечения контента и интеллектуального анализа веб-страниц с использованием SearXNG и LLM.

Описание

Этот проект представляет собой сервер Model Context Protocol (MCP), который предоставляет три основных инструмента:

  1. web/search — Приватный поиск в интернете через SearXNG.
  2. web/fetch — Получение и очистка содержимого веб-страниц (HTML → Markdown).
  3. web/research — Интеллектуальный анализ страницы с помощью LLM (саммаризация, извлечение фактов, перевод).
  4. 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 для мониторинга производительности.

Установка

  1. Убедитесь, что у вас установлен Go 1.27.1 или выше.
  2. Клонируйте репозиторий:
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)

Поиск информации в интернете: запрос параллельно отправляется во все включённые провайдеры (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) — конвертировать в Markdown
  • clean (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) — тема исследования и инструкция для LLM
  • clean (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

  1. Перейдите в Admin Panel -> Settings -> Connections.
  2. В разделе MCP Servers добавьте новый endpoint:
    • Name: SearXNG
    • URL: http://host.docker.internal:3000/mcp (или IP вашего сервера)
  3. Сохраните настройки и перезагрузите страницу. Теперь вы можете выбирать инструменты поиска прямо в чате.

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.