Skip to main content
Glama
jmacaggi-gfm

ads-mcp-server

by jmacaggi-gfm

ads-mcp-server

Локальный MCP-сервер, предоставляющий данные о производительности Google Ads и Meta Marketing, настройки кампаний и историю изменений для Claude (Cowork) для рабочих процессов с ежедневными дашбордами в реальном времени.


Что он делает

Три инструмента, зарегистрированные в MCP:

Инструмент

Назначение

get_google_ads_report(date_range, breakdown)

Производительность + диагностика + 56-дневные ряды + WoW + сравнение по дням недели за 8 недель + настройки кампаний + история изменений

get_meta_ads_report(date_range, breakdown)

Аналогично Google. Конверсии фильтруются по META_CONVERSION_EVENT_NAME

get_campaign_settings(platform)

Настройки + история изменений для google / meta / both

Архитектура: получение необработанных данных ad×day один раз в час для каждой платформы, кэширование в parquet, вычисление всех агрегаций в pandas. Никаких API-запросов при каждом разбиении (breakdown).


Related MCP server: mcp-marketing-analytics

Предварительные требования

Ссылки для настройки учетных данных

Учетные данные

Где получить

GOOGLE_ADS_DEVELOPER_TOKEN

Google Ads UI → Инструменты → Центр API

GOOGLE_ADS_CLIENT_ID / CLIENT_SECRET

https://console.cloud.google.com → OAuth 2.0 client (Desktop app)

GOOGLE_ADS_REFRESH_TOKEN

Запустите python -m google.ads.googleads.examples.authentication.generate_user_credentials после установки google-ads

GOOGLE_ADS_CUSTOMER_IDS

Через запятую, без дефисов. Найти в правом верхнем углу Google Ads UI

GOOGLE_ADS_LOGIN_CUSTOMER_ID

ID аккаунта управляющего MCC, без дефисов

META_APP_ID / META_APP_SECRET

https://developers.facebook.com → Мои приложения → Настройки → Основные

META_ACCESS_TOKEN

https://business.facebook.com → Настройки компании → Системные пользователи → Создать новый токен (долгоживущий, с ads_read)

META_AD_ACCOUNT_ID

Meta Ads Manager → выбор аккаунта в левом верхнем углу. Формат: act_XXXXXXXXX


Установка

cd ~/marketing-ds/ads-mcp-server
uv sync --extra dev

uv создает .venv/ и устанавливает все зависимости, зафиксированные в pyproject.toml.


Настройка учетных данных

Два варианта:

Вариант А — указать на существующий .env (рекомендуется, если у вас уже есть ключи в ~/marketing-ds/decision_science/.env):

export ADS_MCP_ENV_FILE=/Users/jmacaggi/marketing-ds/decision_science/.env

Вариант Б — локальный .env:

cp .env.example .env
# fill in the blanks

Обязательные ключи перечислены в .env.example с комментариями, объясняющими каждый из них.


Запуск

Локально для тестирования:

uv run ads-mcp-server

Сервер общается по MCP через stdio — Cowork (или любой другой MCP-клиент) запускает его по требованию.


Подключение к Claude (Cowork)

Добавьте этот блок в ~/.claude/claude_desktop_config.json (создайте файл, если он отсутствует):

{
  "mcpServers": {
    "ads": {
      "command": "uv",
      "args": [
        "--directory",
        "/Users/jmacaggi/marketing-ds/ads-mcp-server",
        "run",
        "ads-mcp-server"
      ],
      "env": {
        "ADS_MCP_ENV_FILE": "/Users/jmacaggi/marketing-ds/decision_science/.env"
      }
    }
  }
}

Перезапустите Claude/Cowork. Инструменты get_google_ads_report, get_meta_ads_report, get_campaign_settings должны появиться.

Фоновый демон не требуется — Cowork запускает/останавливает процесс для каждой сессии.


Ежедневный предварительный прогрев (рекомендуется для живого дашборда)

Правило валидности кэша: кэш считается свежим, если он содержит дату вчерашнего дня. Обновляется раз в день. Первый запрос пользователя за день инициирует обновление — а получение данных за 56 дней для крупного аккаунта может занять 1-3 минуты.

Чтобы избежать этого ожидания, запланируйте предварительный прогрев на 6 утра через macOS launchd:

# Install
cp /Users/jmacaggi/marketing-ds/ads-mcp-server/launchd/com.jmacaggi.adsmcp.prewarm.plist \
   ~/Library/LaunchAgents/

launchctl load ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist

# Verify it's scheduled
launchctl list | grep adsmcp

# Trigger immediately (test)
launchctl start com.jmacaggi.adsmcp.prewarm

# Logs
tail -f ~/marketing-ds/ads-mcp-server/logs/prewarm.stdout.log
tail -f ~/marketing-ds/ads-mcp-server/logs/$(date +%Y-%m-%d).log

