Apple Ads MCP
apple-search-ads-mcp
Ein Model Context Protocol (MCP) Server, der die vollständige Apple Search Ads (jetzt Apple Ads) Campaign Management API v5 kapselt. 74 typisierte Tools, 1:1-Abbildung auf jeden dokumentierten v5-Endpunkt — Kampagnen, Anzeigengruppen, Anzeigen, Creatives, benutzerdefinierte Produktseiten, Keywords, negative Keywords, Berichte, Impression-Share-Berichte, Budgetaufträge, ACLs, Geo-/App-Suche, App-Metadaten, Audits von Ablehnungsgründen — plus ein Raw-Passthrough für zukünftige Endpunkte.
API-Lebenszyklus: Apple Ads (Search Ads) v5 ist die aktuelle Produktions-API. v5 wird am 26. Januar 2027 zugunsten der neuen "Apple Ads Platform API", die im Sommer 2026 erscheint, eingestellt. Dieser Server zielt auf v5.0 → v5.5 ab.
Schnellinstallation
git clone https://github.com/AppVisionOS/apple-search-ads-mcp.git
cd apple-search-ads-mcp
npm install
npm run buildDann mit einer Zeile bei Claude Code registrieren:
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.jsEinrichtung
1. API-Zugangsdaten abrufen
Die Apple Ads-Benutzeroberfläche teilt die Zugangsdaten auf zwei Bildschirme auf. Der Tab API in den Kontoeinstellungen verwaltet nur den Zugriff für Drittanbieter; für Ihren eigenen programmatischen Zugriff führt der Weg zuerst über die Benutzerverwaltung.
a) API-Benutzer einladen
Unter app-ads.apple.com → Kontoeinstellungen → Benutzerverwaltung → Benutzer einladen:
E-Mail: Jede Adresse, die Sie kontrollieren (kann Ihre eigene sein; Apple erfordert eine separate Apple ID für den API-Benutzer)
Rolle: Wählen Sie eine mit API-Berechtigungen (z. B. API Account Manager)
Senden Sie die Einladung und akzeptieren Sie diese dann im Posteingang des eingeladenen Benutzers
b) Schlüsselpaar lokal generieren
Während die Einladung bearbeitet wird, generieren Sie ein ES256-Schlüsselpaar auf Ihrem Rechner. Stellen Sie sicher, dass es PKCS#8 ist — Apples .p8-Beispiele und die ältere openssl ecparam-Ausgabe sind kein PKCS#8 und jose kann diese nicht laden.
# 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.p8Bewahren Sie asa-private.p8 an einem sicheren Ort auf (z. B. ~/.apple-search-ads/, chmod 600). Sie fügen nur die öffentliche Hälfte bei Apple ein.
c) API-Client generieren
Melden Sie sich ab und als eingeladener API-Benutzer (nicht als Admin-Konto) wieder an. Gehen Sie zu Kontoeinstellungen → API. Sie sehen einen Bildschirm Client-Zugangsdaten mit einem Textfeld für den öffentlichen Schlüssel — dies erscheint nur für Benutzer, die die API-Rolle innehaben.
Fügen Sie den Inhalt von
asa-public.pemein (mit den Markierungen-----BEGIN PUBLIC KEY-----/-----END PUBLIC KEY-----).Klicken Sie auf API-Client generieren.
Kopieren Sie die drei Werte, die Apple Ihnen anzeigt: Client ID, Team ID, Key ID — diese erscheinen später nicht mehr.
2. Installation
npm install
npm run build3. Konfiguration
Kopieren Sie .env.example nach .env und füllen Sie es aus, oder übergeben Sie Umgebungsvariablen über Ihren MCP-Client.
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 callASA_PRIVATE_KEY (PEM-Inhalt inline, mit \n-Escapes, falls über JSON injiziert) wird als Alternative zu ASA_PRIVATE_KEY_PATH unterstützt.
4. In Ihren MCP-Client einbinden
{
"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"
}
}
}
}Authentifizierung
Der Server handhabt den OAuth 2.0 Client-Credentials-Flow mit einer ES256 JWT-Client-Assertion:
Signieren Sie ein JWT mit Ihrem privaten
.p8-Schlüssel (Header:kid=Key ID,alg=ES256; Payload:iss=Team ID,sub=Client ID,aud=https://appleid.apple.com).Senden Sie es per POST an
https://appleid.apple.com/auth/oauth2/tokenmitgrant_type=client_credentialsundscope=searchadsorg.Verwenden Sie das zurückgegebene 1-Stunden-Zugriffstoken mit
Authorization: Bearer …undX-AP-Context: orgId=…bei jedem API-Aufruf.
Das Token wird im Speicher bis ca. 30 s vor Ablauf zwischengespeichert, sodass Sie eine Assertion signieren und ein Token pro Stunde austauschen. Bei 401 erzwingt der Server eine Aktualisierung und versucht es einmal erneut. Bei 429/5xx wird das Tempo gedrosselt (unter Beachtung von Retry-After), bis zu 3 Mal.
Tool-Inventar (74 Tools)
Konto & Zugriff (2)
org_acls, me_user — ohne Organisationskontext aufrufen, um herauszufinden, was Ihr Token tun kann.
Entdeckung (3)
search_apps, search_geo, geo_lookup
App-Metadaten (6)
apps_get, apps_locale_details, apps_eligibilities_find, apps_assets_find, creative_app_preview_devices, countries_or_regions_list
Benutzerdefinierte Produktseiten (3)
cpp_list, cpp_get, cpp_locale_details
Kampagnen (6)
campaigns_create, campaigns_get, campaigns_list, campaigns_find, campaigns_update, campaigns_delete
Anzeigengruppen (7)
adgroups_create, adgroups_get, adgroups_list, adgroups_find_in_campaign, adgroups_find_org_wide, adgroups_update, adgroups_delete
Creatives (4)
creatives_create, creatives_list, creatives_get, creatives_find — Creatives kapseln eine Referenz auf eine benutzerdefinierte Produktseite, eine Standard-Produktseite oder ein Creative-Set. Anzeigen werden über creativeId an Creatives gebunden.
Anzeigen (7)
ads_create, ads_get, ads_list, ads_find_in_campaign, ads_find_org_wide, ads_update, ads_delete
Targeting-Keywords (7)
targeting_keywords_create, targeting_keywords_get, targeting_keywords_list, targeting_keywords_find, targeting_keywords_update, targeting_keywords_delete (Bulk), targeting_keywords_delete_single
Negative Keywords — Anzeigengruppen-Bereich (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
Negative Keywords — Kampagnen-Bereich (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
Berichte (7)
Tool | Endpunkt |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Alle akzeptieren startTime, endTime, optional granularity (HOURLY/DAILY/WEEKLY/MONTHLY), optional groupBy (adminArea / ageRange / countryCode / countryOrRegion / deviceClass / gender / locality), selector, returnRowTotals, returnGrandTotals, returnRecordsWithNoMetrics, timeZone (UTC | ORTZ).
Impression-Share-Berichte (3) — asynchron
custom_reports_create → gibt reportId zurück. Mit custom_reports_get abfragen, bis state=COMPLETED. Mit custom_reports_list auflisten.
Budgetaufträge (4) — nur LOC-Konten
budget_orders_create, budget_orders_get, budget_orders_list, budget_orders_update. v5 hat kein Löschen für Budgetaufträge.
Audit von Ablehnungsgründen (2)
product_page_reasons_find, product_page_reasons_get — schreibgeschützte Überprüfung, warum Apples Prüfer Creatives abgelehnt haben.
Notausgang (1)
apple_search_ads_request — jeden Pfad mit jeder Methode aufrufen. Authentifizierung und Organisationskontext werden weiterhin für Sie gehandhabt.
Selektoren
*_find-Tools akzeptieren Apples Selektor-Grammatik:
{
"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 }
}Operatoren: EQUALS, NOT_EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH, GREATER_THAN, LESS_THAN, IN, NOT_IN, CONTAINS_ALL, CONTAINS_ANY, BETWEEN. values ist immer ein Array.
End-to-End-Beispiel
Ein Workflow, den Sie vollständig über Claude steuern können:
org_acls→ dieorgIdauswählen.search_appsfür Ihre App → dieadamIdabrufen.campaigns_createmit dieser adamId, Tagesbudget, US-Targeting,adChannelType=SEARCH,supplySources=["APPSTORE_SEARCH_RESULTS"],billingEvent=TAPS.adgroups_createinnerhalb der Kampagne mitdefaultBidAmount={amount:"1.00",currency:"USD"}undpricingModel=CPC.targeting_keywords_createmit einer Reihe von{text, matchType, bidAmount}-Zeilen.cpp_list→ eine productPageId auswählen →creatives_createmittype=CUSTOM_PRODUCT_PAGE, um eine creativeId zu erstellen →ads_create, um sie an die Anzeigengruppe zu binden.Warten Sie ein paar Tage.
reports_campaignsfür die Top-Level-Daten, dannreports_search_terms_in_campaign, um neue Keywords / negative Keywords zu sammeln.custom_reports_createfür Impression-Share / Share-of-Voice bei Ihren Top-Suchanfragen.
Bekannte Hinweise (v5-Besonderheiten)
Kein Legacy-Creative-Set CRUD. Apple hat es in v5 entfernt; erstellen Sie stattdessen eine
creatives-Zeile und referenzieren Sie diese vonads.creativeId.Kein App-Kategorien-Endpunkt. Verwenden Sie
apps_getund lesen SieprimaryGenre/secondaryGenre.Kein Geo-Targeting nach Postleitzahlen. Geo-Entitäten in v5 sind nur Country / AdminArea / Locality.
Keine organisationsweite Suche nach Keywords oder Suche nach Keywords auf Anzeigengruppenebene. Apple begrenzt die Suche nach Targeting-Keywords auf Kampagnenebene (
/campaigns/{id}/adgroups/targetingkeywords/find) und fasst sie über Anzeigengruppen hinweg zusammen; filtern Sie nachadGroupIdim Selektor, um die Suche einzugrenzen.Kein DELETE bei Budgetaufträgen. Aktualisieren Sie diese, löschen Sie sie nicht.
Zielgruppen, Prognosen, Conversion-Events sind NICHT in v5 enthalten — diese befinden sich in separaten Apple-APIs (AdServices Attribution etc.).
Lokale Entwicklung
npm run dev # tsc --watch
npm run typecheck # one-shot type check
npm run build # compile to dist/Verwenden Sie apple_search_ads_request, um jeden Endpunkt direkt zu debuggen — es gibt den Raw-Envelope zurück, sodass Sie die genaue Antwortform sehen können, die Apple zurückgegeben hat.
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/AppVisionOS/apple-search-ads-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server