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
Yandex Direct, Metrika & Wordstat MCP for Russian digital marketing.
Read-only Yandex Metrika MCP. Query visits, sources, geo, devices and more in plain language.
MCP servers for Yandex APIs: Wordstat, Search, Webmaster, Metrika, Direct. Open source, by Seyka AI.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables managing Yandex Direct PPC campaigns, ad groups, ads, and keywords, plus pulling performance statistics via the Yandex Direct API v5.46951 npm3MIT
- AlicenseBqualityCmaintenanceMCP 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 gradedqualityCmaintenanceEnables 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