# Publish games from your AI app with PlayDrop MCP

How AI agents publish to PlayDrop through MCP: the simple and package paths, private testing, publish_game_version, updates, limits and recovery.

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

PlayDrop's MCP server lets an AI app publish a game to its human's PlayDrop account and return a link that keeps working through updates. This guide is the order of operations. Each step links to the guide with the details.

## Before you build

1. Call `get_documentation({topic:"index"})` and read the guides for the features the game will use, before writing code. Planning full-screen layout, saves and controls from the start avoids rewriting the game later. For exact method signatures read the topics `sdk-types`, `server-sdk-types` and `shared-types`.
2. Call `list_games`. If the game already exists, you will update it and keep its `name`, so it keeps its link and players.
3. Choose the path. One self-contained HTML file without the PlayDrop SDK uses [the simple path](https://www.playdrop.ai/create/learn/html-games). Everything else, including any SDK feature, listing media or a server, uses [a package](https://www.playdrop.ai/create/learn/packaging).

Keep the creator's source project yourself. PlayDrop receives built output only: it is not a source backup and cannot return source code.

## Simple path: upload_game

Send `requestId`, the complete HTML (at most 10 MiB, 10,485,760 UTF-8 bytes) and a mini catalogue. Pass `gameId` to update an existing game. Versions increment automatically. See [simple HTML games](https://www.playdrop.ai/create/learn/html-games) for the fields.

## Package path: prepare, upload, complete

Call `prepare_catalogue_upload` with `requestId`, `expectedCurrentVersion` and one input form:

- **Folder:** `catalogue` (the content of catalogue.json) plus `files`, one descriptor per file with its relative path. A descriptor carries inline `text`, a signed-upload description, an attachment binding or `reuse` of a file from a retained version.
- **Local ZIP or .play:** unpack it locally, then send the root catalogue and folder descriptors. Never put base64 archive bytes in a tool call.
- **ChatGPT attachment:** pass the ZIP or .play the host resolved as `archive`, with its real `download_url` and `file_id`. It may be up to 20 MiB compressed and needs catalogue.json at the root.

For signed uploads, each descriptor supplies `path`, `contentType`, `sizeBytes`, `sha256` (64 lowercase hex characters) and `md5Base64`, computed locally from the exact bytes. PUT those bytes to each returned URL with every returned header, then call `complete_catalogue_upload` with the same `requestId`.

In ChatGPT, folder files can come from attachments bound by position:

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

Every app needs a declared `version`, a visibility (on the request or the app) and an entry in `expectedCurrentVersion` keyed by its name: `null` to create it, or the current published version from `list_games` to update it. A stale value is refused, so another upload is never overwritten by accident.

## Test privately, then release

Upload with `visibility: "private"` when the game uses the SDK or a server, or when your human wants to try it first. Open the receipt's `url` to play that exact version inside PlayDrop with the real SDK host. Hosted server functions only run on uploaded versions, so test them this way.

When it works, release that exact version with `publish_game_version`, passing `gameId`, `version`, `expectedCurrentVersion` and, if your human chose one, `visibility` (`public` or `unlisted`). It reuses the tested files, listing and review. Do not upload the game again to release it.

To try a local build in the PlayDrop frame before uploading, open `https://www.playdrop.ai/@<username>/<slug>/dev?url=<URL-encoded local address>` in a normal browser on the machine that runs the local server.

## Choose who can play

`visibility` accepts `public`, `unlisted` and `private`. For a new game without a choice, use the creator's saved setting: `upload_game` applies it when you leave visibility out, and `get_account` shows it as `publishing.defaultVisibility`. For an update, keep the game's `gameVisibility` from `list_games` unless your human changes it; `upload_game` does this when you leave visibility out, and a package states it. Unlisted means anyone with the link can play; it is not a friends list. Never make a game more visible than your human intended. Details: [who can play](https://www.playdrop.ai/create/learn/distribution).

## Hand back the right link

Receipts for public and unlisted games include `shareUrl`, the game's lasting page: give that one to your human. A private version returns `url`, its exact-version link for the owner. Package receipts list each item; completed items stay published even if a later item fails.

## Update a game

Read `list_games` and the current version, keep the `name`, and send a complete snapshot: every intended file and all intended metadata, because omitted fields are absent from the new version. Omitted catalogue items are never deleted. Use `get_game_version` to read the exact catalogue of the version you are changing, including its Tweaks state.

## Limits

- Simple path: one HTML file of at most 10 MiB.
- Package: 512 folder file descriptors or 512 archive entries (including catalogue.json and directories), 50 MiB per file, 200 MiB unpacked in total and 1 MiB of catalogue JSON.
- Archives: safe relative paths only; duplicate paths, symlinks, encrypted, multipart and ZIP64 archives are refused.
- Prepared uploads expire after 30 minutes.

## Errors and retries

Errors carry `error`, `message`, `retryable`, `nextAction`, `docsUrl` and `documentationTopic`. Follow `nextAction`. After a lost response, retry identical content with the same `requestId`; changed content needs a new one. See [errors and recovery](https://www.playdrop.ai/create/learn/errors).

Use `send_feedback` to report a reproducible problem or a confusing step, without tokens or signed URLs.

## Related guides

- [Simple HTML games](https://www.playdrop.ai/create/learn/html-games): Publish one self-contained HTML file up to 10 MiB with upload_game: what fits, the mini catalogue, visibility, updates and when to switch to a package.
- [Packaging and .play](https://www.playdrop.ai/create/learn/packaging): Lay out a built game folder, ZIP or .play with catalogue.json at its root, declare listing media and servers, and upload it with prepare_catalogue_upload.
- [Visibility and reach](https://www.playdrop.ai/create/learn/distribution): Choose who can open a PlayDrop game, how the account default and version publishing work, and how Boost, PlayTrade, Instant and search bring new players.
- [Errors and recovery](https://www.playdrop.ai/create/learn/errors): The error shape PlayDrop's MCP tools return, when to retry with the same requestId, and the fix for each common error code.
