通过你的编码代理让应用符合商店要求
你的代理读取眼前的应用——SDK、权限、bundle id——并根据它发现的内容起草每一个合规页面。由你阅读草稿并发布。代理做不到这一步。
开始之前
你需要 Claude Code 和一个 AppFoyer 账号。免费套餐就够了:创建一个。无需创建密钥——代理第一次连接时,会请你在浏览器中批准它。
完全没有编码代理?在浏览器中填写六个字段,无需插件也能得到同样的五个页面。
不用 Claude Code?插件需要它,但隐私政策和服务条款页面不需要:控制面板中的这两个编辑器各有一个已填好你应用信息的提示词,你可以在任何 AI 助手中运行它,再把结果粘贴回来——完整内容刊登在隐私政策指南和服务条款指南中。
安装
claude
/plugin marketplace add appfoyer/claude-plugin
/plugin install appfoyer@appfoyer 开始时不需要账号:代理会在你的机器上读取构建、展示它发现的内容并提出问题,只有在有东西需要保存时才会请你连接。它第一次调用 AppFoyer 时,浏览器会打开一个批准页面:登录或创建一个免费账号,检查名称以及浏览器将返回的位置,然后批准。Claude Code 会保存这个连接并自动续期;无需复制任何东西,也不会在你的 shell 中存储任何东西。如果浏览器没有打开,运行 /mcp,选择 appfoyer,然后选择 Authenticate。在 Claude Code 桌面应用中,先在终端里按这种方式连接一次,然后在桌面应用中开启一个新会话:已在运行的会话看不到新的连接。在控制面板的 Agent 页面断开连接后,下一次调用会立即失败。Claude Code 不会自动刷新第三方插件市场:在 /plugin → Marketplaces → appfoyer 中,选择 Enable auto-update 以接收新版本。
那台机器上没有浏览器——远程服务器、容器、脚本化运行?那就改用 API 密钥:在 Agent → API key — for CI and headless use 下创建一个,按上述方式安装插件以使用工作流,再添加一次服务器,并在请求头中带上密钥:
export APPFOYER_API_KEY=cpk_…
claude mcp add --transport http appfoyer-key https://app.appfoyer.com/mcp --header "Authorization: Bearer $APPFOYER_API_KEY" 插件只从那个环境变量读取密钥——skill 永远看不到它,它只会出现在 Claude Code 填写的 Authorization 请求头中。
其他 MCP 客户端——claude.ai、Claude Desktop、Cursor、VS Code——也可以用同样的方式、通过同样的批准页面连接到 https://app.appfoyer.com/mcp。它们能获得这些工具;而读取构建文件的分步工作流随 Claude Code 插件提供。
该说什么
请在你应用的代码仓库中运行这些指令,而不是在空目录中:
| 说 | 会发生什么 |
|---|---|
Make this app store-ready | 扫描构建文件,确认它无法推导出的事实,起草每一个页面,返回一个审阅链接。 |
Is this app store-ready? | 对照合规检查清单进行只读审查。不写入任何内容。 |
Wire the store-ready links into the app | 在你发布之后:以 diff 的形式提出应用内隐私政策和支持链接的修改,供你审阅。 |
Add the AppFoyer drift check | 提出一个 GitHub 工作流,标出那些新增了页面可能尚未涵盖的 SDK 或权限的拉取请求。工作方式。 |
示例
用你自己的话说就行;以下是 skill 能处理的情况。
一个应用,第一次运行
> Make this app store-ready - 列出它在构建文件中发现的内容——SDK、权限、bundle id——每项都注明文件和行号。
- 只询问它找不到的信息:公司名称、支持邮箱、司法管辖区、商店链接。最多两轮。
- 创建应用,从代码仓库上传图标,并起草全部五个页面。
- 最后给出一个审阅链接。在你于那里发布之前,什么都不会公开。
修改后再次运行
> Make this app store-ready - 通过 application id 找到已有的应用,并把新事实与已存储的事实进行比较。
- 只重新起草受修改影响的页面,例如新增一个分析 SDK 后的隐私政策。
- 除非你要求,否则不会动图标和地址。
多个 flavor,在提示中已指明
> Make com.acme.weather.free and com.acme.weather.pro store-ready - 创建两个应用,不会就选择范围提出任何问题。
- 读取每个 flavor 自己的文件夹、名称和依赖项。只被 free flavor 使用的广告 SDK 不会写进 pro flavor 的隐私政策。
- 为每个 flavor 返回一个审阅链接和一张控制台 URL 表。
多个 flavor,未指明
> Make this app store-ready - 列出各个 flavor 及其 application id,全部预先选中,由你挑选哪些需要站点。
- debug 和 staging 等构建类型会列为已排除,不会提供选择。
品牌 × 环境维度
> Make every brand store-ready - 列出组合(brandAProd、brandBProd),而不是单个 flavor。
- 只提供生产环境。dev 和 qa 永远不会发布到商店。
- 当构建把应用名称放在 Gradle(resValue、manifestPlaceholders)或移动过的 source set 中时,从那里读取应用名称。
- 如果无法判断某个维度是环境还是品牌,它会询问你。
自定义地址(Pro 和 Advanced)
> Make this app store-ready - 根据应用的英文名称生成地址,例如 weather-now。
- 如果这个地址已被占用或与某个品牌名称过于接近,它会尝试下一个——weather-now-app、acme-weather——最多五次,然后询问你。
- 在免费套餐中,它会保留 app-… 地址,并说明自定义地址需要 Pro。
- app-… 地址会继续提供同一个站点。
更改你已经在用的地址
> Change the address to weather-radar - 先询问你。旧的自定义地址会立即释放,仍写着它的商店详情将无法正常访问。
- 只有在你同意后才会更改。
更新图标
> Update the app icon - 找到启动器图标:Play 的 512 图标、最大的 mipmap 图片,或 iOS AppIcon 的营销图片——优先使用该 flavor 自己的图标。
- 如果它超过 512 KB,会在临时文件夹中缩小一份副本。你的代码仓库不会被改动。
- 告诉你上传了哪个文件。对于已发布的应用,新图标会立即上线。
带广告的应用
> Make this app store-ready. AdMob publisher id pub-0000000000000000 - 根据你提供的行写入 app-ads.txt。发布商 ID 不在你的代码中,所以它从不猜测。
- 提醒你在商店详情中把站点设置为开发者网站。
- AdMob 已验证过我们地址上的 app-ads.txt 文件;请给它最多 24 小时来抓取。
让页面与构建保持同步
> Add the AppFoyer drift check - 每次运行“make this app store-ready”都会在代码仓库根目录写入 appfoyer.json:页面所依据的 SDK、数据类型和权限。它由检查所用的同一个扫描器写入,从不手写。
- 这条提示会展示一个使用免费 appfoyer/check-action 的 GitHub 工作流,并在你同意后写入 .github/workflows/appfoyer.yml。它从不覆盖你已有的文件。
- 从此以后,每个拉取请求都会列出自页面写成以来它新增或移除的内容,并注明文件和行号。再次运行插件会更新草稿和 appfoyer.json。
- 不会替你提交任何内容。关于让隐私政策与构建保持同步的指南中有详细说明,以及其他 CI 系统的设置方法。
检查但不做任何修改
> Is this app store-ready? - 为每个匹配的应用运行检查清单,并报告缺少什么。不写入任何内容。
- 尚无对应应用的 flavor 会被报告为缺失。
把链接放进应用
> Wire the store-ready links into the app - 需要已发布的页面。
- 为你设置界面或字符串中的隐私政策和支持链接提出一个 diff。只有在你同意后才会应用,而且从不提交。
哪些内容会离开你的机器
只有推导出的事实:
- 应用的名称、平台以及 bundle id 或 application id;
- 在你构建文件中发现的 SDK 和权限的名称;
- 你确认的答案——公司名称、支持邮箱、司法管辖区、商店 URL;
- 代理起草的页面文本,以草稿形式保存在你的账号中;
- 应用自己的图标,通过一次性上传链接发送一次。
不包括任何其他文件,绝不包括源代码,也绝不包括在代码仓库中发现的机密或密钥。代理发送的内容,本来就是隐私政策必须写明的内容。
只有一个文件会被写入你的代码仓库并留在那里:appfoyer.json,记录页面是根据什么写成的,由插件中附带的扫描器生成。它不会被发送到任何地方。代理从不提交它,也不提交任何其他内容——提交由你来做。
代理不能做什么
无论是通过浏览器还是用 API 密钥连接,插件持有的都是代理凭据——因此它根本无法发布。这一点由服务器强制执行,而不是靠客气地请求代理:
- 没有发布工具。代理写的是草稿;你的线上页面不会改变。
- 有两样东西没有草稿:图标和自定义地址。对于已发布的应用,它们会立即改变线上站点,代理设置它们时会告诉你。未经你同意,它无法替换你已经在用的自定义地址。
- 发布页面的 REST 路由会直接拒绝代理凭据——仅限会话。
- 每个页面在发布时仍要经过与手写修改相同的内容筛查。
- 每次代理调用都会记录在账号的审计日志中,并注明发起调用的连接或密钥。
所以,连接或密钥被盗用时,最坏的情况是需要丢弃一些草稿、一个错误的图标或一个新地址——而不是有页面以你的名义公开。
它能获得的工具
插件连接到一个 MCP 端点,该端点只提供以下工具:
| 工具 | 作用 | |
|---|---|---|
list_apps | 读取 | 账号中的每个应用,包括其 slug、公开 URL,以及是否有已发布的内容。 |
get_app | 读取 | 单个应用:设置、已存储的数据收集事实,以及每个页面的线上文本、发布状态和待处理的草稿。 |
create_app | 写入 | 创建一个带模板页面的应用。不会公开任何内容。 |
create_apps | 写入 | 一次调用最多创建十个应用,每个产品 flavor 一个。每个都以未发布状态开始。 |
update_app | 写入 | 修改设置、已存储的数据收集事实或 SDK 列表。从不编辑页面文本。 |
set_page | 写入 | 为一个页面写入草稿。线上页面不受影响。 |
set_ad_lines | 写入 | 替换 app-ads.txt。仅在存在广告 SDK 且你提供了发布商 ID 时使用。 |
get_checklist | 读取 | 由服务器计算的商店就绪检查清单,以及哪些页面仍有未发布的草稿。 |
get_store_forms | 读取 | 根据事实和 SDK 列表,为 Google Play 的 Data safety 表单和 Apple 的 App Privacy 详情起草答案。由你自己填入控制台。 |
request_publish | 写入 | 表示起草已完成,并返回审阅 URL。不发布任何内容。 |
set_icon | 写入 | 返回一个用于上传应用图标的一次性 URL。立即上线——图标没有草稿。 |
check_slug | 读取 | 按照与控制面板相同的规则检查自定义地址(Pro 和 Advanced)。 |
set_slug | 写入 | 申领一个自定义地址。立即上线。除非你同意,否则拒绝替换你已有的地址。 |
出现问题时
| 症状 | 原因 |
|---|---|
| 工具显示“needs authentication” | 连接从未被批准,或已被断开。运行 /mcp,选择 appfoyer,然后选择 Authenticate。 |
| 批准页面提示该请求无法使用 | 链接已过期或被打开了两次。从编辑器重新开始;没有建立任何连接。 |
使用 API 密钥时出现 unauthorized | 密钥已在控制面板中被撤销,或属于另一个账号。创建一个新密钥并重新导出。 |
| 发布时返回配额错误 | 套餐的已发布应用限额已用完。应用及其草稿会被保留——取消发布另一个应用或升级,然后在审阅界面中发布。 |
| 草稿被拒绝或被暂扣 | 内容筛查匹配到了某些内容。原因列表会说明匹配到了什么以及如何修复;修改后重新发送即可。公开内容没有任何改变。 |
有一件事不会因此改变
这些草稿是根据你的代码补全的模板,不构成法律建议。代理写得快,并不会让内容变得真实——发布之前请读一遍它写的内容,尤其是你的应用收集了哪些数据的列表。商店追究责任的对象是你。
有疑问:support@appfoyer.com。