Apple Ads MCP
apple-search-ads-mcp
一个模型上下文协议 (MCP) 服务器,封装了完整的 Apple Search Ads(现为 Apple Ads)广告系列管理 API v5。包含 74 个类型化工具,与 v5 文档中的每个端点一一对应 — 包括广告系列、广告组、广告、创意、自定义产品页、关键词、否定关键词、报告、展示份额报告、预算订单、ACL、地理位置/应用搜索、应用元数据、拒绝原因审计 — 此外还提供了一个用于访问未来任何端点的原始透传接口。
API 生命周期: Apple Ads (Search Ads) v5 是当前的生产环境 API。v5 将于 2027 年 1 月 26 日停止服务,届时将由 2026 年夏季推出的全新“Apple Ads Platform API”取代。本服务器针对 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设置
1. 获取 API 凭证
Apple Ads UI 将凭证分散在两个屏幕中。账户设置中的 API 选项卡仅用于管理第三方服务提供商的访问权限;对于您自己的程序化访问,流程首先需要通过 用户管理 (User Management)。
a) 邀请 API 用户
在 app-ads.apple.com → 账户设置 (Account Settings) → 用户管理 (User Management) → 邀请用户 (Invite User):
电子邮件:您控制的任何地址(可以是您自己的;Apple 要求 API 用户使用独立的 Apple ID)
角色:选择一个具有 API 权限的角色(例如 API 账户经理)
发送邀请,然后从受邀邮箱中接受邀请
b) 在本地生成密钥对
在处理邀请的同时,在您的机器上生成一个 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 即可。
c) 生成 API 客户端
退出登录并以受邀的 API 用户身份(而非管理员账户)重新登录。前往 账户设置 (Account Settings) → API。您将看到一个带有公钥 (Public Key) 文本区域的 客户端凭证 (Client Credentials) 屏幕 — 该屏幕仅对拥有 API 角色的用户可见。
粘贴
asa-public.pem的内容(包含-----BEGIN PUBLIC KEY-----/-----END PUBLIC KEY-----标记)。点击 生成 API 客户端 (Generate API Client)。
复制 Apple 显示给您的三个值:客户端 ID (Client ID)、团队 ID (Team ID)、密钥 ID (Key ID) — 这些值之后不会再次显示。
2. 安装
npm install
npm run build3. 配置
将 .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 内容内联,如果通过 JSON 注入则需包含 \n 转义)作为 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"
}
}
}
}身份验证
本服务器使用 ES256 JWT 客户端断言处理 OAuth 2.0 客户端凭证流程:
使用您的
.p8私钥签署 JWT(头部:kid=密钥 ID,alg=ES256;载荷:iss=团队 ID,sub=客户端 ID,aud=https://appleid.apple.com)。将其 POST 到
https://appleid.apple.com/auth/oauth2/token,并设置grant_type=client_credentials和scope=searchadsorg。在每次 API 调用时,使用返回的 1 小时访问令牌,并设置
Authorization: Bearer …和X-AP-Context: orgId=…。
令牌会缓存在内存中,直到过期前约 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)
工具 | 端点 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
所有报告工具均接受 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 — 使用任何方法调用任何路径。身份验证和组织上下文仍会自动为您处理。
选择器 (Selectors)
*_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 驱动的工作流:
org_acls→ 选择orgId。search_apps查找您的应用 → 获取adamId。使用该
adamId、每日预算、美国定向、adChannelType=SEARCH、supplySources=["APPSTORE_SEARCH_RESULTS"]、billingEvent=TAPS调用campaigns_create。在广告系列内调用
adgroups_create,设置defaultBidAmount={amount:"1.00",currency:"USD"}和pricingModel=CPC。使用一批
{text, matchType, bidAmount}行调用targeting_keywords_create。cpp_list→ 选择一个productPageId→ 使用type=CUSTOM_PRODUCT_PAGE调用creatives_create以生成creativeId→ 调用ads_create将其绑定到广告组。等待几天。调用
reports_campaigns获取顶层数据,然后调用reports_search_terms_in_campaign以获取新的关键词/否定关键词。调用
custom_reports_create获取热门搜索的展示份额/声量份额。
已知表面说明 (v5 怪癖)
无旧版创意集 CRUD。 Apple 在 v5 中移除了它;请改为创建
creatives行并从ads.creativeId引用它。无应用分类端点。 请使用
apps_get并读取primaryGenre/secondaryGenre。无邮政编码地理定向。 v5 中的地理实体仅限国家/行政区/地区。
无关键词或广告组范围关键词的组织级查找。 Apple 将定向关键词查找范围限定在广告系列级别 (
/campaigns/{id}/adgroups/targetingkeywords/find),并汇总跨广告组的数据;在选择器中通过adGroupId进行过滤以缩小范围。预算订单无 DELETE 操作。 请更新它们,不要删除它们。
受众、预测、转化事件 不在 v5 中 — 这些存在于单独的 Apple API(如 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 返回的确切响应格式。
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