Yandex MCP Server
Enables interaction with Yandex advertising and analytics APIs (Direct, Metrika, Audience, Webmaster, AdMetrica) through MCP tools, resources, and prompts for campaign management and data retrieval.
README
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).
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/ping
MySQL (для высоких нагрузок)
# 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/ping
Admin Panel
Web UI для управления интеграциями с Яндексом. Доступен после деплоя.
| Route | Описание |
|---|---|
/admin/ |
Dashboard — список интеграций, статус токенов |
/admin/integrations/add |
Добавить интеграцию (Direct, Metrika и т.д.) |
/admin/oauth/callback |
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)
| Инструмент | Описание |
|---|---|
ping |
Health check |
list_yandex_accounts |
Список аккаунтов пользователя |
get_direct_campaigns |
Кампании Яндекс Директа |
get_metrika_counters |
Счётчики Яндекс Метрики |
get_webmaster_hosts |
Хосты Яндекс Вебмастера |
get_audience_segments |
Сегменты Яндекс Аудитории |
get_admetrica_campaigns |
Кампании Яндекс AdMetrica |
get_direct_stats |
Статистика кампании (Impressions, Clicks, CTR, CPC, Cost, Conversions) |
get_direct_keywords |
Ключевые слова кампании |
get_direct_ads |
Объявления кампании (Title, Text, Status, State) |
get_wordstat_stats |
Частотность ключевых слов (Wordstat) |
get_account_context |
Получить контекст аккаунта (бизнес-правила, заметки) |
update_account_context |
Обновить контекст аккаунта |
submit_feedback |
Отправить обратную связь о работе сервера |
MCP Resources (5)
LLM может запросить документацию по API прямо во время диалога — без галлюцинаций:
| Resource | Описание |
|---|---|
yandex://direct/docs |
Яндекс.Директ API: структура, статусы, ограничения, best practices |
yandex://metrika/docs |
Яндекс.Метрика API |
yandex://webmaster/docs |
Яндекс.Вебмастер API |
yandex://audience/docs |
Яндекс.Аудитории API |
yandex://admetrica/docs |
Яндекс.AdMetrica API |
Пример: ReadResource(yandex://direct/docs) → возвращает ~1000 символов документации.
MCP Prompts (3)
Готовые сценарии для LLM с типизированными аргументами:
| Prompt | Аргументы | Описание |
|---|---|---|
analyze_campaign_performance |
campaign_id (int), days (int, default 7) |
Детальный анализ кампании с шагами и форматом отчёта |
suggest_budget_optimization |
account_id (int, optional) |
Перераспределение бюджета на основе ROI |
find_underperforming_ads |
account_id (int, optional) |
Выявление объявлений с 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
└── ...
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.