MARTECH

Webmaster MCP

Как я связал Вебмастер с агентом и определил границы автоматизации: чтение, квоты, отмена и неопределённый результат записи.

Self-hosted MCP-сервер на Go для моего SEO Agent: отчёты об индексировании, диагностике и поиске, режим только для чтения и ограниченный доступ к API Яндекса.

Go · MCP · Yandex Webmaster · Docker

Моя роль

Автор проекта: архитектура, Go, интеграция с API Яндекса, MCP, тестирование и контейнеризация.

Open source · Сентябрь 2026. Кейс описывает опубликованную реализацию. Примеры и проверки выполнены на коммите fad9a869, ссылки на код закреплены на этой версии.

Рабочий контекст

Я собираю SEO Agent для своих сайтов: он по расписанию получает поисковые метрики и сопоставляет их с историей страниц. Для Google у меня уже есть отдельный MCP-сервер. Следующим источником стал Яндекс Вебмастер: мне нужны его сведения об индексировании, страницах в поиске и диагностике, чтобы агент мог объяснить, на каких данных основан вывод.

Я написал Webmaster MCP на Go. Это отдельный self-hosted сервис со Streamable HTTP, MCP-инструментами и доступом к REST API Яндекса. Он получает данные, а интерпретация и хранение истории остаются задачей SEO Agent. В самом MCP-сервере нет постоянной базы: такое разделение позволяет проверять интеграцию независимо от сборщика.

Границы системы
  1. SEO AgentРасписание, анализ и история в PostgreSQL
  2. Webmaster MCPGo, доступ к отчётам, полномочия и ограничения запросов
  3. API ЯндексаДанные Вебмастера и очередь переобхода

Агент подключается с MCP bearer-токеном. Отдельный OAuth-токен Яндекса хранится на стороне MCP-сервера. Даты сбора и историю сохраняет SEO Agent.

Сценарий: проверить индексирование сайта

Работу я начинаю с list_hosts. Агент получает доступные сайты и использует host_id ровно в том виде, в котором его вернул Вебмастер, например https:example.com:443. Протокол и порт здесь существенны: самостоятельно составленный идентификатор может привести к запросу другого хоста.

  1. get_summary даёт общую картину: сведения о сайте, страницах и проблемах.
  2. get_diagnostics позволяет прочитать диагностические сообщения, вместо того чтобы предполагать причину изменения показателей.
  3. get_insearch_history показывает историю страниц в поиске, а get_insearch_samples — доступную выборку URL для дальнейшей проверки.

Я разделяю скачивание страницы роботом и её присутствие в поиске: для первого есть инструменты get_indexing_*, для второго — get_insearch_*. Выборка URL не является полной картой индекса, а пустой ответ сам по себе не доказывает отсутствие страниц. В отчёте должны сохраняться выбранный хост, период и ограничения источника.

Применение на opatsay.com: данные перед рекомендацией

12 сентября 2026 года в 14:29:23 UTC я выполнил четыре операции чтения через работающий Webmaster MCP: list_hosts, get_summary, get_diagnostics и get_insearch_history. Хост https:opatsay.com:443 был получен из discovery и подтверждён в Яндексе.

Сводка вернула 50 страниц в поиске и 4 исключённые. История за запрошенный период 29 августа — 11 сентября содержала три точки: 19 страниц 7 сентября, 48 — 9 сентября и 50 — 10 сентября. Диагностика дала 32 состояния ABSENT, ни одного PRESENT и UNDEFINED для NOT_MOBILE_FRIENDLY.

Этот пример проверяет полезность границ данных: агент может сообщить изменение числа страниц, но не назвать его ростом трафика, приписать редизайну или объявить все проверки успешными. Следующие действия — выяснить причины исключения URL и отдельно проверить мобильную верстку; сам отчёт не требует записи в Яндекс.

Параметры, исходные ответы и разбор результата. Это живое наблюдение собственного сайта, не данные демо и не измеренный SEO-эффект продукта. Время запроса сохранено отдельно от дат истории.

Решение 1: режим чтения как исполняемое правило

Плановому сборщику нужны отчёты. Отправка страницы на переобход меняет состояние внешней системы и расходует суточную квоту, поэтому для SEO Agent я предусмотрел MCP_READ_ONLY=true.

В этом режиме каталог содержит 33 инструмента. submit_recrawl исключён из списка, а прямой вызов по известному имени тоже отклоняется. Именно второй случай важен для границы доступа: одного скрытия инструмента из discovery недостаточно. Поведение проверяет отдельный тест через MCP. В обычном режиме доступны 34 инструмента, включая отправку на переобход.