Что он делает каждое утро в 6:00:

  1. Получает данные производительности Google Ads за 56 дней, настройки, change_event за 29 дней → кэш

  2. (Meta в настоящее время отключена — см. "Статус Meta" ниже)

  3. Записывает метку обновления cache/google_lastrefresh.txt = сегодня

К тому времени, как вы откроете Cowork, данные Google будут актуальными. Вызовы инструментов будут возвращать результат менее чем за 1 секунду.

Для удаления:

launchctl unload ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
rm ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist

Статус Meta (по состоянию на 2026-05-07)

Инструменты Meta (get_meta_ads_report, get_campaign_settings(platform="meta"|"both")) структурно завершены, но еще не проверены в сквозном режиме.

Что работает:

  • Получение данных о производительности разбито на 7-дневные окна (позволяет избежать ошибки Service temporarily unavailable / subcode 1504044 "result too large")

  • Данные на уровне объявлений разделены: level=campaign для 56-дневных рядов, level=ad только для вчерашнего дня (позволяет избежать 5-минутной пагинации)

  • Получение AdSet фильтруется по effective_status IN [ACTIVE, PAUSED] (позволяет избежать пагинации тысяч архивированных групп объявлений)

Что нас блокировало:

  • После первого большого порционного получения данных о производительности, получение AdSet достигло почасового лимита Meta (code 17, subcode 2446079: "User request limit reached"). Время ожидания обычно составляет 10-60 минут.

Для повторного тестирования завтра утром (после сброса квоты):

# Remove --skip-meta from the launchd plist to enable Meta in pre-warm
sed -i '' '/<string>--skip-meta<\/string>/d' \
   ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
launchctl unload ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist
launchctl load ~/Library/LaunchAgents/com.jmacaggi.adsmcp.prewarm.plist

# Or run manually
ADS_MCP_ENV_FILE=/Users/jmacaggi/marketing-ds/decision_science/.env \
   uv run python scripts/prewarm.py

Если Meta продолжит ограничивать скорость, возможные запасные варианты (еще не реализованы):

  • Асинхронный запуск отчетов (async=True) для получения данных о производительности

  • Более строгий фильтр effective_status (только ACTIVE, исключить приостановленные)

Если вы предпочитаете долго работающий фоновый процесс (необязательно, не требуется для Cowork): используйте nohup uv run ads-mcp-server > /tmp/ads-mcp.log 2>&1 & или plist для launchd.


Дополнительно: переопределение через CSV (в обход API)

Google Ads UI позволяет экспортировать отчеты в CSV без ограничений квоты API. Поместите CSV в cache/external/, чтобы переопределить получение данных через API:

cache/external/google_2026-05-07.csv
cache/external/meta_2026-05-07.csv

Если соответствующий CSV существует И он новее, чем кэш parquet, сервер загрузит его вместо вызова API. В ответе будет установлено metadata.data_source = "csv_override", чтобы Cowork знал об этом.

Схема столбцов CSV должна соответствовать parquet (см. src/ads_mcp_server/google_ads.py и meta_ads.py для имен столбцов: date, campaign_id, campaign_name, ad_id, ad_name, spend, impressions, clicks, conversions, ...).


Тестирование

uv run pytest -v

Все тесты основаны на моках — никаких сетевых вызовов. Покрывают:

  • classify_campaign (Брендовые/Небрендовые/Другое)

  • diagnose (5-состояний классификатора)

  • Выбор 8 недель по тем же дням недели (выбирает правильные 8 дат)

  • Дельта WoW + деление на ноль

  • Фильтр actions[] для Meta

  • Сравнение снимков (snapshot diff), включая нулевые старые значения и очистку

  • Отсутствие учетных данных возвращает чистую ошибку (без исключения)


Логи

Каждый вызов API и ошибка записываются в logs/YYYY-MM-DD.log (один файл в день).


