Skip to main content
Glama
Apple Ads MCP

Apple Ads MCP

by AppVisionOS

apple-search-ads-mcp

CI npm version npm downloads License: MIT Node MCP Glama MCP server

Сервер протокола контекста модели (MCP), который оборачивает полный API управления кампаниями Apple Search Ads (теперь Apple Ads) v5. 74 типизированных инструмента, прямое соответствие (1:1) каждому задокументированному эндпоинту v5 — кампании, группы объявлений, объявления, креативы, пользовательские страницы продукта, ключевые слова, минус-слова, отчеты, отчеты о доле показов, бюджетные заказы, списки контроля доступа (ACL), гео/поиск приложений, метаданные приложений, аудит причин отклонения — плюс возможность прямого запроса для любых будущих эндпоинтов.

Жизненный цикл API: Apple Ads (Search Ads) v5 — это текущий рабочий API. Поддержка v5 прекращается 26 января 2027 года в пользу нового «Apple Ads Platform API», который появится летом 2026 года. Этот сервер ориентирован на версии v5.0 → v5.5.

Быстрая установка

git clone https://github.com/AppVisionOS/apple-search-ads-mcp.git
cd apple-search-ads-mcp
npm install
npm run build

Затем зарегистрируйте его в Claude Code одной строкой:

claude mcp add apple-search-ads --scope user \
  -e ASA_CLIENT_ID=SEARCHADS.xxxx \
  -e ASA_TEAM_ID=SEARCHADS.xxxx \
  -e ASA_KEY_ID=xxxx \
  -e ASA_PRIVATE_KEY_PATH=/absolute/path/to/asa-private.p8 \
  -e ASA_ORG_ID=1234567 \
  -- node $(pwd)/dist/index.js

Related MCP server: aapl-ads-mcp

Настройка

1. Получение учетных данных API

Интерфейс Apple Ads разделяет учетные данные на два экрана. Вкладка API в настройках аккаунта управляет доступом только для сторонних поставщиков услуг; для вашего собственного программного доступа процесс сначала проходит через Управление пользователями.

а) Приглашение пользователя API

В app-ads.apple.com → Account Settings → User Management → Invite User:

  • Email: любой адрес, который вы контролируете (может быть вашим собственным; Apple требует отдельный Apple ID для пользователя API)

  • Роль: выберите ту, у которой есть разрешения API (например, API Account Manager)

  • Отправьте приглашение, затем примите его из почтового ящика приглашенного пользователя

б) Генерация пары ключей локально

Пока приглашение обрабатывается, сгенерируйте пару ключей ES256 на своем компьютере. Убедитесь, что это PKCS#8 — примеры Apple .p8 и старый вывод openssl ecparam не являются PKCS#8, и jose не сможет их загрузить.

# CORRECT — produces PKCS#8 (-----BEGIN PRIVATE KEY-----)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out asa-private.p8
openssl ec -in asa-private.p8 -pubout -out asa-public.pem

# If you already produced traditional EC (-----BEGIN EC PRIVATE KEY-----), convert it:
#   openssl pkcs8 -topk8 -nocrypt -in asa-private.p8 -out asa-private-pkcs8.p8

Храните asa-private.p8 в безопасном месте (например, ~/.apple-search-ads/, chmod 600). Вы вставите в Apple только публичную часть.

в) Генерация клиента API

Выйдите из системы и войдите снова как приглашенный пользователь API (не под учетной записью администратора). Перейдите в Account Settings → API. Вы увидите экран Client Credentials с текстовым полем Public Key — оно появляется только у пользователей, имеющих роль API.

  1. Вставьте содержимое asa-public.pem (с маркерами -----BEGIN PUBLIC KEY----- / -----END PUBLIC KEY-----).

  2. Нажмите Generate API Client.

  3. Скопируйте три значения, которые покажет Apple: Client ID, Team ID, Key ID — позже они не появятся.

2. Установка

npm install
npm run build

3. Конфигурация

Скопируйте .env.example в .env и заполните его или передайте переменные окружения через ваш MCP-клиент.

ASA_CLIENT_ID=SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ASA_TEAM_ID=SEARCHADS.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ASA_KEY_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ASA_PRIVATE_KEY_PATH=/absolute/path/to/private-key.p8
ASA_ORG_ID=1234567   # optional default; can be overridden per call

