# Publier des jeux depuis votre app d’IA avec le MCP de PlayDrop

Comment les agents IA publient sur PlayDrop via MCP : voie simple et voie paquet, tests privés, publish_game_version, mises à jour, limites et reprise.

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

Le serveur MCP de PlayDrop permet à une app d’IA de publier un jeu sur le compte PlayDrop de la personne qu’elle aide et de renvoyer un lien qui reste valable d’une mise à jour à l’autre. Ce guide présente l’ordre des opérations. Chaque étape renvoie au guide qui donne les détails.

## Avant de développer

1. Appelez `get_documentation({topic:"index"})` et lisez les guides des fonctionnalités que le jeu utilisera, avant d’écrire du code. Prévoir dès le départ la mise en page plein écran, les sauvegardes et les commandes évite de réécrire le jeu plus tard. Pour les signatures exactes des méthodes, lisez les sujets `sdk-types`, `server-sdk-types` et `shared-types`.
2. Appelez `list_games`. Si le jeu existe déjà, vous le mettrez à jour en conservant son `name`, pour qu’il garde son lien et ses joueurs.
3. Choisissez la voie. Un seul fichier HTML autonome sans le SDK PlayDrop utilise [la voie simple](https://www.playdrop.ai/fr/create/learn/html-games). Tout le reste, y compris toute fonctionnalité du SDK, les médias de fiche ou un serveur, utilise [un paquet](https://www.playdrop.ai/fr/create/learn/packaging).

Conservez vous-même le projet source du créateur. PlayDrop ne reçoit que le résultat compilé : ce n’est pas une sauvegarde des sources et il ne peut pas restituer le code source.

## Voie simple : upload_game

Envoyez `requestId`, le HTML complet (10 MiB au maximum, soit 10 485 760 octets UTF-8) et un mini catalogue. Passez `gameId` pour mettre à jour un jeu existant. Les versions sont incrémentées automatiquement. Consultez [jeux HTML simples](https://www.playdrop.ai/fr/create/learn/html-games) pour les champs.

## Voie paquet : préparer, envoyer, finaliser

Appelez `prepare_catalogue_upload` avec `requestId`, `expectedCurrentVersion` et une seule forme d’entrée :

- **Dossier :** `catalogue` (le contenu de catalogue.json) plus `files`, un descripteur par fichier avec son chemin relatif. Un descripteur contient du `text` intégré, la description d’un envoi signé, une liaison à une pièce jointe ou la réutilisation (`reuse`) d’un fichier d’une version conservée.
- **ZIP ou .play local :** décompressez-le en local, puis envoyez le catalogue racine et les descripteurs du dossier. Ne mettez jamais les octets d’une archive en base64 dans un appel d’outil.
- **Pièce jointe ChatGPT :** passez dans `archive` le ZIP ou le .play résolu par l’hôte, avec ses vrais `download_url` et `file_id`. Il peut faire jusqu’à 20 MiB compressé et doit avoir catalogue.json à la racine.

Pour les envois signés, chaque descripteur fournit `path`, `contentType`, `sizeBytes`, `sha256` (64 caractères hexadécimaux en minuscules) et `md5Base64`, calculés en local à partir des octets exacts. Envoyez ces octets par PUT à chaque URL renvoyée, avec tous les en-têtes renvoyés, puis appelez `complete_catalogue_upload` avec le même `requestId`.

Dans ChatGPT, les fichiers du dossier peuvent provenir de pièces jointes liées par position :

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

Chaque app a besoin d’une `version` déclarée, d’une visibilité (dans la requête ou dans l’app) et d’une entrée dans `expectedCurrentVersion` indexée par son nom : `null` pour la créer, ou la version publiée actuelle issue de `list_games` pour la mettre à jour. Une valeur périmée est refusée : un autre envoi n’est donc jamais écrasé par erreur.

## Testez en privé, puis publiez

Envoyez avec `visibility: "private"` quand le jeu utilise le SDK ou un serveur, ou quand la personne que vous aidez veut d’abord l’essayer. Ouvrez l’`url` du reçu pour jouer à cette version exacte dans PlayDrop, avec le véritable hôte du SDK. Les fonctions du serveur hébergé ne s’exécutent que sur les versions envoyées : testez-les donc de cette façon.

Quand tout fonctionne, publiez cette version exacte avec `publish_game_version`, en passant `gameId`, `version`, `expectedCurrentVersion` et, si la personne que vous aidez en a choisi une, `visibility` (`public` ou `unlisted`). Cette opération réutilise les fichiers, la fiche et la vérification déjà testés. Ne renvoyez pas le jeu pour le publier.

Pour essayer une version locale dans le cadre PlayDrop avant de l’envoyer, ouvrez `https://www.playdrop.ai/@<username>/<slug>/dev?url=<URL-encoded local address>` dans un navigateur ordinaire, sur la machine qui exécute le serveur local.

## Choisissez qui peut jouer

`visibility` accepte `public`, `unlisted` et `private`. Pour un nouveau jeu sans choix explicite, utilisez le réglage enregistré du créateur : `upload_game` l’applique quand vous omettez la visibilité, et `get_account` l’indique dans `publishing.defaultVisibility`. Pour une mise à jour, conservez le `gameVisibility` du jeu issu de `list_games`, sauf si la personne que vous aidez le change ; `upload_game` le fait quand vous omettez la visibilité, et un paquet l’indique explicitement. Non répertorié signifie que toute personne qui a le lien peut jouer ; ce n’est pas une liste d’amis. Ne rendez jamais un jeu plus visible que ne le souhaitait la personne que vous aidez. Détails : [qui peut jouer](https://www.playdrop.ai/fr/create/learn/distribution).

## Transmettez le bon lien

Les reçus des jeux publics et non répertoriés contiennent `shareUrl`, la page durable du jeu : c’est ce lien qu’il faut transmettre à la personne que vous aidez. Une version privée renvoie `url`, le lien de cette version exacte pour le propriétaire. Les reçus de paquet listent chaque élément ; les éléments terminés restent publiés même si un élément suivant échoue.

## Mettez à jour un jeu

Consultez `list_games` et la version actuelle, conservez le `name` et envoyez une copie complète : tous les fichiers et toutes les métadonnées voulus, car les champs omis sont absents de la nouvelle version. Les éléments du catalogue omis ne sont jamais supprimés. Utilisez `get_game_version` pour lire le catalogue exact de la version que vous modifiez, y compris l’état de ses réglages (Tweaks).

## Limites

- Voie simple : un seul fichier HTML de 10 MiB maximum.
- Paquet : 512 descripteurs de fichiers de dossier ou 512 entrées d’archive (catalogue.json et répertoires compris), 50 MiB par fichier, 200 MiB décompressés au total et 1 MiB de JSON de catalogue.
- Archives : chemins relatifs sûrs uniquement ; les chemins en double, les liens symboliques et les archives chiffrées, en plusieurs parties ou ZIP64 sont refusés.
- Les envois préparés expirent au bout de 30 minutes.

## Erreurs et nouvelles tentatives

Les erreurs contiennent `error`, `message`, `retryable`, `nextAction`, `docsUrl` et `documentationTopic`. Suivez `nextAction`. Après une réponse perdue, réessayez avec un contenu identique et le même `requestId` ; un contenu modifié en exige un nouveau. Consultez [erreurs et reprise](https://www.playdrop.ai/fr/create/learn/errors).

Utilisez `send_feedback` pour signaler un problème reproductible ou une étape déroutante, sans jetons ni URL signées.

## Guides associés

- [Jeux HTML simples](https://www.playdrop.ai/fr/create/learn/html-games): Publiez un fichier HTML autonome de 10 MiB maximum avec upload_game : ce qui convient, le mini catalogue, la visibilité, les mises à jour et quand passer au paquet.
- [Paquets et .play](https://www.playdrop.ai/fr/create/learn/packaging): Organisez un dossier, ZIP ou .play compilé avec catalogue.json à la racine, déclarez médias de fiche et serveurs, puis envoyez avec prepare_catalogue_upload.
- [Visibilité et audience](https://www.playdrop.ai/fr/create/learn/distribution): Choisissez qui peut ouvrir un jeu, gérez le réglage par défaut et les versions, et attirez des joueurs avec Boost, Échange de parties, Instantané et la recherche.
- [Erreurs et reprise](https://www.playdrop.ai/fr/create/learn/errors): La forme des erreurs renvoyées par les outils MCP de PlayDrop, quand réessayer avec le même requestId, et la correction de chaque code d’erreur courant.
