# 用 PlayDrop MCP 从你的 AI 应用发布游戏

AI Agent 如何通过 MCP 发布到 PlayDrop：简单方式和包方式、私密测试、publish_game_version、更新、限制和恢复。

Source: https://www.playdrop.ai/zh-hans/create/learn/mcp-publishing

PlayDrop 的 MCP 服务器让 AI 应用可以把游戏发布到其用户的 PlayDrop 账号，并返回一个在更新后依然有效的链接。本指南介绍操作顺序。每一步都链接到包含详细信息的指南。

## 构建之前

1. 在编写代码之前，调用 `get_documentation({topic:"index"})`，并阅读游戏将用到的功能的指南。从一开始就规划好全屏布局、存档和操控，可以避免之后重写游戏。如需确切的方法签名，请阅读主题 `sdk-types`、`server-sdk-types` 和 `shared-types`。
2. 调用 `list_games`。如果游戏已经存在，你将更新它并保留它的 `name`，这样它就能保留原来的链接和玩家。
3. 选择方式。一个不使用 PlayDrop SDK 的独立 HTML 文件使用[简单方式](https://www.playdrop.ai/zh-hans/create/learn/html-games)。其他所有情况，包括任何 SDK 功能、商店页面媒体或服务器，都使用[包](https://www.playdrop.ai/zh-hans/create/learn/packaging)。

请你自己保管创作者的源代码项目。PlayDrop 只接收构建产物：它不是源代码备份，也无法返回源代码。

## 简单方式：upload_game

发送 `requestId`、完整的 HTML（最大 10 MiB，即 10,485,760 个 UTF-8 字节）和一个迷你 catalogue。传入 `gameId` 可更新已有游戏。版本号会自动递增。字段说明请参阅[简单 HTML 游戏](https://www.playdrop.ai/zh-hans/create/learn/html-games)。

## 包方式：准备、上传、完成

用 `requestId`、`expectedCurrentVersion` 和一种输入形式调用 `prepare_catalogue_upload`：

- **文件夹**：`catalogue`（catalogue.json 的内容）加上 `files`，每个文件一个描述符，带有它的相对路径。描述符可以携带内联 `text`、签名上传说明、附件绑定，或者对保留版本中某个文件的 `reuse`。
- **本地 ZIP 或 .play**：先在本地解压，然后发送根目录的 catalogue 和文件夹描述符。绝不能把 base64 编码的压缩包字节放进工具调用中。
- **ChatGPT 附件**：把宿主解析出的 ZIP 或 .play 作为 `archive` 传入，并附上它真实的 `download_url` 和 `file_id`。压缩后最大 20 MiB，并且 catalogue.json 必须位于根目录。

对于签名上传，每个描述符都要提供 `path`、`contentType`、`sizeBytes`、`sha256`（64 个小写十六进制字符）和 `md5Base64`，它们都根据确切的字节在本地计算。把这些字节 PUT 到返回的每个 URL，并带上返回的所有请求头，然后用同一个 `requestId` 调用 `complete_catalogue_upload`。

在 ChatGPT 中，文件夹中的文件可以来自按位置绑定的附件：

```
attachments: [htmlFile, iconFile]
files: [{path:"index.html", attachmentIndex:0}, {path:"listing/icon.png", attachmentIndex:1, role:"LISTING", app:"my-game"}]
```

每个应用都需要声明 `version`、一个可见性（在请求或应用上），以及 `expectedCurrentVersion` 中以其名称为键的条目：创建时为 `null`，更新时为 `list_games` 中当前已发布的版本。过时的值会被拒绝，这样就绝不会意外覆盖另一次上传。

## 先私密测试，再发布

当游戏使用 SDK 或服务器，或者你的用户想先试玩时，用 `visibility: "private"` 上传。打开回执中的 `url`，就能在 PlayDrop 中配合真实的 SDK 宿主玩这个确切的版本。托管服务器的功能只在已上传的版本上运行，所以请用这种方式测试它们。

运行正常后，用 `publish_game_version` 发布这个确切的版本，传入 `gameId`、`version` 和 `expectedCurrentVersion`；如果你的用户选择了受众，再传入 `visibility`（`public` 或 `unlisted`）。它会沿用已测试的文件、商店页面和审核。不要为了发布而再次上传游戏。

要在上传前在 PlayDrop 框架中试玩本地构建，请在运行本地服务器的那台机器上，用普通浏览器打开 `https://www.playdrop.ai/@<username>/<slug>/dev?url=<URL-encoded local address>`。

## 选择谁可以玩

`visibility` 接受 `public`、`unlisted` 和 `private`。对于没有选择的新游戏，请使用创作者保存的设置：省略可见性时，`upload_game` 会应用该设置；`get_account` 会以 `publishing.defaultVisibility` 显示它。更新时，请保留 `list_games` 中游戏的 `gameVisibility`，除非你的用户要更改；省略可见性时 `upload_game` 会这样做，而包需要明确写出它。不公开列出表示任何拿到链接的人都能玩；它不是好友名单。绝不能让游戏比你的用户预期的更公开。详细信息：[谁可以玩](https://www.playdrop.ai/zh-hans/create/learn/distribution)。

## 交回正确的链接

公开和不公开列出游戏的回执包含 `shareUrl`，即游戏长期有效的页面：请把这个链接交给你的用户。私密版本会返回 `url`，即供所有者使用的该确切版本的链接。包的回执会列出每个条目；即使后面的条目失败，已完成的条目也会保持发布状态。

## 更新游戏

读取 `list_games` 和当前版本，保留 `name`，并发送完整快照：所有要包含的文件和所有要包含的元数据，因为省略的字段在新版本中将不存在。省略的 catalogue 条目绝不会被删除。用 `get_game_version` 读取你要修改的那个版本的确切 catalogue，包括它的可调数值状态。

## 限制

- 简单方式：一个最大 10 MiB 的 HTML 文件。
- 包：512 个文件夹文件描述符或 512 个压缩包条目（包括 catalogue.json 和目录），每个文件 50 MiB，解压后总计 200 MiB，catalogue JSON 最大 1 MiB。
- 压缩包：只接受安全的相对路径；包含重复路径或符号链接的压缩包，以及加密、分卷和 ZIP64 压缩包都会被拒绝。
- 准备好的上传会在 30 分钟后过期。

## 错误和重试

错误会携带 `error`、`message`、`retryable`、`nextAction`、`docsUrl` 和 `documentationTopic`。请按照 `nextAction` 操作。响应丢失后，用同一个 `requestId` 重试完全相同的内容；内容改变后需要新的 ID。请参阅[错误与恢复](https://www.playdrop.ai/zh-hans/create/learn/errors)。

用 `send_feedback` 报告可复现的问题或令人困惑的步骤，不要包含令牌或签名 URL。

## 相关指南

- [简单 HTML 游戏](https://www.playdrop.ai/zh-hans/create/learn/html-games): 用 upload_game 发布一个最大 10 MiB 的独立 HTML 文件：适用范围、迷你 catalogue、可见性、更新，以及何时改用包。
- [打包和 .play](https://www.playdrop.ai/zh-hans/create/learn/packaging): 整理一个根目录带有 catalogue.json 的已构建游戏文件夹、ZIP 或 .play，声明商店页面媒体和服务器，并用 prepare_catalogue_upload 上传。
- [可见性与曝光](https://www.playdrop.ai/zh-hans/create/learn/distribution): 选择谁可以打开 PlayDrop 游戏，了解账号默认设置和版本发布的规则，以及 Boost、互玩、即玩和搜索如何带来新玩家。
- [错误与恢复](https://www.playdrop.ai/zh-hans/create/learn/errors): PlayDrop MCP 工具返回的错误结构、何时使用同一个 requestId 重试，以及每个常见错误代码的修复方法。