Решение 2: тайм-аут записи не означает отказ

Если запрос на переобход ушёл в Яндекс, а ответ не пришёл вовремя, сервер уже мог принять URL. Автоматическая повторная отправка в таком состоянии способна создать лишнюю операцию. Поэтому клиент никогда автоматически не повторяет отправку на переобход.

Тайм-аут или отмена после отправки получают результат outcome_unknown с retryable: false. Это не подтверждение успеха и не подтверждение отказа. Прежде чем решать, отправлять ли URL повторно, нужно проверить get_recrawl_queue и, когда известен идентификатор задания, get_recrawl_task. Я вынес этот сценарий в регрессионный тест, чтобы общая политика повторов не начала незаметно распространяться на запись.

Решение 3: ограничивать чтение целиком

У запросов к Яндексу есть общий бюджет времени: по умолчанию 30 секунд, включая ожидание свободного слота и повторные попытки. При временных ошибках чтение может повторяться, но новая попытка не получает отдельные полные 30 секунд. Отмена охватывает и очередь, и обращение к внешнему API.

По умолчанию один процесс допускает восемь параллельных операций с Яндексом, а размер ответа ограничен 8 MiB. Эти границы помогают управлять ожиданием и потреблением памяти. Они не заменяют квоты провайдера: при запуске нескольких реплик суммарная нагрузка возрастёт, поскольку ограничитель у каждой реплики собственный.

Как я проверяю результат

В публичном репозитории есть воспроизводимый деморежим с явно обозначенными синтетическими данными. Он не обращается к Яндексу и позволяет проверить подключение без OAuth-токена. Интеграционные HTTP-тесты используют настоящий MCP SDK, проверку bearer-токена и подставной внешний транспорт; так я проверяю успешные вызовы, валидацию и ошибки интеграции.

Проверки разделены по смыслу. /health подтверждает, что процесс работает. Встроенный smoke проверяет обнаружение инструментов и представительный набор вызовов; в живой конфигурации он также проверяет доступ к данным Яндекса. Успешное демо не подтверждает права OAuth, доступ к конкретному сайту или настройку HTTPS на сервере.

Реализован и проверен следующий контракт: 33 инструмента для автоматического чтения, 34 в обычном режиме, явная ошибка для неопределённого результата записи и ограниченная работа с внешним API. Влияние на поисковый трафик здесь не измерялось.

Открытый код позволяет проверить каталог и регистрацию инструментов, пределы запросов и политику повторов, а также интеграцию HTTP → авторизация → MCP → API.

При подготовке кейса прошли тесты пакетов internal/webmaster, internal/mcpserver и cmd/mcp-server, включая отдельные проверки запрета прямого переобхода и тайм-аута записи. Изолированное демо прошло smoke с девятью вызовами. Проверки выполнены на опубликованном коммите fad9a869.

Ограничения и следующий шаг

Одна установка использует один OAuth-токен. Здесь нет изоляции независимых пользователей, распределённого ограничения запросов и браузерного входа в Яндекс. Для разных владельцев сайтов нужны отдельные установки. Сам сервис также не устанавливает причинную связь между изменением статьи и поисковыми показателями.

Дальше я развиваю сопоставление отчётов с историей страниц в SEO Agent: хочу видеть, какой материал изменился, какие данные уже обновились и где пока недостаточно наблюдений. Webmaster MCP остаётся источником проверяемых сведений, на которые этот анализ может ссылаться.

Попробовать публичное демо

Нужны Git и Docker с Compose. Команды собирают опубликованный исходный код. Демо использует синтетические данные и не обращается к Яндексу.

git clone https://github.com/tenqz/webmaster-mcp.git
cd webmaster-mcp
docker compose -f compose.demo.yml up -d --build
docker compose -f compose.demo.yml exec mcp /mcp-server --smoke http://127.0.0.1:8080/mcp

Подключение: http://localhost:8080/mcp, заголовок Authorization: Bearer demo-token. Это публичный демонстрационный токен. Compose-демо по умолчанию показывает 34 инструмента. Его параметр read_only относится к файловой системе контейнера — режим инструментов задаёт MCP_READ_ONLY.

После проверки остановите демо:

docker compose -f compose.demo.yml down

Для работы со своим сайтом продолжите со статьёй о подключении и использовании. Полный код доступен в репозитории Webmaster MCP.

GitHub Инструкция подключения

Давайте делать сложное понятным.

Архитектура, инженерное лидерство и AI в разработке — когда система слишком важна, чтобы её упрощать, и слишком дорогая, чтобы ею не владеть.

LinkedIn Telegram Email