Skip to main content
Une app est un workflow empaqueté pour des exécutions en un clic sans canevas. C’est un répertoire sur votre machine qui contient quatre choses : Les bundles vivent sous le répertoire utilisateur de ComfyUI à <user>/comfyui-mcp-panel/apps/<app-id>/ — volontairement pas le répertoire des workflows, pour qu’une app masquée ne apparaisse jamais dans le navigateur de workflows.
La raison pour laquelle les apps existent comme leur propre couche : le canevas est la mauvaise interface pour exécuter un workflow auquel vous faites déjà confiance. Un formulaire avec cinq champs étiquetés est la bonne, et c’est la seule interface qu’un téléphone ou un agent puisse piloter du tout.
Il y a une implémentation de stockage et d’exécution — les routes HTTP du pack du panneau (/comfyui_mcp_panel/apps/*). Le panneau bureau, l’onglet Apps mobile, et les outils MCP apps_* en sont tous des clients, donc une app se comporte de façon identique d’où que vous la lanciez.

Prérequis

Les apps sont servies par le pack du panneau (comfyui-mcp-panel), pas par le serveur MCP tout seul. Si le pack sur votre ComfyUI précède la fonctionnalité, apps avec action:"list" échoue avec un message explicite « the panel pack on this ComfyUI predates the Apps feature » — mettez à jour le pack et redémarrez ComfyUI.

Convertir un workflow en app

Dans le panneau, le bouton de barre d’outils Apps (à côté de Civitai) ouvre la grille d’apps. Convertir le workflow ouvert fait trois choses :
  1. Importe la config mode APP de ComfyUI si le workflow en porte déjà une, et sinon choisit les entrées et sorties heuristiquement (widgets de prompt, seeds, réglages de sampler ; nœuds de classe SaveImage comme sorties). Les entrées mode APP importées sont honorées sur n’importe quel type de nœud, donc les endpoints de nœuds personnalisés survivent à la conversion.
  2. Analyse les dépendances — les modèles et packs de nœuds personnalisés dont le graphe a besoin — dans manifest.deps.
  3. Prend un instantané du prompt au format API. Les valeurs de widgets au moment de la conversion deviennent le default de formulaire de chaque entrée.
Chaque entrée de appMode.inputs porte nodeId, widget, label, et un kind parmi text, number, combo, toggle, image, ou model ; les combos portent aussi choices. C’est ce dont le formulaire d’exécution se rend — sur le bureau et sur mobile.

Masquer le workflow

hideWorkflow retire entièrement workflow.json du bundle, donc le graphe n’est pas remis à qui exécute ou installe l’app.
hideWorkflow est de l’obfuscation, jamais de la sécurité. Le prompt API reste visible à quiconque exécute l’app via le /history propre de ComfyUI, et les modèles et nœuds personnalisés que l’app installe révèlent les dépendances du graphe. Traitez-le comme « ne pas encombrer mon navigateur de workflows », pas comme une protection pour un graphe que vous ne pouvez pas vous permettre de laisser fuiter.

Exécuter une app

Une exécution patche vos valeurs de formulaire dans l’instantané stocké et met le résultat en file. Les clés de patch sont "<nodeId>.<widget>" — par exemple {"6.text": "a cat", "3.seed": 42}. La clé se coupe seulement sur le premier point, donc les noms de widgets qui contiennent eux-mêmes des points (piles LoRA, lora_1.model) restent intacts. Le patch est strict : une clé qui adresse un nœud ou une entrée qui n’existe pas dans l’instantané est une erreur dure, pas un saut silencieux. Un raté veut dire que le manifeste a dérivé de l’instantané, et échouer fort vaut mieux que d’exécuter avec des valeurs périmées. Les entrées que vous omettez gardent leurs défauts du moment de la conversion. L’exécution renvoie un prompt_id ; sondez-le pour le statut (pendingrunningdone, ou unknown si ComfyUI n’en a jamais entendu parler) et pour les sorties regroupées sous chaque nœud de sortie.

Exécuter sur un pod RunPod

Le chemin Exécuter sur RunPod du panneau réutilise le même moteur de patch en mode dry : le panneau demande le prompt patché sans le mettre en file localement, pousse les dépendances épinglées vers le pod, et met le prompt en file là-bas à la place.
Les apps avec une entrée image refusent de s’exécuter sur un pod. Les envois atterrissent sur le ComfyUI local, que le pod ne peut pas atteindre — donc le panneau refuse honnêtement plutôt que de mettre en file une exécution qui échouerait sur un fichier manquant.

Publier et Explorer

L’onglet Explorer du panneau est un registre public (un Cloudflare Worker adossé à D1 + R2) avec des listes tendances / nouveaux / plus étoilés et une recherche. Tendances = stars * 3 + runs sur 7 jours. Publier envoie le bundle — manifeste, prompt, workflow sauf s’il est masqué, vignette — sous une identité de créateur à clé sha256. Installer depuis Explorer affiche d’abord une boîte de dialogue de consentement aux dépendances : les deps d’une app sont signalées, jamais installées en silence. Rien n’installe un modèle ou un pack de nœuds personnalisés sur votre machine parce que vous avez appuyé sur une carte.
pricing_json et hosted_only existent dans le schéma du manifeste et sont transmis tels quels, mais rien ne les lit. Ils réservent de la place pour une phase de monétisation uniquement conçue — il n’y a aucun comportement d’app payante aujourd’hui.

L’outil MCP apps

Un outil avec cinq actions, toutes de minces proxies au-dessus de l’API Apps du panneau. C’est la surface sans canevas : ce que l’appli mobile et un agent piloté directement utilisent. Il est sur la liste blanche call_tool de l’orchestrateur — list/get/run_status sont en lecture seule, et run porte la même posture de risque que enqueue_workflow (il met en file un job que l’utilisateur a explicitement lancé).

Paramètres

action est le seul paramètre exigé par le schéma — chaque action a besoin d’un sous-ensemble différent, donc le reste est optionnel dans le schéma et leur présence est imposée par le gestionnaire, qui nomme le champ qui manque. La contrainte de forme de prompt_id est imposée deux fois — à la frontière du schéma et encore à l’intérieur du gestionnaire — parce que l’id est interpolé dans un chemin d’URL. Un « prompt id » en forme de traversée ne doit jamais atteindre le constructeur d’URL même si un appelant contourne le schéma. Pour la référence de schéma générée par outil, voir Outils Apps.

Importer depuis le registre

action:"import" récupère le bundle du registre côté serveur et le crée comme une app locale. L’id du registre devient l’id local, donc réimporter une app que vous avez déjà signale un conflit d’id plutôt que de la dupliquer. La vignette vit à un endpoint de registre séparé et est récupérée et transmise séparément, donc une app installée garde son illustration de carte. Les dépendances ne sont pas installées. L’outil renvoie les deps du manifeste pour que l’appelant puisse les signaler et laisser l’utilisateur les installer délibérément.
registry_url est une liste blanche, pas une URL libre. La récupération se fait sur le serveur, donc une URL arbitraire serait une primitive SSRF — adresses loopback ou LAN, ou une URL publique qui redirige vers l’une d’elles. Seul le registre public par défaut est accepté sauf si l’opérateur met en liste blanche des origines supplémentaires via COMFYUI_MCP_REGISTRY_URLS (séparées par des virgules, prévu pour le dev/la préprod). Les redirections sont refusées net plutôt que suivies.

Limites et validation

Des choses que vous pouvez vraiment rencontrer : Validation que vous remarquerez :
  • Les ids d’app doivent être des uuid. Tout le reste est rejeté avant qu’un chemin soit construit, et le chemin de bundle résolu est revérifié pour rester sous la racine des apps.
  • Un prompt doit être au format API — clés d’id de nœud numériques, chaque nœud un objet {class_type, inputs}. Les graphes au format UI sont rejetés.
  • Un workflow UI est requis sauf si hideWorkflow est défini.
  • Créer une app qui existe déjà est un conflit, pas un écrasement.
  • Les mises à jour partielles de manifeste sont vraiment partielles. Publier ou masquer une app n’envoie que ses propres champs et n’effacera pas votre nom, description, ou appMode.
  • Les clés de manifeste inconnues sont abandonnées, sauf les champs pass-through réservés, donc une machine plus ancienne ignore les champs qu’elle ne comprend pas au lieu d’échouer.
La racine des apps est remplaçable avec COMFYUI_MCP_APPS_DIR (surtout pour les tests) ; par défaut elle est dérivée du propre répertoire utilisateur de ComfyUI, donc elle survit aux installations portables.

Sur le téléphone

L’appli mobile livre un vrai onglet Apps — pas un aperçu. Il a deux moitiés :
  • Mes apps — les apps installées sur votre machine, listées via le pont avec action:"list". Appuyer sur l’une ouvre un formulaire d’exécution généré, la met en file avec action:"run", et sonde action:"run_status" toutes les 2 s (borné à 30 minutes) jusqu’à ce que les sorties s’affichent.
  • Explorer — le registre public, frappé directement en HTTPS depuis le téléphone (pas de saut de pont, donc la navigation marche avant que vous ayez appairé). Installer va dans l’autre sens : la machine récupère le bundle elle-même via action:"import".
C’est la chose la plus claire que le téléphone peut faire et que le chat ne peut pas — exécuter un vrai workflow, avec de vraies entrées, sans canevas nulle part en vue.

Voir aussi