Yandex MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Yandex MCP Serverget my Yandex Direct campaigns"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Yandex MCP Server
MCP-сервер для API Яндекса: Direct, Metrika, Audience, Webmaster, AdMetrica + Admin Panel.
Архитектура: FastMCP + apiforge async + SQLAlchemy (Dual DB: SQLite/MySQL) + FastAPI Admin
Быстрый старт (локально, SQLite)
# 1. Клонировать и перейти в директорию
cd yandex-mcp-server
# 2. Установить зависимости
uv sync --no-dev
# 3. Скопировать .env
cp .env.example .env
# 4. Сгенерировать Fernet-ключ (если не задан в .env)
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
# Вставь ключ в .env: FERNET_KEY=...
# 5. Применить миграции
uv run alembic upgrade head
# 6. Запустить сервер
uv run python -m app.mainСервер будет доступен на http://localhost:8000/mcp (Streamable HTTP).
Related MCP server: yandex-marketing-mcp
Production-деплой
SQLite (рекомендуется для MVP)
# 0. Создать внешнюю Docker-сеть (только первый раз)
docker network create mais-bifrost-net
# 1. Скопировать production env
cp .env.example .env.prod
# Заполнить: FERNET_KEY, YANDEX_CLIENT_ID, YANDEX_CLIENT_SECRET
# 2. Запустить стек (сборка + запуск)
docker compose -f docker-compose.prod.sqlite.yml up -d --build
# 3. Применить миграции
docker exec mais-yandex-mcp uv run alembic upgrade head
# 4. Проверить
docker exec mais-yandex-mcp curl http://127.0.0.1:8000/pingMySQL (для высоких нагрузок)
# 0. Создать внешнюю Docker-сеть (только первый раз)
docker network create mais-bifrost-net
# 1. Скопировать production env
cp .env.prod.example .env.prod
# Заполнить: MYSQL_ROOT_PASSWORD, MYSQL_PASSWORD, FERNET_KEY, YANDEX_CLIENT_ID, YANDEX_CLIENT_SECRET
# 2. Запустить стек (сборка + запуск)
docker compose -f docker-compose.prod.yml up -d --build
# 3. Применить миграции
docker exec mais-yandex-mcp uv run alembic upgrade head
# 4. Проверить
curl http://localhost:8000/pingAdmin Panel
Web UI для управления интеграциями с Яндексом. Доступен после деплоя.
Route | Описание |
| Dashboard — список интеграций, статус токенов |
| Добавить интеграцию (Direct, Metrika и т.д.) |
| OAuth callback для Yandex |
Стек: FastAPI + Jinja2 + общая БД с MCP-сервером.
Настройка Bifrost
Bifrost должен проксировать заголовок X-Bifrost-User-Id при подключении к MCP-серверу. MCP-сервер слушает на /mcp (Streamable HTTP).
app.mais.agency {
# Admin panel (protected by Yandex OAuth)
@admin path /admin/*
handle @admin {
forward_auth auth:4180 {
uri /auth
}
reverse_proxy mais-yandex-admin:8100
}
# MCP endpoint
handle @mcp {
reverse_proxy /mcp/* yandex-mcp:8000 {
header_up X-Bifrost-User-Id {http.request.header.X-Bifrost-User-Id}
}
}
# Bifrost UI
reverse_proxy /api/* mais-bifrost:8080
}Доступные MCP-инструменты (14)
Инструмент | Описание |
| Health check |
| Список аккаунтов пользователя |
| Кампании Яндекс Директа |
| Счётчики Яндекс Метрики |
| Хосты Яндекс Вебмастера |
| Сегменты Яндекс Аудитории |
| Кампании Яндекс AdMetrica |
| Статистика кампании (Impressions, Clicks, CTR, CPC, Cost, Conversions) |
| Ключевые слова кампании |
| Объявления кампании (Title, Text, Status, State) |
| Частотность ключевых слов (Wordstat) |
| Получить контекст аккаунта (бизнес-правила, заметки) |
| Обновить контекст аккаунта |
| Отправить обратную связь о работе сервера |
MCP Resources (5)
LLM может запросить документацию по API прямо во время диалога — без галлюцинаций:
Resource | Описание |
| Яндекс.Директ API: структура, статусы, ограничения, best practices |
| Яндекс.Метрика API |
| Яндекс.Вебмастер API |
| Яндекс.Аудитории API |
| Яндекс.AdMetrica API |
Пример: ReadResource(yandex://direct/docs) → возвращает ~1000 символов документации.
MCP Prompts (3)
Готовые сценарии для LLM с типизированными аргументами:
Prompt | Аргументы | Описание |
|
| Детальный анализ кампании с шагами и форматом отчёта |
|
| Перераспределение бюджета на основе ROI |
|
| Выявление объявлений с CTR < 1%, CPC > avg, 0 конверсий |
Пример: GetPrompt(analyze_campaign_performance, campaign_id=12345, days=7) → возвращает message с инструкцией для LLM: "Проанализируй эффективность кампании 12345 за последние 7 дней. ШАГИ: 1. Получи контекст аккаунта... 2. Получи статистику..."
Отладка с MCP Inspector
Используй MCP Inspector для тестирования инструментов без LLM.
Локальный запуск
# 1. Убедись, что в .env указан SQLite
# DATABASE_URL=sqlite+aiosqlite:///./data/yandex-mcp.db
# 2. Запусти сервер
uv run python -m app.main
# 3. В другом терминале запусти Inspector
npx @modelcontextprotocol/inspector
# 4. В браузере (http://localhost:5173) выбери:
# Transport: Streamable HTTP
# URL: http://localhost:8000/mcp
# 5. Перейди во вкладку Tools → List Tools → протестируй pingТестирование ошибок
Если apiforge получает 400/401/429 от Яндекса, сервер возвращает структурированный JSON:
{
"status": "error",
"yandex_api_error": true,
"message": "Yandex API returned 401: Authentication failed",
"suggestion": "Re-authorize the Yandex account via OAuth."
}Ошибки выводятся в ответе инструмента (Response tab) и в терминале сервера (stdout).
Benchmark
Подключение:
POST http://localhost:8000/mcp(Streamable HTTP,Accept: application/json, text/event-stream)
1. ListTools → get_direct_stats_tool (inputSchema + description)
{
"name": "get_direct_stats_tool",
"description": "Получить статистику по кампании Яндекс.Директа за период.\n\n КОГДА ИСПОЛЬЗОВАТЬ:\n - Нужно проанализировать эффективность кампании\n - Получить показы, клики, CTR, CPC, расходы, конверсии\n\n ПАРАМЕТРЫ:\n - campaign_id: ID кампании из get_direct_campaigns\n - date_from: Начало периода в формате YYYY-MM-DD\n - date_to: Конец периода в формате YYYY-MM-DD\n - account_id: ID аккаунта (опционально)\n\n ВОЗВРАЩАЕТ: метрики Impressions, Clicks, CTR, CPC, Cost, Conversions.",
"inputSchema": {
"properties": {
"campaign_id": {"type": "integer"},
"date_from": {"type": "string"},
"date_to": {"type": "string"},
"account_id": {"anyOf": [{"type": "integer"}, {"type": "null"}], "default": null}
},
"required": ["campaign_id", "date_from", "date_to"]
}
}2. ListResources
{
"resources": [
{"name": "direct_docs", "uri": "yandex://direct/docs", "mimeType": "text/plain"},
{"name": "metrika_docs", "uri": "yandex://metrika/docs", "mimeType": "text/plain"},
{"name": "webmaster_docs", "uri": "yandex://webmaster/docs", "mimeType": "text/plain"},
{"name": "audience_docs", "uri": "yandex://audience/docs", "mimeType": "text/plain"},
{"name": "admetrica_docs", "uri": "yandex://admetrica/docs", "mimeType": "text/plain"}
]
}3. ReadResource → yandex://direct/docs
# Яндекс.Директ API — Полная документация
## Структура данных
- Кампания (Campaign) → Группы (AdGroups) → Объявления (Ads) + Фразы (Keywords)
- Каждая кампания имеет: Id, Name, Status, StartDate, DailyBudget
## Статусы кампаний
- DRAFT — черновик, не запущена
- MODERATION — на проверке
- ACCEPTED — принята, готова к запуску
- RUNNING — активна, показываются объявления
- STOPPED — остановлена вручную
- ENDED — завершена (закончился бюджет или дата)
## Ограничения API
- Максимум 10000 объектов ...Полная длина: 1003 символа.
4. ListPrompts
{
"prompts": [
{
"name": "analyze_campaign_performance",
"description": "Анализ эффективности рекламной кампании за последние N дней.",
"arguments": [
{"name": "campaign_id", "required": true},
{"name": "days", "required": false}
]
},
{
"name": "suggest_budget_optimization",
"description": "Предложения по оптимизации бюджета рекламных кампаний.",
"arguments": [{"name": "account_id", "required": false}]
},
{
"name": "find_underperforming_ads",
"description": "Поиск неэффективных объявлений для оптимизации.",
"arguments": [{"name": "account_id", "required": false}]
}
]
}5. GetPrompt → analyze_campaign_performance(campaign_id=12345, days=7)
{
"description": "Анализ эффективности рекламной кампании за последние N дней.",
"messages": [{
"role": "user",
"content": {
"type": "text",
"text": "Проанализируй эффективность кампании 12345 за последние 7 дней.\n\nШАГИ:\n1. Получи контекст аккаунта через get_account_context\n2. Получи статистику кампании за период (используй get_direct_stats)\n3. Получи статистику за предыдущий аналогичный период для сравнения\n4. Рассчитай ключевые метрики: CTR, CPC, CR, CPA, ROI\n5. Выяви аномалии (резкие падения/росты)\n6. Предложи конкретные оптимизации\n\nФОРМАТ ОТВЕТА:\n- Краткое резюме (1-2 предложения)\n- Ключевые метрики (таблица)\n- Сравнение с предыдущим периодом\n- Выявленные проблемы\n- Рекомендации (приоритизированные)"
}
}]
}Полезные команды
# Проверить health
curl http://localhost:8000/ping
# Прямой запрос к MCP (JSON-RPC)
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Contributing
См. CONTRIBUTING.md.
License
MIT License — см. LICENSE.
Seed-данные для тестирования
Наполни SQLite тестовым пользователем с аккаунтом Директа (токен истёк вчера — триггернет auto-refresh):
uv run python -m scripts.seedПосле этого в Inspector при вызове get_direct_campaigns:
Сервер получит 401 от Яндекса
Попробует обновить токен через
refresh_account_tokenВернёт структурированную ошибку с
"yandex_api_error": true
Структура проекта
app/
├── main.py # FastMCP + регистрация инструментов/ресурсов/промптов
├── config.py # Pydantic Settings (Dual DB, Fernet, OAuth)
├── database.py # SQLAlchemy async engine
├── models.py # ORM: mcp_users, mcp_yandex_accounts (+ account_context)
├── crypto.py # TokenCrypto (Fernet)
├── context_parser.py # X-Bifrost-User-Id из контекста
├── apiforge_async.py # AsyncYandexClient + auto-refresh + ctx.logging
├── rate_limiter.py # In-memory per-user/per-tool rate limiter (30 req/min)
├── services/
│ └── account_service.py # AccountService (DB + refresh OAuth + context)
├── tools/
│ ├── accounts.py # list_yandex_accounts
│ ├── direct.py # get_direct_campaigns | stats | keywords | ads
│ ├── metrika.py # get_metrika_counters
│ ├── webmaster.py # get_webmaster_hosts
│ ├── audience.py # get_audience_segments
│ ├── admetrica.py # get_admetrica_campaigns
│ ├── account_management.py # get/update_account_context
│ ├── wordstat.py # get_wordstat_stats
│ └── feedback.py # submit_feedback
├── resources/
│ └── yandex_docs.py # MCP Resources: 5 API documentation endpoints
├── prompts/
│ └── yandex_scenarios.py # MCP Prompts: 3 analysis scenarios
├── yandex_configs/ # JSON-конфиги для apiforge
admin/
├── app.py # FastAPI admin panel
├── templates/ # Jinja2 HTML шаблоны
└── static/ # CSS
docs/ # Документация и JSON-RPC дампы
├── yandex-mcp-connection.md
├── yandex-tools-dump.json
├── yandex-resources-dump.json
├── yandex-prompts-dump.json
└── ...This server cannot be deployed
Maintenance
Related MCP Connectors
MCP for Yandex Direct: manage ad campaigns & analytics from Claude or ChatGPT
Read-only Yandex Metrika MCP. Query visits, sources, geo, devices and more in plain language.
Build, edit and sync Google, Microsoft, Reddit and Meta ad campaigns from your assistant.
Yandex search results, images, and SERP data via the Apify Yandex Search Scraper, hosted MCP.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables managing Yandex Direct PPC campaigns, ad groups, ads, and keywords, plus pulling performance statistics via the Yandex Direct API v5.44100 npm1MIT
- AlicenseBqualityBmaintenanceMCP server for managing Yandex Direct advertising, Yandex Metrica analytics, Wordstat keyword research, and Yandex Webmaster SEO tools, with self-configuring OAuth; provides 153 tools for complete ad and search workflows from AI assistants.1006 npm3MIT
- AlicenseAqualityDmaintenanceEnables AI assistants to manage Yandex Direct advertising campaigns, ads, keywords, and reports via natural language using the Yandex Direct API v5.21MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to work with Yandex Webmaster, Direct, and Metrika data through natural language, including managing sites, sitemaps, recrawls, ad campaigns with write-safety guards, and pulling traffic, conversion, and ad statistics.MIT