Устранение неполадок

  • Ошибка установки google-ads: убедитесь, что Python 3.13 (uv python pin 3.13) и pip install grpcio работают в вашей системе. На Apple Silicon: arch -arm64 uv sync.

  • Истек срок действия токена Meta: пересоздайте токен системного пользователя в "Настройках компании"; долгоживущие токены действуют 60 дней.

  • Инструмент не появляется в Cowork: проверьте ~/Library/Logs/Claude/mcp*.log на наличие ошибок запуска. Убедитесь, что uv находится в PATH для графического процесса (возможно, потребуется полный путь: which uv).

  • Устаревший кэш: удалите cache/*.parquet, чтобы принудительно выполнить свежее получение данных.


Карта файлов

src/ads_mcp_server/
  server.py        # MCP entry + tool handlers
  config.py        # env loading, validates creds
  google_ads.py    # 3 GAQL queries: perf, settings, change_event
  meta_ads.py      # Insights + AdSet pull
  snapshots.py     # Meta snapshot diff (Meta has no reliable change API)
  cache.py         # parquet + CSV override
  aggregate.py     # all pandas math
  classify.py      # Brand/NB/Other
  diagnose.py      # 5-state diagnosis
  date_ranges.py   # window resolution + 8wk DoW
  retry.py         # exponential backoff
  logging_setup.py # daily file logs
  schema.py        # response shape constants

Available Tools

3 tools
get_campaign_settingsC

Current campaign settings + 56-day change history per platform.

ParametersJSON Schema
NameRequiredDescriptionDefault
platformYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must fully convey behavioral traits. It discloses that the tool returns both settings and a 56-day history, but does not indicate whether it is read-only, any authentication needs, rate limits, or what triggers destructive actions. The behavior is partially described but lacks completeness.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, making it very concise, but it omits important details such as parameter semantics and usage context. Conciseness is achieved at the expense of completeness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema, no annotations), the description is insufficient. It does not explain the output structure, whether the data is aggregated per platform, or provide examples. The lack of detail makes it hard for an AI agent to fully understand the tool's capabilities.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has one parameter 'platform' with enum values, but the description does not explain the parameter's meaning beyond 'per platform'. It fails to clarify what 'both' implies or how the parameter affects the output. With 0% schema description coverage, the description adds no value over the schema itself.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves 'current campaign settings + 56-day change history per platform', which is a specific verb+resource. However, it does not explicitly differentiate itself from sibling tools like get_google_ads_report or get_meta_ads_report, which are focused on ads reports rather than settings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as get_google_ads_report or get_meta_ads_report. It does not mention exclusion criteria or context for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_google_ads_reportA

Pull Google Ads performance. Returns account totals, campaign-type breakdown, top-50 per-ad rows with diagnosis, 56-day daily series, and WoW + 8-week DoW comparisons. Set include_campaign_settings=True to also return per-campaign settings (target CPA, daily budget, diagnosis, utilization) for ENABLED campaigns only.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_rangeYes
breakdownYes
include_campaign_settingsNoIf true, attach campaign_settings list to the response. Defaults to false to keep payload small.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, but the description details return components and the conditional behavior of include_campaign_settings (only for ENABLED campaigns).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences, no fluff, front-loaded with purpose and outputs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Description covers essential behavioral and parameter details despite lack of output schema; minor gaps in rate limits or authentication info.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is low (33%), but the description adds meaning to parameters by linking them to return elements (e.g., 'campaign-type breakdown' for breakdown enum).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Pull Google Ads performance' and lists specific outputs, distinguishing it from siblings like get_meta_ads_report and get_campaign_settings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its use for Google Ads performance but does not explicitly guide when to use this tool over siblings or provide exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_meta_ads_reportB

Pull Meta Ads performance. Same shape as get_google_ads_report. Conversions filtered to META_CONVERSION_EVENT_NAME.

ParametersJSON Schema
NameRequiredDescriptionDefault
date_rangeYes
breakdownYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It only mentions the output shape similarity and a conversion filter, but lacks details on side effects, rate limits, authentication needs, or other behavioral traits. This is minimal disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with two short sentences, each providing distinct value. It front-loads the key information and avoids fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description should explain the report contents. It mentions a conversion filter but does not list other metrics or describe the full structure. Relying on the shape of get_google_ads_report is insufficient without that tool's description being present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description should add meaning to parameters. It does not explain the 'date_range' or 'breakdown' parameters beyond their enum values, which are self-explanatory but not enriched. This is a significant gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The name and description clearly indicate this tool retrieves Meta Ads performance data. The verb 'Pull' is specific, and the description explicitly states it is analogous to get_google_ads_report, which distinguishes it from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by comparing to get_google_ads_report, but does not provide explicit guidance on when to use this tool versus alternatives or any prerequisites. No exclusions or when-not-to-use information is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedget_campaign_settings
    • First observedget_google_ads_report
    • First observedget_meta_ads_report

TDQS

B3.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct area: campaign settings, Google Ads performance, and Meta Ads performance. No overlap; descriptions clearly differentiate them.

Naming Consistency5/5

All tool names follow a consistent 'get_' prefix with the specific resource (campaign_settings, google_ads_report, meta_ads_report). Consistent snake_case pattern.

Tool Count4/5

Three tools is minimal but appropriate for a focused ads reporting and settings retrieval server. Could be expanded but current count is reasonable for the stated purpose.

Completeness2/5

Only read operations are exposed; no create, update, or delete tools for campaigns or ads. Significant gaps for a full ads management workflow.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides access to Google Ads API for comprehensive campaign analytics, enabling conversational ad performance analysis with Claude Code.
    25 npm
    2
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Connect Claude to your marketing data from Google and Meta, enabling read and write operations on Search Console, Analytics, Tag Manager, Business Profile, and Meta platforms.
    35
    Apache 2.0