ASA_PRIVATE_KEY (содержимое PEM в строке, с экранированием \n, если передается через JSON) поддерживается как альтернатива ASA_PRIVATE_KEY_PATH.

4. Подключение к вашему MCP-клиенту

{
  "mcpServers": {
    "apple-search-ads": {
      "command": "node",
      "args": ["/absolute/path/to/apple-search-ads-mcp/dist/index.js"],
      "env": {
        "ASA_CLIENT_ID": "SEARCHADS.xxxx...",
        "ASA_TEAM_ID": "SEARCHADS.xxxx...",
        "ASA_KEY_ID": "xxxx...",
        "ASA_PRIVATE_KEY_PATH": "/absolute/path/to/private-key.p8",
        "ASA_ORG_ID": "1234567"
      }
    }
  }
}

Аутентификация

Сервер обрабатывает поток OAuth 2.0 client-credentials с использованием утверждения клиента JWT ES256:

  1. Подпишите JWT своим закрытым ключом .p8 (заголовок: kid=Key ID, alg=ES256; полезная нагрузка: iss=Team ID, sub=Client ID, aud=https://appleid.apple.com).

  2. Отправьте его POST-запросом на https://appleid.apple.com/auth/oauth2/token с параметрами grant_type=client_credentials и scope=searchadsorg.

  3. Используйте полученный токен доступа (действует 1 час) с заголовками Authorization: Bearer … и X-AP-Context: orgId=… при каждом вызове API.

Токен кэшируется в памяти примерно за 30 секунд до истечения срока действия, поэтому вы подписываете одно утверждение и обмениваете один токен в час. При получении 401 сервер принудительно обновляет токен и повторяет попытку один раз. При 429/5xx он делает паузу (соблюдая Retry-After) до 3 раз.

Инвентарь инструментов (74 инструмента)

Аккаунт и доступ (2)

org_acls, me_user — вызывайте без контекста организации, чтобы узнать, что может ваш токен.

Обнаружение (3)

search_apps, search_geo, geo_lookup

Метаданные приложений (6)

apps_get, apps_locale_details, apps_eligibilities_find, apps_assets_find, creative_app_preview_devices, countries_or_regions_list

Пользовательские страницы продукта (3)

cpp_list, cpp_get, cpp_locale_details

Кампании (6)

campaigns_create, campaigns_get, campaigns_list, campaigns_find, campaigns_update, campaigns_delete

Группы объявлений (7)

adgroups_create, adgroups_get, adgroups_list, adgroups_find_in_campaign, adgroups_find_org_wide, adgroups_update, adgroups_delete

Креативы (4)

creatives_create, creatives_list, creatives_get, creatives_find — креативы оборачивают ссылку на пользовательскую страницу продукта, страницу продукта по умолчанию или набор креативов. Объявления привязываются к креативам через creativeId.

Объявления (7)

ads_create, ads_get, ads_list, ads_find_in_campaign, ads_find_org_wide, ads_update, ads_delete

Таргетинг по ключевым словам (7)

targeting_keywords_create, targeting_keywords_get, targeting_keywords_list, targeting_keywords_find, targeting_keywords_update, targeting_keywords_delete (массовое), targeting_keywords_delete_single

Минус-слова — область действия группы объявлений (6)

adgroup_negative_keywords_create, adgroup_negative_keywords_get, adgroup_negative_keywords_list, adgroup_negative_keywords_find, adgroup_negative_keywords_update, adgroup_negative_keywords_delete

Минус-слова — область действия кампании (6)

campaign_negative_keywords_create, campaign_negative_keywords_get, campaign_negative_keywords_list, campaign_negative_keywords_find, campaign_negative_keywords_update, campaign_negative_keywords_delete

Отчеты (7)

Инструмент

Эндпоинт

reports_campaigns

POST /reports/campaigns

reports_adgroups

POST /reports/campaigns/{id}/adgroups

reports_keywords_in_campaign

POST /reports/campaigns/{id}/keywords

reports_keywords_in_adgroup

POST /reports/campaigns/{id}/adgroups/{id}/keywords

reports_search_terms_in_campaign

POST /reports/campaigns/{id}/searchterms

reports_search_terms_in_adgroup

POST /reports/campaigns/{id}/adgroups/{id}/searchterms

reports_ads_in_campaign

POST /reports/campaigns/{id}/ads

Все принимают startTime, endTime, необязательный granularity (HOURLY/DAILY/WEEKLY/MONTHLY), необязательный groupBy (adminArea / ageRange / countryCode / countryOrRegion / deviceClass / gender / locality), selector, returnRowTotals, returnGrandTotals, returnRecordsWithNoMetrics, timeZone (UTC | ORTZ).

Отчеты о доле показов (3) — асинхронные

custom_reports_create → возвращает reportId. Опрашивайте с помощью custom_reports_get, пока state=COMPLETED. Список через custom_reports_list.

Бюджетные заказы (4) — только для аккаунтов LOC

budget_orders_create, budget_orders_get, budget_orders_list, budget_orders_update. В v5 нет удаления для бюджетных заказов.

Аудит причин отклонения (2)

product_page_reasons_find, product_page_reasons_get — проверка только для чтения, почему рецензенты Apple отклонили креативы.

Запасной вариант (1)

apple_search_ads_request — вызов любого пути с любым методом. Аутентификация и контекст организации по-прежнему обрабатываются за вас.

Селекторы

Инструменты *_find принимают грамматику селекторов Apple:

{
  "conditions": [
    { "field": "status", "operator": "EQUALS", "values": ["ENABLED"] },
    { "field": "countriesOrRegions", "operator": "CONTAINS_ANY", "values": ["US", "GB"] }
  ],
  "fields": ["id", "name", "status"],
  "orderBy": [{ "field": "name", "sortOrder": "ASCENDING" }],
  "pagination": { "limit": 100, "offset": 0 }
}

Операторы: EQUALS, NOT_EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH, GREATER_THAN, LESS_THAN, IN, NOT_IN, CONTAINS_ALL, CONTAINS_ANY, BETWEEN. values всегда является массивом.

Сквозной пример

Рабочий процесс, который можно полностью реализовать через Claude:

  1. org_acls → выберите orgId.

  2. search_apps для вашего приложения → получите adamId.

  3. campaigns_create с этим adamId, дневным бюджетом, таргетингом на США, adChannelType=SEARCH, supplySources=["APPSTORE_SEARCH_RESULTS"], billingEvent=TAPS.

  4. adgroups_create внутри кампании с defaultBidAmount={amount:"1.00",currency:"USD"} и pricingModel=CPC.

  5. targeting_keywords_create с пакетом строк {text, matchType, bidAmount}.

  6. cpp_list → выберите productPageId → creatives_create с type=CUSTOM_PRODUCT_PAGE для создания creativeId → ads_create для привязки к группе объявлений.

  7. Подождите несколько дней. reports_campaigns для общих показателей, затем reports_search_terms_in_campaign для сбора новых ключевых слов / минус-слов.

  8. custom_reports_create для доли показов / доли голоса по вашим топовым поисковым запросам.

Известные особенности (нюансы v5)

  • Нет устаревшего CRUD для наборов креативов. Apple удалила его в v5; вместо этого создайте строку creatives и ссылайтесь на нее из ads.creativeId.

  • Нет эндпоинта категорий приложений. Используйте apps_get и читайте primaryGenre / secondaryGenre.

  • Нет геотаргетинга по почтовым индексам. Гео-сущности в v5 — это только Country / AdminArea / Locality.

  • Нет поиска ключевых слов или поиска ключевых слов в рамках группы объявлений по всей организации. Apple ограничивает поиск ключевых слов уровнем кампании (/campaigns/{id}/adgroups/targetingkeywords/find) и суммирует их по группам объявлений; фильтруйте по adGroupId в селекторе для сужения области.

  • Нет DELETE для бюджетных заказов. Обновляйте их, не удаляйте.

  • Аудитории, прогнозирование, события конверсии НЕ входят в v5 — они находятся в отдельных API Apple (AdServices Attribution и т.д.).

Локальная разработка

npm run dev        # tsc --watch
npm run typecheck  # one-shot type check
npm run build      # compile to dist/

Используйте apple_search_ads_request для отладки любого эндпоинта напрямую — он возвращает необработанный конверт, чтобы вы могли увидеть точную форму ответа, которую вернула Apple.

Available Tools

74 tools
adgroup_negative_keywords_createC

Bulk-create negative keywords on an ad group.

Inputs: campaignId (required), adGroupId (required), keywords (required), orgId.

adgroup_negative_keywords_deleteB

Bulk-delete ad-group-level negative keywords by ID.

Inputs: campaignId (required), adGroupId (required), keywordIds (required), orgId.

adgroup_negative_keywords_findB

Find ad-group-level negative keywords across all ad groups in a campaign with a selector.

Inputs: campaignId (required), selector (required), orgId.

adgroup_negative_keywords_getB

Fetch a single ad-group-level negative keyword by ID.

Inputs: campaignId (required), adGroupId (required), keywordId (required), orgId.

adgroup_negative_keywords_listB

List ad-group-level negative keywords (paginated).

Inputs: campaignId (required), adGroupId (required), limit, offset, +1 more.

adgroup_negative_keywords_updateC

Bulk-update ad-group-level negative keywords. Each entry must include id.

Inputs: campaignId (required), adGroupId (required), keywords (required), orgId.

adgroups_createB

Create an ad group within a campaign. Bid + targeting live here, not on the campaign.

Inputs: campaignId (required), name (required), startTime (required), defaultBidAmount (required), +9 more.

adgroups_deleteC

Delete an ad group.

Inputs: campaignId (required), adGroupId (required), orgId.

adgroups_find_in_campaignA

Find ad groups within a single campaign using a selector.

Inputs: campaignId (required), selector (required), orgId.

adgroups_find_org_wideA

Find ad groups across the entire org with a selector.

Inputs: selector (required), orgId.

adgroups_getC

Fetch a single ad group.

Inputs: campaignId (required), adGroupId (required), orgId.

adgroups_listC

List all ad groups in a campaign (paginated).

Inputs: campaignId (required), limit, offset, orgId.

adgroups_updateC

Update an ad group. Pass only the fields you want to change.

Inputs: campaignId (required), adGroupId (required), adGroup (required), orgId.

ads_createB

Create an ad inside an ad group. Ads bind a Creative (creativeId) to the ad group; the creative itself can wrap a Custom Product Page, Default Product Page, or Creative Set reference.

Inputs: campaignId (required), adGroupId (required), ad (required), orgId.

ads_deleteC

Delete an ad.

Inputs: campaignId (required), adGroupId (required), adId (required), orgId.

ads_find_in_campaignA

Find ads across all ad groups in a campaign with a selector.

Inputs: campaignId (required), selector (required), orgId.

ads_find_org_wideB

Find ads across the entire org with a selector.

Inputs: selector (required), orgId.

ads_getC

Fetch a single ad by ID.

Inputs: campaignId (required), adGroupId (required), adId (required), orgId.

ads_listB

List all ads in an ad group.

Inputs: campaignId (required), adGroupId (required), limit, offset, +1 more.

ads_updateB

Update an ad — typically status, name, or repointing to a different creativeId.

Inputs: campaignId (required), adGroupId (required), adId (required), ad (required), +1 more.

apple_search_ads_requestA

Escape hatch: call any Apple Search Ads endpoint by method + path. Authentication and org context are handled for you. Use only if no dedicated tool covers the endpoint you need.

Inputs: method (required), path (required), query, body, +2 more.

apps_assets_findB

Find App Store screenshots / app-preview assets for an app — returns assetGenIds you can use to author creatives or audit rejected assets.

Inputs: adamId (required), selector (required), orgId.

apps_eligibilities_findA

Find app-eligibility records by selector (filterable by supplySource, countryOrRegion, deviceClass, state).

Inputs: adamId (required), selector (required), orgId.

apps_getC

Fetch App Store metadata for an app: appName, developerName, primaryGenre, secondaryGenre, iconPictureUrl, availableStorefronts, deviceClasses, etc.

Inputs: adamId (required), orgId.

apps_locale_detailsB

Get localized default product-page details for an app (subtitle, short description, screenshots, app preview) per locale.

Inputs: adamId (required), orgId.

budget_orders_createB

Create a budget order (LOC accounts only). Wraps Apple's {bo, orgIds} envelope.

Inputs: name (required), budget (required), startDate (required), endDate (required), +8 more.

budget_orders_getB

Fetch a single budget order by ID.

Inputs: budgetOrderId (required), orgId.

budget_orders_listB

List all budget orders in the org (paginated).

Inputs: limit, offset, orgId.

budget_orders_updateC

Update a budget order. Most fields are editable post-creation; status is read-only. v5 has no delete endpoint for budget orders.

Inputs: budgetOrderId (required), bo (required), orgIds, orgId.

campaign_negative_keywords_createB

Bulk-create campaign-level negative keywords (apply across all ad groups).

Inputs: campaignId (required), keywords (required), orgId.

campaign_negative_keywords_deleteC

Bulk-delete campaign-level negative keywords by ID.

Inputs: campaignId (required), keywordIds (required), orgId.

campaign_negative_keywords_findB

Find campaign-level negative keywords within a single campaign with a selector.

Inputs: campaignId (required), selector (required), orgId.

campaign_negative_keywords_getB

Fetch a single campaign-level negative keyword by ID.

Inputs: campaignId (required), keywordId (required), orgId.

campaign_negative_keywords_listC

List campaign-level negative keywords (paginated).

Inputs: campaignId (required), limit, offset, orgId.

campaign_negative_keywords_updateC

Bulk-update campaign-level negative keywords.

Inputs: campaignId (required), keywords (required), orgId.

campaigns_createB

Create a new campaign. The minimum useful body specifies adamId, name, countriesOrRegions, adChannelType, supplySources, billingEvent, and a budget.

Inputs: name (required), adamId (required), countriesOrRegions (required), adChannelType (required), +14 more.

campaigns_deleteB

Permanently delete a campaign. Cannot be undone.

Inputs: campaignId (required), orgId.

campaigns_findA

Search campaigns with a selector — supports conditions (EQUALS/IN/CONTAINS/...), orderBy, and pagination.

Inputs: selector (required), orgId.

campaigns_getB

Fetch a single campaign by ID.

Inputs: campaignId (required), orgId.

campaigns_listA

List all campaigns in the org (paginated). For richer filtering use campaigns_find.

Inputs: limit, offset, orgId.

campaigns_updateA

Update a campaign. Pass only the fields you want to change. Use clearGeoTargetingOnCountryOrRegionChange=true if you change countriesOrRegions.

Inputs: campaignId (required), campaign (required), clearGeoTargetingOnCountryOrRegionChange, orgId.

countries_or_regions_listA

List supported countries / regions with their default and supported product-page languages.

Inputs: orgId.

cpp_getB

Fetch a single Custom Product Page by ID.

Inputs: adamId (required), productPageId (required), orgId.

cpp_listC

List Custom Product Pages for an app.

Inputs: adamId (required), orgId.

cpp_locale_detailsB

List the locales available for a Custom Product Page (with localized assets per locale).

Inputs: adamId (required), productPageId (required), orgId.

creative_app_preview_devicesA

List supported app-preview device-size mappings (e.g. IPHONE_61, IPAD_129). Used when authoring creatives or interpreting screenshot/preview metadata.

Inputs: orgId.

creatives_createC

Create a creative (a reference to a default product page, custom product page, or creative set). Ads bind to creatives via creativeId.

Inputs: name (required), adamId (required), type (required), productPageId, +2 more.

creatives_findC

Find creatives across the org with a selector.

Inputs: selector (required), orgId.

creatives_getB

Fetch a single creative by ID.

Inputs: creativeId (required), orgId.

creatives_listB

List all creatives in the org (paginated).

Inputs: limit, offset, orgId.

custom_reports_createB

Create an Impression Share (Share of Voice) report — async. Returns a reportId you poll with custom_reports_get until state=COMPLETED.

Inputs: name (required), startTime (required), endTime (required), granularity, +3 more.

custom_reports_getA

Fetch a single Impression Share report — poll until state=COMPLETED to read rows (rank, impressionShare, lowImpressionShare, highImpressionShare, searchPopularity).

Inputs: reportId (required), orgId.

custom_reports_listB

List all Impression Share reports created in the org.

Inputs: limit, offset, orgId.

geo_lookupA

Resolve geos by raw IDs. Each request item is { id: 'CountryCode|adminArea|locality', entity: 'Country|AdminArea|Locality' }. Useful when a report returns geo IDs you want named.

Inputs: requests (required), orgId.

me_userA

Return information about the calling API user (userId, parentOrgId).

Inputs: no named parameters.

org_aclsA

List all org-level ACLs (orgs your API user can access, with orgName / currency / paymentModel / roleNames). Use this to discover the orgId for ASA_ORG_ID. Does not require X-AP-Context.

Inputs: no named parameters.

product_page_reasons_findB

Find ad-creative rejection reasons (filterable by adamId, productPageId, assetGenId, countryOrRegion, languageCode, supplySource, reasonLevel). Use this to audit why a creative was rejected by Apple's review team.

Inputs: selector (required), orgId.

product_page_reasons_getB

Fetch a single rejection reason by ID.

Inputs: productPageReasonId (required), orgId.

reports_adgroupsC

Ad-group-level report within a single campaign.

Inputs: campaignId (required), startTime (required), endTime (required), granularity, +7 more.

reports_ads_in_campaignB

Ad-level performance (per Custom Product Page / creative variation) rolled up across the campaign.

Inputs: campaignId (required), startTime (required), endTime (required), granularity, +7 more.

reports_campaignsA

Campaign-level performance report. Returns rows with impressions, taps, installs, spend, CPT/CPM/CPI, conversion rate, etc. Pass groupBy to pivot by country, device, age, gender.

Inputs: startTime (required), endTime (required), granularity, timeZone, +6 more.

reports_keywords_in_adgroupC

Keyword report scoped to a single ad group.

Inputs: campaignId (required), adGroupId (required), startTime (required), endTime (required), +8 more.

reports_keywords_in_campaignC

Keyword report rolled up across all ad groups in one campaign.

Inputs: campaignId (required), startTime (required), endTime (required), granularity, +7 more.

reports_search_terms_in_adgroupC

Search-terms report scoped to a single ad group.

Inputs: campaignId (required), adGroupId (required), startTime (required), endTime (required), +8 more.

reports_search_terms_in_campaignB

Search-terms report rolled up across all ad groups in a campaign. Reveals what users actually typed — harvest new keywords or negatives from here.

Inputs: campaignId (required), startTime (required), endTime (required), granularity, +7 more.

search_appsA

Search the App Store for apps to target / advertise. Returns adamId, name, developerName, and country availability. You need adamId to create campaigns.

Inputs: query (required), returnOwnedApps, limit, offset, +1 more.

search_geoB

Search geo entities by name (Country / AdminArea / Locality). Pass countrycode (lowercase, Apple's quirk) to scope an admin-area or locality search to one country.

Inputs: query (required), entity (required), countrycode, limit, +2 more.

targeting_keywords_createB

Bulk-create targeting (positive) keywords on an ad group. Pass up to 1000 per call.

Inputs: campaignId (required), adGroupId (required), keywords (required), orgId.

targeting_keywords_deleteC

Bulk-delete targeting keywords by ID.

Inputs: campaignId (required), adGroupId (required), keywordIds (required), orgId.

targeting_keywords_delete_singleB

Delete a single targeting keyword by ID (uses Apple's REST DELETE variant).

Inputs: campaignId (required), adGroupId (required), keywordId (required), orgId.

targeting_keywords_findA

Find targeting keywords across all ad groups in a campaign with a selector. Apple does not expose a per-ad-group find — filter by adGroupId in the selector if needed.

Inputs: campaignId (required), selector (required), orgId.

targeting_keywords_getC

Fetch a single targeting keyword by ID.

Inputs: campaignId (required), adGroupId (required), keywordId (required), orgId.

targeting_keywords_listB

List targeting keywords on an ad group (paginated).

Inputs: campaignId (required), adGroupId (required), limit, offset, +1 more.

targeting_keywords_updateB

Bulk-update targeting keywords (status, bid, text, matchType). Each entry must include id.

Inputs: campaignId (required), adGroupId (required), keywords (required), orgId.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 74 tools

    Disambiguation5/5

    Each tool targets a distinct resource and action, with clear prefixes like adgroups_, campaigns_, targeting_keywords_, etc., so there is no ambiguity between tools.

    Naming Consistency5/5

    All tool names follow a consistent snake_case verb_noun pattern (e.g., adgroups_create, campaigns_list, custom_reports_create), with very few deviations like delete_single, which is still clear.

    Tool Count4/5

    With 74 tools, the count is high but appropriate for the comprehensive Apple Search Ads API covering many resources and operations. Each tool serves a specific purpose, though the number exceeds typical well-scoped servers.

    Completeness5/5

    The tool set covers all major workflows: CRUD for campaigns, ad groups, ads, keywords, negatives, creatives, budget orders; reporting; app and geo search; org management. The escape hatch handles any missing endpoints, ensuring no dead ends.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Apple Search Ads API v5 (read-only). Campaigns, ad groups, keywords, performance reports.
      9
      1
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      Typed MCP server for OpenAI Ads and ChatGPT Ads via the Advertiser API. Supports account, campaign, ad group, ad, creative, audience, insight, and conversion tools with readonly mode and guarded writes.
      12
      4
      MIT