MCP référence de l'outil
Chaque outil Showly MCP — portée, paramètres, forme de retour, comportement d'audit.
Chaque outil exposé par le serveur Showly MCP. Chaque entrée répertorie la portée requise, le schéma d'entrée sous forme abrégée, la forme de retour et ce qui est écrit dans le journal d'audit.
Tous les outils nécessitent un client MCP authentifié. Les jetons sont émis à partir des Paramètres de l'espace de travail → MCP clients.
Quand un appel est bloqué
Tout échec renvoyé par Showly utilise la même enveloppe : ceux qu'un outil décide comme ceux que la couche MCP décide avant son exécution (une portée absente du jeton, un argument ou un résultat trop volumineux). ok vaut false et error est un code de type string sur lequel vous pouvez brancher, jamais un objet. Un refus de la couche MCP positionne en plus l'indicateur MCP isError, si bien qu'un client qui s'y fie voit toujours un appel en échec ; le texte qui accompagne l'indicateur est ce même JSON.
Trois échecs n'utilisent pas cette enveloppe, car le SDK MCP y répond avant que le moindre code Showly ne s'exécute. Tous trois arrivent sous la forme isError: true avec un message en texte brut :
- Un argument manquant ou d'un type erroné :
MCP error -32602: Input validation error: Invalid arguments for tool <name>: …. C'est l'échec le plus fréquent que produit une intégration, alors analysez le corps de manière défensive. - Un nom d'outil que ce serveur n'expose pas :
MCP error -32602: Tool <name> not found. - Un plantage inattendu : panne de transport ou bogue.
Un argument que l'outil ne déclare pas ne figure pas dans cette liste et n'est même pas un échec : le SDK écarte les clés inconnues avant l'appel, si bien que l'outil ne voit que les arguments qu'il a déclarés.
Traitez un corps que vous ne pouvez pas analyser comme une erreur inconnue plutôt que de supposer un code.
{
ok: false,
error: "insufficient_credits",
message: "A production deployment costs 5 credits and this workspace has 2 left.",
status?: 402,
resolvedBy: "agent" | "human",
actionUrl?: "https://showly.ai/app/billing#upgrade",
humanAction?: "Open Plan & Billing and add credits, then tell the agent to retry.",
agentNext: {
kind: "retry" | "retry_with" | "call_tool" | "poll" | "wait_for_human" | "stop",
tool?: "publish_site",
afterSeconds?: 10,
note: "After the balance changes, start the publish over from step 1."
}
}
Lisez resolvedBy en premier. "agent" signifie que vous pouvez corriger le problème vous-même avec les outils dont vous disposez déjà : choisir un autre previewSlug, récupérer l'id manquant, ou appeler l'outil nommé par agentNext.tool. "human" signifie qu'aucune suite d'appels n'y changera rien : transmettez humanAction et actionUrl à l'utilisateur, puis suivez agentNext.
actionUrl est absolue et pointe vers une page de l'application web Showly, jamais vers une zone réservée aux administrateurs. Transmettez actionUrl sous forme de lien lorsqu'elle est présente, et transmettez humanAction à chaque fois : c'est cette phrase qui rend le lien utilisable par la bonne personne. Forfait et facturation est le cas qui compte : la page est réservée aux propriétaires, aux administrateurs et au rôle de facturation, et le paiement exige en plus billing:write, si bien qu'un membre qui suit le lien est renvoyé au tableau de bord. Showly ne peut pas savoir lequel des deux lit votre message — la page tranche à partir de la session web de la personne, alors qu'un jeton MCP décrit l'agent —, donc le lien part toujours et humanAction porte la réserve : un propriétaire agit dessus, quiconque d'autre le transmet. L'ancien webUpgradeUrl sur un échec de forfait ou de crédits porte la même URL et la même réserve.
Les mêmes quatre champs apparaissent sur le seul succès qui réclame une personne : request_publish renvoie resolvedBy, actionUrl, humanAction et agentNext au niveau supérieur, exactement là où un échec les place, si bien que if (result.actionUrl) fonctionne dans les deux cas. Ils sont également répétés dans data, à côté de l'ancien webApprovalUrl, pour qu'une intégration qui lit data.actionUrl continue de fonctionner.
Deux champs plus anciens accompagnent toujours actionUrl avec la même valeur, afin que les intégrations existantes continuent de fonctionner : webVerificationUrl sur email_verification_required et webApprovalUrl sur un request_publish réussi.
list_projects
Portée : project:read
Répertorie les projets (espaces de travail) que le jeton peut voir.
Input: {}
Output: { ok, data: Array<{ id, name, slug, createdAt }> }
Audit: mcp.list_projects
list_sites
Portée : site:read
Répertorie les sites dans l'espace de travail actuel. Passez projectId pour définir la portée de la liste ; un jeton MCP à l'échelle du projet force ce filtre quel que soit le paramètre.
Input: { projectId?: string }
Output: { ok, data: Array<Site>, view: ListSitesView }
Audit: mcp.list_sites
C'est le seul outil qui répond avec deux blocs de texte. Le premier est un résumé rédigé côté serveur — les noms des sites, ceux qui sont publics et une action recommandée — et se lit donc de la même façon à chaque appel. Le second est l'enveloppe JSON ci-dessus, inchangée : lisez-la depuis content[content.length - 1], et non depuis content[0]. La même enveloppe est également renvoyée dans structuredContent, et view est la projection dont partent à la fois le résumé et le rendu interactif décrit ci-dessous.
Un client qui déclare l'extension MCP Apps io.modelcontextprotocol/ui dans ses capacités initialize reçoit en plus _meta.ui.resourceUri sur cet outil, qui pointe vers une ressource HTML ui:// que l'hôte affiche dans une iframe isolée. Un client qui ne la déclare pas ne voit jamais ces métadonnées, et rien d'autre du résultat ne change.
get_site_context
Portée : site:read
Renvoie le site, son framework détecté, les routes, les noms de variables d'environnement référencés, la dernière URL d'aperçu et le dernier identifiant de déploiement de production pour un siteId donné. Voir la forme Site dans [Types courants](#common-types).
Input: { siteId }
Output: { ok, data: { site, framework, routes, envReferences, latestPreviewUrl, lastProductionDeploymentId } }
Audit: mcp.get_site_context (records siteId)
create_change_plan
Portée : site:read
Produit une proposition de plan de changement. Ne modifie _pas_ aucun fichier. L'agent lit généralement le plan renvoyé, demande confirmation à l'utilisateur, puis appelle apply_site_patch.
Input: { siteId, request: string }
Output: { ok, data: { siteId, request, plan, nextStep } }
Audit: mcp.create_change_plan
apply_site_patch
Portée : site:write
Modifications du fichier Stages pour un site. L'ensemble de modifications par étapes est temporaire et doit être matérialisé par create_preview.
Input: { siteId, files: Array<{ path, content }>, message: string }
Output: { ok, data: { changesetId, siteId, fileCount, ttlSeconds, nextStep } }
Audit: mcp.apply_site_patch (records siteId + changesetId + file count)
create_preview
Portée : preview:create
Construit l'espace de travail corrigé et produit une URL d'aperçu. L'utilisateur est propriétaire du décision d'accès privé : omettez access pour un court XXX-XXX généré par le serveur mot de passe, transmettez un mot de passe personnalisé de 6 à 128 caractères ou sélectionnez organization (Pro+) ou organization_or_password. Le texte brut généré est renvoyé une fois et ne peut pas être récupéré ultérieurement. Un aperçu ne peut pas être public ; publiez-le en direct quand il devrait être visible par tout le monde. previewSlug peut choisir une adresse distincte sur un seul niveau : <previewSlug>.showly.site.
Input: { changesetId?, siteId?, files?, previewSlug?, access?: { mode, password? } }
Output: { deploymentId, previewUrl, framework?, fileCount?, access: { mode, passwordConfigured, password? } }
Audit: mcp.create_preview
create_github_preview
Portée : preview:create
Crée un aperçu privé à partir du dernier commit sur le GitHub connecté à un site branche. Les informations d'identification d'installation restent à l'intérieur de Showly. Omettez access pour obtenir un mot de passe court XXX-XXX généré par le serveur renvoyé une fois, transmettez un 6 à 128 personnalisé mot de passe de caractère, ou choisissez l'accès membre de l'organisation sur Pro+. Cet outil ne publie jamais Live. Sondage get_preview_status aux retournés deploymentId.
Si le site n'a pas de référentiel d'applications GitHub actif, connectez-le d'abord dans Showly Web. La construction automatique du référentiel prend actuellement en charge les cibles de déploiement statiques ; une dynamique la cible du conteneur renvoie repository_build_target_unsupported avant tout est en file d'attente. Un e-mail Showly non vérifié renvoie email_verification_required avec une URL Web pour terminer la vérification.
set_preview_access
Portée : preview:create
Modifie la politique d'accès d'un aperçu ou d'un déploiement Live publié sans modifier son URL. Pour protéger un site publié, utilisez l'identifiant production prêt fourni par list_deployments ; l'outil conserve son nom historique pour compatibilité. Le mode mot de passe fait pivoter le mot de passe ; transmettez une valeur de 6 à 128 caractères ou omettez password pour générer un court XXX-XXX code de partage côté serveur. La réponse affiche le nouveau mot de passe en texte clair une fois à côté de previewUrl. Chaque politique la modification invalide les cookies d’accès en aperçu précédemment émis.
Les modes d'organisation vérifient l'adhésion active à l'organisation Showly du visiteur, afin que les coéquipiers se connectent au lieu de partager un mot de passe. organization_or_password conserve ce flux interne tout en permettant à un réviseur externe d'utiliser un mot de passe.
Input: { deploymentId, access: { mode: "password" | "organization" | "organization_or_password", password? } }
Output: { deploymentId, target, previewUrl, access: { mode, passwordConfigured, password? }, policyVersion, advancedDeploymentControls }
Audit: mcp.set_preview_access
Exemple de rotation de mot de passe personnalisé :
{
"deploymentId": "00000000-0000-4000-8000-000000000000",
"access": { "mode": "password", "password": "ABC-123" }
}
retry_deployment
Portée : preview:create
Reconstruit un déploiement préliminaire échoué ou annulé. Rapprovisionnez le même files que vous avez donné create_preview — la source n'est pas conservée côté serveur, donc files est obligatoire. Crée un nouveau deploymentId (celui qui a échoué reste dans l'historique) dans status: "building" et le renvoie pour interrogation. Chaque nouvelle tentative compte dans votre quota de déploiement mensuel : il s'agit d'une nouvelle version. Renvoie 409 not_retryable si le déploiement est encore en cours de construction ou est déjà prêt, 404 s'il n'est pas visible pour votre jeton, 402 si vous dépassez le quota.
Input: { deploymentId, files: [{ path, content }] }
Output: { ok, data: { deploymentId, status: "building", pollUrl, retriedFrom } }
Audit: mcp.retry_deployment
run_checks
Portée : checks:run
Exécute la matrice de vérification de l'espace de travail (peluches, types, hooks CI personnalisés) par rapport à un aperçu. checks est une liste de { id, status } lignes (lint / typecheck / build / audit-gate) ; summary est une chaîne d'une seule ligne telle que "3 passed / 1 pending".
Input: { deploymentId }
Output: { ok, data: { deploymentId, checks: [{ id, status }], summary } }
Audit: mcp.run_checks
request_publish
Portée : publish:request
Ouvre une demande d’approbation pour un déploiement préliminaire prêt. La réponse comprend un lien profond webApprovalUrl ; faire apparaître ce lien afin que l'utilisateur puisse consulter le contenu exact Prévisualisez et complétez toute approbation à la deuxième personne requise par le plan. La publication fait ne nécessite pas d’inscription à OTP/MFA. L'utilisateur lié au jeton MCP doit avoir un e-mail du compte Showly vérifié. Si l'outil retourne email_verification_required, envoyez l'utilisateur vers webVerificationUrl pour renvoyer et effectuez la vérification avant de réessayer.
Input: { deploymentId, message: string }
Output: { approvalId, deploymentId, state: "pending", expiresAt, reused, webApprovalUrl }
Audit: mcp.request_publish
publish_site
Portée : publish:confirm
Publie un déploiement préliminaire prêt en production directement à partir de la conversation — pour les espaces de travail solo et les plans sans workflows d'approbation. L'utilisateur lié au jeton MCP doit disposer d'une adresse e-mail de compte Showly vérifiée. Si l'outil renvoie email_verification_required, envoyez l'utilisateur vers webVerificationUrl, attendez qu'il termine la vérification, puis redémarrez le flux en deux étapes ; le site n'est pas encore en ligne. En deux étapes confirmé par l'homme : appelez avec siteId + deploymentId (non confirmationToken) pour obtenir un résumé + de courte durée confirmationToken ; montrez à l'utilisateur ce qui est sur le point d'être mis en ligne, puis rappelez-le avec le jeton. L'étape 2 renvoie 202 publishing. Sur les plans avec des flux de travail d'approbation activés, utilisez plutôt request_publish : cet outil vous y dirige.
Step 1: { siteId, deploymentId } → { confirmationToken, summary }
Step 2: { siteId, deploymentId, confirmationToken } → { siteId, deploymentId, status: "publishing" }
Audit: mcp.publish_site
Les hôtes qui affichent les MCP Apps peuvent éviter l’aller-retour de l’étape 1 : la carte d’un Preview prêt porte un bouton Publish live, et un clic envoie la confirmation de l’utilisateur dans la conversation sous forme de message. Traitez ce message comme la confirmation : enchaînez le contrôle préalable et la publication confirmée, puis répondez une seule fois, avec le résultat. Rien d’autre ne change : les deux mêmes appels, le même jeton émis par le serveur, les mêmes blocages et le même coût en crédits que tout déploiement en production.
get_preview_status
Portée : preview:read
Renvoie l'état actuel d'un déploiement préliminaire. Éventuellement, des interrogations longues (30 s par défaut, jusqu'à 60 s) jusqu'à ce que le statut s'éloigne d'une valeur connue - utile après request_publish en attendant un réviseur. Lorsque status est failed ou canceled, le résultat contient également errorCode, errorMessage, stage et un court logTail expliquant pourquoi la construction a échoué ; associez-le avec retry_deployment pour reconstruire.
Input: { deploymentId, waitForChange?: boolean, currentStatus?: string, timeoutMs?: number }
Output: { ok, data: Deployment & { productionUrl?, errorCode?, errorMessage?, stage?, logTail? }, changed?, timedOut? }
Audit: mcp.get_preview_status
get_deployment_logs
Portée : logs:read
Renvoie la queue du journal de build pour un déploiement (les dernières lignes lineCount, par défaut 200, de la sortie de build capturée). source discrimine db (lignes de journal réelles), pending (le déploiement existe mais aucun journal n'a encore été capturé - toujours en construction ou pas de queue) ou not-found (aucun déploiement de ce type pour ce jeton).
Input: { deploymentId, lineCount?: number }
Output: { ok, data: { deploymentId, lineCount, source, lines } }
Audit: mcp.get_deployment_logs
diagnose_deployment
Portée : logs:read
Diagnostiquez automatiquement l'un de vos propres déploiements. Renvoie un seul ensemble de diagnostic structuré et consommable par l'IA afin que l'agent puisse expliquer pourquoi une build a échoué en un seul appel - puis corriger la source et retry_deployment - plutôt que d'assembler des lectures get_preview_status / get_deployment_logs distinctes. Le bundle regroupe : l'échec de build (stage, errorCode, errorMessage, un logTail), les erreurs d'exécution associées de Sentry (corrélées par le commit SHA + environnement + une fenêtre autour du déploiement, fail-soft), le statut ops-job du déploiement, le statut quota de l'organisation, tout clientLogs poussé par l'agent (expurgé + plafonné) et déterministe hypotheses — causes profondes probables avec une confiance (par exemple quota_exceeded / build_install_failed), dérivées de règles (et non de l'IA) comme point de départ de haute qualité.
Isolé par le locataire : vous ne pouvez diagnostiquer les déploiements que dans votre propre organisation. Un identifiant de déploiement qui n'est pas visible pour votre jeton renvoie 404 (impossible à distinguer d'un identifiant inexistant – aucune fuite d'existence entre organisations). Il s’agit du jumeau face à l’agent du pack Staff Diagnostics Center ; les deux partagent un agrégateur backend. Appelle GET /deployments/:deploymentId/diagnostics.
Input: { deploymentId }
Output: { ok, data: { deployment, failure, jobRun, quota, sentry, clientLogs, hypotheses } }
Audit: mcp.diagnose_deployment
list_templates
Portée : template:read
Répertorie Showly modèles de site disponibles pour le jeton actuel. Associez-le à create_site_from_template pour intégrer un nouveau site sans dépôt Git.
Input: { framework?: string }
Output: { ok, data: Array<{ slug, displayName, description, framework, screenshots }> }
Audit: mcp.list_templates
create_site_from_template
Portées : template:create, site:write
Matérialise un nouveau site géré par Showly à partir d'un modèle et construit son premier Aperçu privé. Omis access génère un mot de passe appartenant au serveur renvoyé exactement une fois avec initialPreviewUrl ; les modes d'organisation nécessitent Pro. siteSlug est l'adresse stable <siteSlug>.showly.site pour ce premier aperçu comme pour Live.
Input: { projectId, templateSlug, name, siteSlug, variables?: Record<string, unknown>, access?: { mode, password? } }
Output: { ok, data: { siteId, projectId, initialVersionId, initialPreviewDeploymentId, initialPreviewUrl, access, templateSlug, createdAt } }
Audit: mcp.create_site_from_template
create_site_from_html
Portées : site:write, preview:create
Crée un nouveau site géré par Showly directement à partir de simples fichiers HTML/CSS/JS — pas de modèle, pas de framework, pas de dépôt Git. Transmettez soit les fichiers en ligne (index.html requis ; encoding: "base64" pour les actifs binaires), ou un sourceBundleId pour une source volumineuse que vous avez téléchargée hors bande via request_upload_url (exactement l'un des files / sourceBundleId). Le site est créé et son premier aperçu est construit en un seul appel ; interrogez le deploymentId renvoyé avec get_preview_status. siteSlug devient l'adresse partagée <siteSlug>.showly.site pour Aperçu/Live. La production reste sur le flux de publication.
Input: { projectId, name, siteSlug, files?: Array<{ path, content, encoding?: "utf8" | "base64" }>, sourceBundleId?, framework?, access?: { mode, password? } }
Output: { ok, data: { siteId, deploymentId, status | previewUrl, access, ... } }
Audit: mcp.create_site_from_html
request_upload_url
Portées : site:write, preview:create
Crée une URL d'envoi de courte durée et à usage unique pour une source de site volumineuse qui ne doit pas transiter par le modèle. Envoyez une archive tar vers le uploadUrl renvoyé avec PUT et Content-Type: application/x-tar, puis appelez create_site_from_html avec le sourceBundleId renvoyé à la place de files.
Input: {}
Output: { ok, data: { uploadUrl, sourceBundleId, contentType, expiresInSeconds } }
Audit: mcp.request_upload_url
request_download_url
Portée : site:read
L'outil de lecture correspondant à request_upload_url. Passez un deploymentId visible pour recevoir un downloadUrl de courte durée et à usage unique pour son archive source conservée. Modifiez l'archive localement, envoyez la nouvelle source avec request_upload_url, puis passez son sourceBundleId à create_preview. Renvoie source_not_retained (422) lorsqu'aucune archive source n'est disponible ; utilisez get_site_files pour les petits sites.
Input: { deploymentId }
Output: { ok, data: { downloadUrl, expiresInSeconds } }
Audit: mcp.request_download_url
claim_trial_site
Portées : site:write
Réclame un site créé via le flux d'essai public de Showly dans le compte authentifié actuel, afin qu'il cesse d'expirer et devienne permanent. Passez les trialId + guestToken fournis par le serveur. Échoue si l'essai a expiré ou si l'espace de travail possède une restriction explicite sur les sites actifs ; supprimez alors un site inutilisé ou contactez l’assistance Showly, puis réessayez. Free et Pro autorisent par défaut un nombre illimité d’aperçus et de sites en ligne ; changer d’offre n’ajoute pas de sites.
Input: { trialId: string, guestToken: string }
Output: { ok, data: { trialId, siteId, claimed: true } }
Audit: mcp.claim_trial_site
delete_preview
Portée : preview:create
Supprime de manière logicielle un déploiement d'aperçu par identifiant. Renvoie deletedAt. Idempotent — la suppression d'un aperçu déjà supprimé renvoie 404 preview_not_found. Seuls les aperçus peuvent être supprimés ici ; la production n’est pas affectée.
Input: { deploymentId }
Output: { ok, data: { deploymentId, deletedAt } }
Audit: mcp.delete_preview
delete_site
Portée : site:delete
Supprime de manière logicielle un site et en cascade vers ses déploiements, versions et domaines personnalisés. En deux étapes confirmé par l'homme : appelez avec siteId (pas de confirmationToken) pour obtenir un résumé (le slug + le nombre de déploiements en cascade) plus un confirmationToken de courte durée ; montrez à l'utilisateur, puis rappelez-le avec le jeton à supprimer. Récupérable uniquement à partir d'une sauvegarde.
Step 1: { siteId } → { confirmationToken, summary: { siteSlug, cascade: { deployments } } }
Step 2: { siteId, confirmationToken } → { siteId, deletedAt }
Audit: mcp.delete_site
list_site_domains
Portée : site:read
Répertorie les domaines personnalisés attachés à un site, y compris l'étape guidée en cours, les enregistrements DNS, l'état du certificat, le CTA de récupération, la page de gestion et l'URL en ligne. Les résultats contiennent 50 lignes par défaut et acceptent jusqu'à 100 lignes. Lorsque pagination.nextCursor n'est pas null, renvoyez-le sans modification comme cursor ; les curseurs sont opaques et liés à un seul site.
Pour un résultat non vide, suivez le domains[].journey de chaque ligne cible ; il n'existe pas de journey de premier niveau. Un journey de premier niveau est renvoyé uniquement pour une liste vide, afin de guider la première connexion de domaine. Interrogez un domaine cible uniquement tant que sa phase est setting_up_https, puis arrêtez à needs_attention.
Input: { siteId, limit?, cursor? }
Output: { ok,
journeyGuide: { steps, whatShowlyGivesYou },
domains: [{ id, hostname, status, isLive, certStatus, liveUrl,
manageUrl, dnsRecords, proxyNote, apexNote?,
journey: { phase, currentStep, stepStatuses,
whereYouAre, userAction, agentAction,
actionUrl }, recovery? }],
pagination: { count, total, nextCursor },
journey? }
Audit: mcp.list_site_domains
add_custom_domain
Portée : site:write · Disponible avec tous les forfaits
Attache le propre domaine d'un client à un site et renvoie les enregistrements DNS que l'utilisateur doit publier auprès de son fournisseur de domaine.
Vous ne pouvez pas effectuer cette étape à leur place. La revendication crée un enregistrement en attente et n'achemine aucun trafic ; le domaine ne devient réel qu'une fois que le client modifie DNS chez la personne à qui il l'a acheté. Remettez-leur les enregistrements, dites clairement que rien ne se passe jusqu'à ce qu'ils les ajoutent et attendez. Sur un domaine racine, la réponse porte un apexNote — faites-la apparaître, car un simple CNAME n'est pas valide au sommet d'une zone. Chaque réponse porte aussi un proxyNote : relayez-le, car le CNAME doit être publié sans proxy (sur Cloudflare, un nuage gris ; les nouveaux enregistrements sont oranges), sinon le certificat ne pourra jamais être émis, et l'enregistrement TXT se vérifie dans les deux cas, donc rien d'autre dans le flux ne le détectera.
Conservez le verificationToken renvoyé ; verify_custom_domain en a besoin et il n'est affiché qu'une seule fois.
Input: { siteId, hostname }
Output: { ok, domain: { id, hostname, status, dnsRecords, proxyNote, apexNote?, verificationToken }, nextStep }
Audit: mcp.add_custom_domain
verify_custom_domain
Portée : site:write · Disponible avec tous les forfaits
Revérifie DNS pour un domaine en attente. Appelez-le après que l'utilisateur a déclaré avoir ajouté les enregistrements. Cela ne réussit que si l'enregistrement est réellement publié et propagé — un échec signifie généralement « pas encore », et non « cassé », alors attendez quelques minutes et réessayez plutôt que de signaler une erreur.
En cas de succès, le certificat TLS est demandé automatiquement et le domaine est mis en ligne dans l'heure. Sondez list_site_domains pour isLive.
Input: { siteId, domainId, token }
Output: { ok, domain: { id, hostname, status, isLive, ... } }
Audit: mcp.verify_custom_domain
La suppression d'un domaine n'est délibérément pas disponible pour les agents. L'archivage d'un domaine actif met le site du client hors ligne à l'adresse qu'il a annoncée, instantanément et sans que rien d'autre que Showly n'ait besoin d'être d'accord — cela reste donc l'action d'une personne dans le tableau de bord. Voir ADR 0015.
list_site_versions
Portée : site:read
Répertorie l'historique des versions d'un site (la plus récente en premier) : id, source, changeSummary, auteur, createdAt. Associez-le à get_site_files (en passant un versionId) pour lire le contenu de cette version.
Pagination par jeu de clés. limit majuscules à 100 par page ; pour accéder aux anciennes versions, transmettez le pagination.nextCursor de la réponse précédente en cursor. Un nextCursor sur un null signifie que vous avez atteint la fin de l'historique. Le curseur est opaque et lié à un site : il épingle le catalogue à l'instant de votre première page, de sorte que les versions créées pendant votre page ne peuvent pas déplacer les lignes sur une page que vous avez déjà lue.
hasMore est obsolète et reflète pagination.nextCursor !== null ; préférez pagination.
Input: { siteId, limit?, cursor? }
Output: { ok, data: {
versions: [{ id, source, changeSummary, authorUserId, createdAt }],
hasMore,
pagination: { limit, nextCursor: string | null }
} }
Audit: mcp.list_site_versions
list_deployments
Portée : site:read
Répertorie les déploiements d'un site (le plus récent en premier) : id, target (preview / staging / production), status, url, createdAt. C'est de là que vient le deploymentId — utilisez le id renvoyé avec retry_deployment, delete_preview, request_publish ou publish_site.
Input: { siteId }
Output: { ok, data: [{ id, siteId, target, status, url, createdAt }] }
Audit: mcp.list_deployments
get_site_files
Portée : site:read
Lit l'arborescence des fichiers d'une version du site (path → content) afin que vous puissiez voir le contenu actuel avant de le modifier. Passez siteId + versionId (à partir de list_site_versions). Les versions volumineuses/soutenues par un manifeste renvoient files: null plus un note.
Input: { siteId, versionId }
Output: { ok, data: { versionId, source, changeSummary, files: Record<string,string> | null, note? } }
Audit: mcp.get_site_files
diff_site_versions
Portée : site:read
Compare deux versions et renvoie exactement ce qui a changé : l'état par fichier (added / removed / changed) plus le niveau de ligne add / remove / context. Passez siteId + versionA (l'ancien "avant") + versionB (le plus récent "après"), tous deux à partir de list_site_versions. Répond à des questions telles que « qu'est-ce qui a changé entre hier et aujourd'hui ». Les versions volumineuses/soutenues par un manifeste ne peuvent pas être comparées et renvoient une erreur.
Input: { siteId, versionA, versionB }
Output: { ok, data: {
versionA: { id, source, changeSummary, createdAt },
versionB: { id, source, changeSummary, createdAt },
summary: { filesChanged, filesAdded, filesRemoved, linesChanged },
files: Array<{ path, status, lines: Array<{ type, text }> }>
} }
Audit: mcp.diff_site_versions
rollback_to_version
Portée : rollback:confirm
Revient PRODUCTION à une ancienne version et la publie SANS aperçu — l'outil le plus conséquent ici. Deux étapes confirmées par l'homme : appelez avec siteId + versionId (pas de confirmationToken) pour obtenir un warning + résumé + confirmationToken ; montrez l'avertissement à l'utilisateur, puis rappelez-le avec le jeton. L'étape 2 renvoie 202 building — Showly crée un aperçu de cette version et la promeut automatiquement en production. Récupérable en passant à une version plus récente.
Step 1: { siteId, versionId } → { confirmationToken, warning, summary: { changeSummary, versionCreatedAt, previewed: false } }
Step 2: { siteId, versionId, confirmationToken } → { siteId, versionId, deploymentId, status: "building" }
Audit: mcp.rollback_to_version
Outils de production (non exposés à MCP)
Non exposé MCP — nécessite un flux d'approbation Web/API.
L'ancienne action rollback_deployment n'est pas disponible via MCP. Elle n'apparaît pas dans tools/list et ne peut pas être appelée avec un jeton MCP ; utilisez l'écran d'approbation Showly Web correspondant.
La publication de production est MCP appelable : publish_site (confirmation en deux étapes, ci-dessus) publie directement et rollback_to_version annule la production - deux outils de style kind: "confirm-publish" qui n'agissent jamais au premier appel.
Types courants
La référence utilise quelques formes nommées ci-dessus. L'ensemble de champs concrets est affiché dans le flux de bout en bout, qui parcourt une session complète avec le réel JSON. Résumés rapides :
| Tapez | Champs clés |
|---|---|
Site | id, name, slug, projectId, framework (auto-détecté), repositoryUrl |
Deployment | id, siteId, target (preview / staging / production), status, previewUrl?, createdAt |
plan | la proposition create_change_plan : une liste des modifications de fichiers prévues ainsi qu'un résumé lisible par l'homme ; pas appliqué avant le apply_site_patch |
checks | résultats par vérification de la matrice de vérification de l'espace de travail (peluches, types, hooks CI personnalisés) |
summary | un cumul de checks (nombre de réussites/échecs) renvoyé par run_checks |
status est l'un des queued, building, ready, failed, canceled. ready est l'état de réussite du terminal pour les déploiements en préversion et en production. framework est détecté automatiquement au moment de la construction et fait partie des astro, vite, next-export, static-html, custom ou unknown — ce n'est pas quelque chose que vous définissez dans le manifeste.
Gestion des versions
Les schémas d'outils suivent semver via le champ MCP version. Les modifications majeures envoient un nouveau nom d'outil (apply_site_patch_v2) ; l'ancien nom continue de fonctionner pendant au moins un cycle de publication avec une note de dépréciation dans notes.