# 从本地发布到 1GP

本地渠道只使用 API + MCP，不提供网页手动上传。推荐使用 [1GP MCP](https://github.com/1gp-studio/publisher-mcp)：在本地检查和构建，直接上传完整运行产物。无需发布者登录 Vercel、AWS 或 ECR，云资源由 1GP 提供。

## 连接与身份

调用 `connect_platform`，由用户在浏览器登录 1GP 并授权。客户端保存 1GP 发布凭证；HTTP 请求使用 `Authorization: Bearer <1GP 发布凭证>`。不要使用云厂商密钥，也不要把凭证粘贴到提示词、源码或截图中。接口地址基于当前 1GP 站点 origin；MCP 可用 `ONEGP_PLATFORM_URL` 配置站点。

## 静态网页

MCP v0.8.0 推荐先用 `prepare_game`，一次取得游戏识别、渠道、版本差异、构建检查和可选功能。复用结果准备版本说明，再调用 `publish_game`，不重复逐项检查。静态产物使用 `output_directory`；需要执行已有 npm 构建脚本时指定 `build_script`。已有产物应与当前代码一致。

直接接入时，向 `POST /api/publish` 提交 JSON：

```json
{
  "source": "local",
  "buildMethod": "web-static",
  "projectId": "0123456789abcdef0123456789abcdef",
  "title": "My Game",
  "description": "A browser game",
  "release": { "version": "1.0.0", "title": "First release", "notes": "Initial playable version", "changeType": "minor" },
  "files": [{ "file": "index.html", "encoding": "base64", "data": "PGgxPkdhbWU8L2gxPg==" }]
}
```

`projectId` 是 32 位小写十六进制的稳定本地项目标识；更新时保持不变。转移或移动项目后，使用已验证归属的 `gameSlug` 更新原游戏，避免另建游戏。静态文件合计最多 3 MiB、300 个文件；必须包含 `index.html`，不接受凭证、source map 或源码目录。

## 包含服务端的完整产物

兼容的游戏使用 `build_vercel_game` 或框架适配器在本地生成 Vercel Build Output API v3 产物；使用返回的 `deployment_target: "vercel"` 和 `vercel_output_directory` 调用 `publish_game`。包括 `config.json`、`static/`、自包含的 Node.js 22/24 `functions/*.func/` 及路由。不能只上传前端。

MCP 自动完成下面的 API 流程：

1. `POST /api/publish/vercel/files` 分批上传文件，取得与账号、文件路径及内容绑定的短期 receipt。
2. `POST /api/publish`，使用 `source: "local"`、`buildMethod: "vercel-output"`，提交对应文件引用、配置和 receipts。
3. 使用返回的任务 `id` 查询 `GET /api/publish/{id}`，直到 `ready` 或 `failed`。结果不明时先查询，不盲目重复发布。

完整产物合计最多 64 MiB、10000 个文件、单文件 16 MiB；批次与请求体另有大小限制。自定义客户端应参考 MCP 的 `src/vercel-upload.js` 和 `src/vercel-output.js`，不要自行构造或复用过期 receipts。

## 不适合本地网页/函数产物的情况

自建 WebSocket 服务、常驻进程、内存房间状态等需求，需要评估 [1GP Docker 托管](./docker-hosting.md)。固定选择本地渠道后，AI 应说明限制并建议切换，不自动改道。缺失数据库、环境配置或资源权限应明确报告。

网页资源会提供给玩家，服务端产物由平台运行。`ready` 只表示部署完成，不保证多人玩法正确；发布后检查页面和必要接口，并说明尚未验证的行为。

## 可选云存档与排行榜（MCP v0.8.0）

作者可分别选择 `add_cloud_saves`、`add_leaderboard` 提示词。`prepare_game` 读取已有设置，`features` 只记住本机作者的明确选择，不会自动启用服务。已有发布授权直接沿用；功能接入后仍需测试游戏，并按原渠道更新。

作者接口使用同一发布凭证，仅允许操作自己拥有的游戏；这些接口不提供玩家存档、玩家凭证或成绩提交：

- `GET /api/developer/game-integrations/{slug}` 返回游戏、`cloudSaves`、`leaderboards` 和可信 `platformOrigin`。查询 `feature=cloud-saves` 可取得专属说明；查询 `feature=leaderboards&boardId={真实榜单ID}` 返回该榜单说明。
- `PUT` 同一路径，JSON 为 `{"feature":"cloud-saves","enabled":true,"schemaVersion":1}`。保留原格式版本；升级前实现并验证旧存档迁移。
- `POST` 同一路径创建榜单，JSON 为 `{"feature":"leaderboards","action":"create","board":{"key":"main","name":"Best score","description":"","order":"desc","unit":"points","minScore":0,"maxScore":1000000000,"minPlayMs":0}}`。计分规则必须来自该游戏，不能直接套用示例。相同 key 与配置可安全重试；同 key 不同配置返回 409，不替换已有榜单。更新用 `action:"update"`，board 包含真实 `id`、`name`、可选 `description` 和明确 `enabled`；不改变计分规则或清空成绩。

配置返回真实游戏/榜单 ID 和接入材料。游戏未发布时须保持功能请求关闭，不编造 ID；配置成功也不代表代码已接入。游戏内使用各自独立的短期玩家会话，不放作者发布凭证。父窗口校验使用返回的 `platformOrigin`，不能以旧 MCP 连接域名替代。

异步发布后用 `wait_for_publish(build_id?, wait_seconds?)` 等待，最多 45 秒；pending 时继续原任务，中断后省略 ID 可恢复当前账号最近任务。工具只查询，不盲目重发发布。
