Aller au contenu
PalmaPlan — le wiki ← PalmaPlan

La vue embarquée

show_schedule affiche un planning vivant dans la conversation : pas une image ni un export, mais le Gantt de PalmaPlan, peint par le même code que l'écran. Il est éditable si votre rôle le permet et se tient à jour quand quelqu'un d'autre écrit.

show_schedule { schedule: "Migration S/4HANA", view: "gantt", critical_path: true }

Options :

Le rôle réel de l'utilisateur plafonne toujours : editable ne donne jamais plus qu'un rôle n'accorde.

Ce qu'est la vue : une MCP App native

PalmaPlan sert une MCP App : la ressource ui://palmaplan/planning, de type text/html;profile=mcp-app. C'est une page unique : le HTML, le JavaScript et le CSS sont en ligne, et rien ne se charge d'ailleurs. show_schedule, what_if et diff_versions la désignent (_meta.ui.resourceUri). Un hôte qui rend les MCP Apps l'affiche dans la conversation, dans un cadre isolé. Elle s'ouvre en ligne, puis en plein écran sur demande, aux couleurs du thème de l'hôte (clair ou sombre), dans sa langue et son fuseau.

La vue ne parle qu'à l'hôte. Sa CSP n'ouvre aucun domaine : ni connectDomains, ni frameDomains, ni resourceDomains. Elle lit et écrit en appelant les tools du serveur (tools/call), que l'hôte relaie sous le jeton ou l'OAuth du connecteur. La vue n'a donc ni jeton à elle, ni cadre imbriqué, ni accès direct à PalmaPlan. Trois tools lui sont réservés (_meta.ui.visibility: ["app"]) ; l'hôte les cache au modèle :

ToolCe qu'il rend
get_schedule_pagele planning par pages, chaque réponse sous 120 000 caractères (le plafond d'un résultat d'outil chez Claude est d'environ 150 000)
get_changes_sinceles entrées du journal après un rang, pour rester à jour
get_schedule_absencesl'agenda : les noms des membres et les dates de leurs absences, jamais le motif ni l'e-mail

Les trois vues, et l'avant/après

« Accepter » applique exactement ce que l'avant/après montre, et rien d'autre.

Les gestes

Dans le Gantt, quand le rôle le permet :

Chaque geste appelle un tool existant (move_periods, resize_period, set_action_status, undo…), comme le ferait l'agent. Le journal, l'annulation et le temps réel sont donc ceux de l'écran. Une écriture refusée (rôle, verrou, conflit) s'affiche dans la vue. Un lecteur voit une vue qui lit seulement.

Le direct : la vue relit le journal par get_changes_since, d'abord toutes les deux secondes, puis de moins en moins souvent quand rien ne bouge (jusqu'à quinze secondes). Elle s'arrête quand le cadre est caché. Chaque appel de show_schedule monte un nouveau cadre ; une vue plus ancienne du même planning se retire d'elle-même et dit qu'une vue plus récente est ouverte plus bas.

Parler au modèle

La négociation : qui voit quoi

Un hôte MCP Apps annonce l'extension io.modelcontextprotocol/ui avec le type text/html;profile=mcp-app. Le serveur lit trois voies, et la première qui l'annonce suffit :

  1. capabilities.extensions["io.modelcontextprotocol/ui"] à initialize (la voie de la spec stable) ;
  2. capabilities.experimental["io.modelcontextprotocol/ui"] (l'ancienne voie) ;
  3. _meta["io.modelcontextprotocol/clientCapabilities"] d'une requête : la voie du protocole sans état. Le SDK du serveur (1.x) ne parle pas encore ce protocole, mais la voie est lue.

Ce qui en dépend :

Un hôte MCP AppsUn client sans MCP Apps (Claude Code)
tools/listles 101 tools ; l'hôte cache au modèle les trois réservés à la vueles 98 tools du modèle : les trois réservés à la vue ne sont pas listés (rien ne les y cacherait au modèle, et get_schedule_page rend jusqu'à 120 000 caractères)
show_schedulela vue ; un texte qui la résume ; aucun lien ni jetonle texte et le lien /embed d'une heure
what_if, diff_versionsl'avant/après, et leur texteleur texte

L'appel d'un tool réservé reste servi à tous. La visibilité n'est pas une frontière de droits : les mêmes données se lisent par palmaplan://schedule/{id}/json, sous les mêmes droits. Et un hôte qui afficherait la vue sans avoir annoncé l'extension ne la trouve pas vide.

Ce que montre Claude Code : du texte

Claude Code n'affiche pas les MCP Apps. show_schedule y rend un texte qui se suffit : le nom, la période, le nombre de groupes, de lignes, de blocs et de jalons, les risques (liens violés, blocs à risque d'absence) et le lien d'une heure :

Planning « Migration S/4HANA » — du 2026-11-02 au 2026-12-18 ; 2 groupes, 6 lignes, 6 blocs, 1 jalon.
Risques : 1 bloc à risque d absence.
Cet hôte n'affiche pas les vues MCP Apps : cette adresse ouvre le planning, valable une heure, en lecture seule : http://127.0.0.1:4785/embed/<id>?t=…

Son structuredContent est compact : { schedule_id, name, view, options, rank, read_only, shown_at, url, expires_at }. Il ne porte jamais le modèle, parce que Claude Code le donne au modèle à la place du texte. Les 98 tools du modèle sont éprouvés de même par un test : chacun rend un texte utile (un résultat, ou un refus qui dit quoi corriger) et un structuredContent compact.

Le lien /embed, pour les hôtes sans MCP Apps

Le lien ouvre l'écran de PalmaPlan, réduit au planning, dans un navigateur ou dans une iframe d'un autre site. Il porte un jeton signé d'une heure, plafonné au planning et au rôle réel. Ce lien :

Ce n'est pas un jeton nommé : il n'apparaît pas dans Réglages › Connexions et agents › Applications connectées (voir Les jetons et les portées).

Les limites

Ce qui est prouvé, ce qui ne l'est pas

Prouvé, dans le dépôt :

Pas prouvé : aucun hôte réel n'a encore affiché cette vue. Ni Claude Desktop, ni claude.ai, ni un autre hôte MCP Apps. L'hôte de recette suit la documentation, pas le code de Claude : sa CSP exacte, sa façon d'annoncer la capacité MCP Apps à initialize, sa WebView mobile peuvent différer. En particulier, si un hôte réel affiche la vue sans annoncer l'extension, le modèle n'y verra que les 98 tools du modèle, et la vue continuera de fonctionner, puisque les appels réservés restent servis. La marche à suivre de l'essai réel est dans Brancher Claude Desktop, section « L’essai de la vue dans Claude Desktop ». Tant qu'il n'a pas été joué, considérez la vue comme prouvée au protocole, pas comme prouvée dans Claude.