# yandex-direct-mcp-plus Ведение контекстной рекламы Яндекс.Директа из диалога с ассистентом: собрать кампанию, разобрать поисковые запросы, вычистить минус-фразы, поправить ставки и посмотреть расход — не переключаясь между разделами кабинета. Работает в любом MCP-клиенте: Claude Code, Claude Desktop, Cursor и другие. [![npm](https://img.shields.io/npm/v/yandex-direct-mcp-plus.svg)](https://www.npmjs.com/package/yandex-direct-mcp-plus) [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) [![Node](https://img.shields.io/badge/node-%3E%3D22-green.svg)](https://nodejs.org) - **Вход из диалога.** Ассистент даёт ссылку, вы входите своим аккаунтом Яндекса и присылаете код — без регистрации приложения, заявки на доступ к API и ручного токена. - **68 инструментов**, из них 27 только читают. Кампании и стратегии, группы, объявления и модерация, ключевые фразы и ставки, прогноз по фразам без кампании, минус-фразы и общие наборы, запрещённые площадки и IP, быстрые ссылки, уточнения, изображения, визитки, корректировки ставок, ретаргетинг, аудиторные и динамические цели, фиды, расписание показов, статистика, поисковые запросы, баланс и справочники. - **Деньги — в рублях**, на вводе и на выводе; в микроединицы API сервер переводит сам. Поддержан агентский режим (`Client-Login`). - **ID — строками** (`"1915016273214320641"`): 64-битные идентификаторы Директа не помещаются в число JavaScript и молча теряют точность. - **Реклама боевая.** Тестовой среды у Директа больше нет — какие инструменты тратят деньги и что удаляют необратимо, перечислено в разделе [Что меняет данные](#что-меняет-данные). - **Телеметрии нет.** Сервер не отправляет никуда ничего, кроме запросов к API Яндекса. ## Содержание - [Что можно делать](#что-можно-делать) — примеры запросов обычным текстом - [Установка](#установка) — Claude Code, Claude Desktop, Cursor, из исходников - [Подключение к Директу](#подключение-к-директу) — вход из диалога или свой токен - [Что меняет данные](#что-меняет-данные) — что тратит бюджет и что необратимо - [Инструменты](#инструменты) — полный список с описаниями - [Разработка](#разработка) — сборка, тесты, архитектура ## Что можно делать Обычным текстом в чате — инструменты сервер подставляет сам: ```text Собери кампанию «Летняя распродажа»: бюджет 5000 ₽/день, старт 1 мая, показы будни 9–21 Добавь минус-фразы «бесплатно» и «скачать» в кампанию 12345, не затерев остальные Посмотри поисковые запросы за месяц и предложи, что заминусовать Подними ставку до 25 ₽ там, где CTR выше 8%, а показов меньше сотни Что изменилось в кампаниях со вчера? Покажи расход по кампаниям за неделю и баланс аккаунта Найди код региона для Новосибирска ``` Полный список — в разделе [Инструменты](#инструменты). ## Установка Понадобится Node.js не ниже 22. Отдельно ставить сервер не нужно: клиент сам запускает пакет через `npx` и общается с ним по stdio. Токен заранее не нужен — вход делается из диалога ([как](#подключение-к-директу)). ### Claude Code ```bash claude mcp add yandex-direct -- npx -y yandex-direct-mcp-plus ``` ### Claude Desktop, Cursor и другие клиенты В конфиг MCP-серверов клиента (`claude_desktop_config.json`, `.cursor/mcp.json` и т. п.) добавляется запись: ```json { "mcpServers": { "yandex-direct": { "command": "npx", "args": ["-y", "yandex-direct-mcp-plus"] } } } ``` Агентскому аккаунту в `env` нужен ещё `YANDEX_DIRECT_LOGIN` — см. [Подключение к Директу](#подключение-к-директу). ### Из исходников ```bash git clone git@github.com:Pavelsiba/yandex-direct-mcp-plus.git cd yandex-direct-mcp-plus npm ci npm run build ``` В конфиге клиента вместо `npx` тогда стоит `"command": "node"`, а в `args` — абсолютный путь к `dist/app/index.js`. ### Удалённый сервер Тот же сервер можно поднять по HTTP на своей машине — в Docker, за nginx с HTTPS — и подключаться к нему по адресу из claude.ai, с телефона или из Claude Desktop без установки Node. Вход закрыт секретом. Настройка — [docs/deploy.md](docs/deploy.md). ## Подключение к Директу ### Вход из диалога Достаточно попросить ассистента подключиться к Директу. Он вызовет `start_login` и покажет ссылку на вход в Яндекс — входите аккаунтом, у которого есть доступ к нужному кабинету. Яндекс покажет код подтверждения; его нужно прислать в чат, и ассистент передаст его в `finish_login`. - Вход идёт через приложение этого сервера с одобренным доступом к API, поэтому своё приложение и заявка не нужны. Баллы API тратит ваш аккаунт, как и при собственном токене. - Код одноразовый и без ключа, который хранится только в запущенном сервере, бесполезен — присылать его в чат безопасно. - Токен сохраняется в `~/.config/yd-mcp/credentials.json` (или `$XDG_CONFIG_HOME/yd-mcp/`), файл доступен только владельцу. Срок продлевается сам. - Кто подключён и до когда — `auth_status`. Выйти — `logout`: он удаляет сохранённый вход. Отозвать доступ совсем — в Яндекс ID, раздел «Устройства, сервисы и пароли». ### Свой токен Если токен уже есть — например, для CI или удалённого сервера, — его можно передать в окружении, и тогда он главнее входа из диалога. Токен выпускается для приложения, зарегистрированного в [Яндекс OAuth](https://oauth.yandex.ru/), с доступом к API Директа: [регистрация приложения и получение токена](https://yandex.ru/dev/direct/doc/ru/token), доступ [запрашивается в интерфейсе Директа](https://yandex.ru/dev/direct/doc/ru/access-request) — заявку рассматривают от часа до нескольких суток. ```bash claude mcp add yandex-direct -e YANDEX_DIRECT_TOKEN=ваш_токен -- npx -y yandex-direct-mcp-plus ``` В JSON-конфиге клиента — `"env": { "YANDEX_DIRECT_TOKEN": "ваш_токен" }` рядом с `args`. ### Переменные окружения - `YANDEX_DIRECT_TOKEN` — OAuth-токен. Необязателен: без него сервер берёт сохранённый вход из диалога, а если нет и его — инструмент вернёт ошибку с подсказкой, как подключиться. - `YANDEX_DIRECT_LOGIN` — логин рекламодателя, уходит в заголовок `Client-Login`. Нужен только агентскому аккаунту: без него запросы идут в собственный кабинет агентства, а не в кабинет клиента. ## Что меняет данные Тестовой среды у Яндекс.Директа больше нет: песочница отключена с июля 2026, и любой вызов идёт по боевому аккаунту. Отлаживать сценарии приходится на отдельной кампании, оставленной черновиком, — показов она не даёт и потому не тратит бюджет, пока не пройдёт модерацию и не будет включена. Граница проходит не по «чтение или запись», а по скорости, с которой действие превращается в деньги. **Только читают** все `list_*`, `get_*` и справочники. Вызвать их безопасно всегда. **Тратят бюджет или запускают показы:** | Инструмент | Чем именно | | ------------ | ------------ | | `manage_campaigns` | `resume` — включает показы остановленной кампании | | `manage_ads` | `resume` и `moderate` — возвращает объявления в показ | | `moderate_ads` | Отправляет объявления на модерацию, после неё начнутся показы | | `update_campaign` | Меняет дневной бюджет | | `set_keyword_bids` | Меняет ставки, то есть цену клика | | `set_auto_keyword_bids` | Пересчитывает ставки под цену нужного объёма трафика — до потолка, если он задан | | `set_strategy` | Меняет стратегию — переписывает всю экономику кампании | | `add_bid_adjustments` | Заводит корректировку: +N% к ставке на срезе аудитории | | `set_bid_adjustments` | Меняет коэффициент существующей корректировки | **Удаляют необратимо** — эти инструменты помечены аннотацией `DESTRUCTIVE`, и хороший MCP-клиент спросит подтверждение перед вызовом: `manage_campaigns` (`delete`), `manage_ads` (`delete`), `manage_keywords` (`delete`), `delete_ad_groups`, `delete_ad_extensions`, `delete_sitelinks`, `delete_vcards`, `delete_bid_adjustments`, `delete_retargeting_lists`, `manage_ad_images` (`delete`), `manage_dynamic_targets` (`delete`), `set_audience_targets` (`delete`), `manage_negative_keyword_shared_sets` (`delete`). Сюда же — `set_campaign_negative_keywords` и `set_ad_group_negative_keywords` в режиме `replace`: он затирает прежний список минус-фраз целиком. Именно поэтому у них нет режима по умолчанию — `mode` приходится назвать явно. Так же устроен `set_priority_goals`: `replace` и `remove` убирают цели стратегии, а любая смена целей перезапускает её обучение. Остальные инструменты создают и правят объекты. Пока кампания не прошла модерацию и не включена, показов по ней нет и бюджет не расходуется. **Чего API не умеет.** Смарт-баннеры и динамические объявления Директ через API не создаёт с 22 мая 2026, визитки — тоже: в WSDL методы есть, боевой API отвечает ошибкой 3500. Такие объекты заводятся в интерфейсе Директа, а дальше сервер с ними работает: кампании читает и правит, визитки читает и удаляет. Единую перфоманс-кампанию сервер пока только читает. ## Инструменты В таблицах — первое предложение описания, которое сервер отдаёт модели; таблицы собираются из кода, поэтому список всегда полный. ### Подключение | Инструмент | Описание | | ------------ | ---------- | | `start_login` | Первый шаг входа из диалога, без ручного токена: возвращает ссылку на вход в Яндекс. | | `finish_login` | Второй шаг входа: меняет код подтверждения от пользователя на токен и сохраняет его на этом компьютере. | | `auth_status` | Откуда сервер берёт токен (переменная окружения, вход из диалога или запрос) и до когда он действует. | | `logout` | Удаляет сохранённый вход из диалога с этого компьютера. | ### Кампании и стратегии | Инструмент | Описание | | ------------ | ---------- | | `list_campaigns` | Список рекламных кампаний Яндекс.Директ с фильтрацией по статусу и типу. | | `get_campaign` | Детальная информация о кампании по ID: бюджет (руб), статус и пояснение к нему, даты, статистика, UTM-разметка, цели и их ценность (PriorityGoals), счётчики Метрики, модель атрибуции и прочие настройки. | | `create_campaign` | Создать новую текстово-графическую кампанию. | | `update_campaign` | Обновить кампанию: название, бюджет (руб), UTM-разметку, счётчики Метрики, модель атрибуции и/или статус (SUSPEND/RESUME/ARCHIVE/UNARCHIVE). | | `manage_campaigns` | Запустить, остановить, архивировать, разархивировать или удалить кампании. | | `get_strategy` | Получить текущую стратегию показов текстово-графической кампании вместе с целями (PriorityGoals), счётчиками и моделью атрибуции. | | `set_strategy` | Изменить стратегию текстово-графической кампании: ручная, максимум кликов, средняя цена клика или конверсии, оплата за конверсию. | | `set_priority_goals` | Задать цели стратегии кампании (PriorityGoals) и их ценность в рублях — по ним автостратегия оптимизирует ставки, в том числе «максимум конверсий» со служебным GoalId 13. | | `get_time_targeting` | Временной таргетинг кампании: часовой пояс, часы показов по дням недели, почасовые коэффициенты и настройка праздников. | | `set_time_targeting` | Задать расписание показов кампании: дни, часы, почасовые коэффициенты, праздники и часовой пояс. | ### Группы объявлений | Инструмент | Описание | | ------------ | ---------- | | `list_ad_groups` | Группы объявлений выбранных кампаний: названия, регионы, статусы. | | `create_ad_group` | Создать группу объявлений в кампании с таргетингом по регионам (см. get_regions). | | `update_ad_group` | Изменить группу объявлений без пересоздания: название, регионы показа (полный список, заменяет прежний) и/или UTM-разметку ссылок. | | `delete_ad_groups` | Удалить группы объявлений по их ID. | ### Объявления | Инструмент | Описание | | ------------ | ---------- | | `list_ads` | Объявления: все заголовки и тексты, ссылки, статусы, тип и подтип объявления, привязанные сайтлинки, изображения и видео. | | `create_responsive_ad` | Создать комбинаторное объявление: от 1 до 7 заголовков (≤56 символов), от 1 до 3 текстов (≤81) и ссылка; варианты показа Директ собирает из них сам. | | `update_responsive_ad` | Обновить комбинаторное объявление: заголовки, тексты, ссылка. | | `manage_ads` | Действие над объявлениями: suspend/resume/archive/unarchive/moderate/delete. | | `moderate_ads` | Отправить выбранные объявления на модерацию. | ### Ключевые фразы и ставки | Инструмент | Описание | | ------------ | ---------- | | `list_keywords` | Ключевые фразы в группах объявлений: фразы, ставки (руб), статусы. | | `add_keywords` | Добавить ключевые фразы в группу объявлений. | | `update_keywords` | Изменить текст ключевых фраз, подстановочные переменные {param1}/{param2} и настройки автотаргетинга. | | `manage_keywords` | Действие над ключевыми фразами: suspend/resume/delete. | | `set_keyword_bids` | Установить фиксированные ставки (поиск/сети, в рублях) на уровне фраз, групп или кампаний и включить или выключить автоставку автотаргетинга. | | `set_auto_keyword_bids` | Назначить ставки по правилу вместо суммы: на поиске — под желаемый объём трафика (5–100%), в сетях — под долю аудитории, с надбавкой в процентах и потолком в рублях. | | `get_keyword_auction` | Сколько стоит трафик по фразам: текущие ставки и торги на поиске и в сетях. | | `get_keyword_forecast` | Прогноз трафика и цены клика по списку фраз без кампании — для подбора семантики. | ### Минус-фразы | Инструмент | Описание | | ------------ | ---------- | | `get_campaign_negative_keywords` | Получить текущие минус-фразы кампаний по их ID. | | `set_campaign_negative_keywords` | Минус-фразы на уровне кампании. | | `set_ad_group_negative_keywords` | Минус-фразы на уровне группы объявлений. | | `list_negative_keyword_shared_sets` | Получить общие наборы минус-фраз аккаунта. | | `manage_negative_keyword_shared_sets` | Создать, изменить или удалить общие наборы минус-фраз аккаунта. | | `link_negative_keyword_sets` | Заменить привязки общих наборов минус-фраз у кампаний и/или групп объявлений. | ### Запреты показа | Инструмент | Описание | | ------------ | ---------- | | `set_campaign_excluded_sites` | Площадки РСЯ и приложения, на которых кампания не показывается (до 1000). | | `set_campaign_blocked_ips` | IP-адреса, которым кампания не показывается (до 25, одиночные публичные IPv4). | ### Ассеты объявления | Инструмент | Описание | | ------------ | ---------- | | `list_sitelinks` | Получить все или выбранные наборы быстрых ссылок. | | `set_sitelinks` | Создать новый набор из 1–8 быстрых ссылок. | | `delete_sitelinks` | Удалить наборы быстрых ссылок по ID. | | `list_ad_extensions` | Получить уточнения (callouts) с их статусами и текстом. | | `add_ad_extensions` | Создать уточнения (callouts), каждый текст до 25 символов. | | `delete_ad_extensions` | Удалить уточнения по ID. | | `manage_ad_images` | Загрузить, получить или удалить изображения объявлений (AdImages). | | `list_vcards` | Получить виртуальные визитки по ID или найти их через объявления выбранных кампаний. | | `delete_vcards` | Удалить визитки по ID; удаление необратимо. | ### Таргетинг и корректировки | Инструмент | Описание | | ------------ | ---------- | | `list_audience_targets` | Получить условия нацеливания на аудиторию по ID кампании, группы, ретаргетинга или интереса. | | `set_audience_targets` | Добавить, остановить, возобновить, удалить аудиторные цели или изменить их ставки. | | `list_dynamic_targets` | Получить условия нацеливания динамических текстовых объявлений. | | `manage_dynamic_targets` | Создать, изменить ставки, остановить, возобновить или удалить динамические цели. | | `list_retargeting_lists` | Получить условия ретаргетинга и подбора аудитории с правилами и областью применения. | | `add_retargeting_list` | Создать условие ретаргетинга из целей Метрики, сегментов или интересов. | | `update_retargeting_lists` | Изменить название, описание и правила условий ретаргетинга. | | `delete_retargeting_lists` | Удалить условия ретаргетинга и подбора аудитории по ID; удаление необратимо. | | `get_bid_adjustments` | Получить корректировки ставок кампании или группы: устройства, пол и возраст, аудитории, регионы, платёжеспособность, размещение. | | `add_bid_adjustments` | Создать корректировки ставок на кампаниях или группах. | | `set_bid_adjustments` | Изменить коэффициенты существующих корректировок по их ID. | | `delete_bid_adjustments` | Удалить корректировки по их ID. | ### Отчёты | Инструмент | Описание | | ------------ | ---------- | | `get_statistics` | Статистика за период по кампаниям, группам, объявлениям, условиям показа или аккаунту: показы, клики, расход (руб), CTR, CPC; с goals — конверсии и CPA по целям Метрики (ReportService, TSV). | | `get_search_queries` | Отчёт по фактическим поисковым запросам для анализа и добавления минус-фраз. | ### Аккаунт и справочники | Инструмент | Описание | | ------------ | ---------- | | `get_account_balance` | Баланс и финансовая информация аккаунта (Amount, Currency) через Live API v4. | | `list_businesses` | Получить доступные профили организаций из Яндекс Бизнеса. | | `get_changes` | Проверить изменения кампаний, групп и объявлений начиная с указанного времени, а также изменения справочников (mode=dictionaries) и текущее время сервера Директа. | | `list_feeds` | Получить товарные фиды, их источники, статусы обработки и связанные кампании. | | `get_regions` | Справочник кодов регионов (GeoRegions) для таргетинга. | | `list_time_zones` | Справочник часовых поясов (TimeZones) для set_time_targeting и create_campaign. | ## Разработка ```bash npm ci # зависимости строго по lock-файлу npm run dev # сервер из исходников, без сборки npm run build # dist/ — то, что запускает MCP-клиент npm test # юнит-тесты, сеть подменена npm run lint # Biome: формат и линт npm run typecheck # типы в src, тестах и конфигах npm run lint:md # markdownlint: README и docs по правилам форматтера IDE npm run lint:dead # knip: неиспользуемый код и зависимости npm run lint:workflows # actionlint + zizmor: корректность и безопасность workflow npm run lint:secrets # gitleaks по всей истории npm run docs:tools # таблицы инструментов в README из реестра ``` gitleaks, actionlint, zizmor и shellcheck — не npm-пакеты; без них хуки pre-commit не пропустят коммит. На Windows: ```powershell winget install -e --id Gitleaks.Gitleaks winget install -e --id rhysd.actionlint winget install -e --id zizmor.zizmor winget install -e --id koalaman.shellcheck ``` Без режима разработчика winget не создаёт ссылки в `%LOCALAPPDATA%\Microsoft\WinGet\Links`, и каталоги пакетов из `%LOCALAPPDATA%\Microsoft\WinGet\Packages` придётся добавить в `PATH`. Таблицы инструментов выше руками не правятся: после смены описания инструмента — `npm run docs:tools`, иначе юнит-тест покажет расхождение. Сетевые тесты (`npm run test:int`) идут по боевому аккаунту и пишут только в кампанию-полигон, оставленную черновиком: её ID задаётся переменной `YANDEX_DIRECT_POLYGON_CAMPAIGN_ID`. Без переменной они пропускаются. Код разложен по слоям `app → tools → shared`; инструмент — это каталог `src/tools/<домен>/` с `schema.ts`, `handler.ts` и `tool.ts`. Подробности — в [docs/architecture.md](docs/architecture.md). ## Происхождение и благодарности Проект начат на коде [`theYahia/yandex-direct-mcp`](https://github.com/theYahia/yandex-direct-mcp) под лицензией MIT. Расширение с 20 до 48 инструментов и перевод ID на строки — работа [**Maxim (DrSeedon)**](https://github.com/DrSeedon), [PR #7](https://github.com/theYahia/yandex-direct-mcp/pull/7); в npm эта версия не публиковалась. Дальше проект развивается самостоятельно и апстрим не отслеживает. История изменений с отделения от апстрима — в [CHANGELOG.md](CHANGELOG.md). ## Лицензия Copyright © 2026 Pavelsiba. [GNU AGPL-3.0-only](LICENSE). Пользоваться сервером, изменять его и разворачивать у себя можно свободно, в том числе в работе с клиентами. Кто предоставляет изменённый сервер другим людям по сети, обязан дать им исходный код своей версии (раздел 13 лицензии). Версии до 1.7.0 включительно вышли под MIT и под ней остаются. Pull request'ы принимаются вместе с передачей прав на вклад автору проекта (CLA) — без этого проект не сможет распоряжаться своим кодом. Перед большой правкой лучше завести issue.