MCP UI ou MCP Apps : différences, SDK et exemples

MCP UI est né comme un SDK communautaire pour les interfaces interactives des outils, et MCP Apps est l’extension officielle qui a standardisé cette idée en janvier 2026. Cet article compare les deux : modèle de livraison, isolation, prise en charge par les hôtes, packages SDK et code exécutable pour les serveurs, les Views et les hôtes, avec des conseils pour choisir pour un nouveau projet.

MCP UI ou MCP Apps : différences, SDK et exemples
Cristian Da Conceicao
Fondateur de Picasso IA

Demandez à dix développeurs ce qui distingue MCP UI de MCP Apps et vous obtiendrez dix réponses différentes. La raison est simple : les deux noms désignent un projet communautaire et le standard officiel qui en est issu, et de nombreux articles les présentent comme des rivaux. Si l’un de vos outils MCP doit afficher un graphique, un formulaire ou une carte au lieu d’un mur de texte, vous devez savoir quel package installer, où vit le HTML et quels hôtes l’afficheront réellement. Cette comparaison de MCP UI face à MCP Apps détaille les différences, les éléments du SDK de chaque côté et du code que vous pouvez adapter dès aujourd’hui.

💡 Réponse courte : MCP Apps est l’extension officielle de MCP, mise en ligne le 26 janvier 2026. MCP-UI est le projet SDK antérieur qui a ouvert la voie à cette idée, et ses packages fonctionnent désormais avec le standard MCP Apps. Considérez-les comme un ancêtre et son successeur, et non comme des concurrents.

Ce que sont vraiment les deux

MCP UI en termes simples

MCP-UI est un SDK permettant de créer des composants d’interface interactifs pour les outils du Model Context Protocol. Il est apparu en 2025 et a popularisé l’idée qu’un serveur MCP puisse répondre avec une interface vivante plutôt qu’avec du texte brut. Selon la documentation de MCP-UI, le projet a directement influencé la spécification MCP Apps.

La boîte à outils se divise en deux :

  • @mcp-ui/server expose createUIResource, qui construit une ressource d’interface à partir d’une chaîne HTML ou d’une URL externe.
  • @mcp-ui/client expose AppRenderer pour afficher l’interface d’un outil et AppFrame pour le HTML que vous avez déjà récupéré.

Des helpers côté serveur existent aussi pour Ruby (mcp_ui_server) et Python (mcp-ui-server), un vrai atout lorsque votre serveur MCP n’est pas écrit en TypeScript. Dans sa forme initiale, MCP-UI proposait plusieurs types de contenu, dont le HTML brut, les URL externes et Remote DOM, et l’interface voyageait dans la réponse de l’outil.

MCP Apps en termes simples

MCP Apps est l’extension officielle qui permet à un outil de renvoyer un composant interactif, comme un tableau de bord, un formulaire ou un flux de travail en plusieurs étapes, affiché dans la conversation au sein d’une iframe isolée. L’annonce officielle la présente comme la première extension officielle de MCP et indique qu’elle est prête pour la production.

Elle repose sur deux primitives MCP classiques :

  1. Un outil qui porte les métadonnées d’interface dans le champ _meta.ui.resourceUri.
  2. Une ressource d’interface servie via le schéma ui://, contenant le HTML et le JavaScript regroupés.

Le SDK tient dans un seul package npm, @modelcontextprotocol/ext-apps, avec des sous-chemins pour les hooks React, l’intégration dans l’hôte et l’enregistrement côté serveur.

Mains d’un développeur tapant sur un ordinateur portable fin affichant une interface de graphique à barres colorée, sur une table de café en bois

Comment les deux projets ont fusionné

De l’expérimentation à l’extension

Les mainteneurs ont proposé MCP Apps en novembre 2025, en s’appuyant sur le travail de MCP-UI et sur l’OpenAI Apps SDK. Deux mois plus tard, le 26 janvier 2026, l’extension a été mise en ligne. L’annonce précise que MCP-UI continue d’exister comme projet distinct et que le passage à l’extension officielle est facultatif.

Ce détail compte pour quiconque possède du code plus ancien. Rien n’oblige à tout réécrire demain, et les packages MCP-UI renvoient désormais vers registerAppTool et registerAppResource du standard MCP Apps comme moyen de connecter les outils et les ressources.

Pourquoi un standard comptait

Avant la fusion, les expérimentations d’interface étaient liées à des clients précis. Un panneau conçu pour un hôte donné ne pouvait pas être supposé fonctionner dans un autre sans code spécifique au client. Réunir les idées de MCP-UI et du SDK Apps dans une seule extension signifie qu’un auteur de serveur écrit une interface et que tout hôte compatible peut l’afficher.

Pour les équipes qui livrent des serveurs MCP à de nombreux clients, c’est tout l’enjeu : un seul build, plusieurs hôtes, une seule logique de sécurité.

Deux collègues dessinant deux rectangles reliés au marqueur sur un tableau blanc dans un bureau lumineux

Les différences qui comptent vraiment

Le tableau comparatif

AspectMCP-UIMCP Apps
OrigineProjet SDK communautaire datant de 2025Extension officielle de MCP, proposée en novembre 2025, en ligne depuis le 26 janvier 2026
RôlePrécurseur de l’interface interactive sur MCP, fournit des helpersSpécification standard plus un SDK de référence
Lien avec l’outilLe modèle d’origine renvoie l’interface dans la réponse de l’outil_meta.ui.resourceUri pointe vers une ressource ui://
Type MIMEtext/html;profile=mcp-app lorsqu’il est utilisé avec le standardtext/html;profile=mcp-app
Helpers serveurcreateUIResource dans @mcp-ui/serverregisterAppTool et registerAppResource dans ext-apps/server
View et clientAppRenderer et AppFrame dans @mcp-ui/clientClasse App, plus app-bridge pour les hôtes
LangagesHelpers serveur en TypeScript, Ruby et PythonSDK TypeScript avec hooks React
StatutContinue comme projet distinct, migration facultativePrésenté comme prêt pour la production

Lisez le tableau comme une carte de couches, et non comme un tableau de classement. MCP Apps définit le contrat, et MCP-UI apporte du confort par-dessus ce contrat.

Où vit le HTML

La différence structurelle la plus importante tient à l’emplacement de l’interface. Dans MCP Apps, le serveur stocke l’interface sous une URI ui:// et l’outil y pointe via _meta.ui.resourceUri. L’hôte récupère cette ressource séparément et l’affiche à son propre rythme, de sorte que le HTML n’est pas intégré à chaque réponse d’outil.

Les gains concrets :

  • Des modèles vérifiables. Un hôte peut lire le modèle avant de l’exécuter.
  • Une séparation nette. Les résultats d’outils restent des données, et la ressource reste l’interface.

Vue aérienne d’un bureau en chêne avec des croquis de wireframes au crayon, un ordinateur portable affichant une carte et une tablette avec une mise en page similaire

Sécurité et isolation

Le code interactif dans une conversation présente un risque, c’est pourquoi le modèle de sécurité est une fonctionnalité de premier plan. L’annonce énumère quatre couches :

  • Isolation des iframes (sandboxing) avec des permissions restreintes
  • Modèles pré-déclarés que les hôtes peuvent examiner
  • Messagerie JSON-RPC auditable pour chaque échange entre l’interface et l’hôte
  • Consentement facultatif de l’utilisateur avant tout appel d’outil initié par l’interface

Côté MCP-UI, AppRenderer accepte une propriété sandbox qui pointe vers une page proxy distincte, que l’exemple de la documentation sert depuis son propre port. Le HTML non fiable ne partage jamais une page avec votre application hôte.

💡 Astuce : Le gestionnaire onOpenLink documenté vérifie qu’une URL commence par https:// ou http:// avant d’appeler window.open. Reprenez cette habitude. Une View est une entrée non fiable, filtrez donc ce qu’elle demande à l’hôte de faire.

Gros plan d’un terrarium en verre contenant de petits blocs de bois et un cadenas en laiton, comme un bac à sable

Les hôtes qui affichent les Views

Au lancement, l’annonce citait Claude (web et bureau), Goose et Visual Studio Code Insiders, avec ChatGPT arrivant la même semaine. Le dépôt ext-apps répertorie désormais ChatGPT, Claude, VS Code, Goose, Postman, MCPJam, l’inspecteur mcp-use et l’Alpic Playground. JetBrains, AWS, Google DeepMind et Antigravity ont été cités comme acteurs envisageant une prise en charge.

Vérifiez le statut actuel de l’hôte visé avant d’annoncer une date de lancement. Cette liste évolue vite.

Présentateur dans une salle de réunion aux parois vitrées, à côté d’un écran affichant un tableau de bord épuré tandis que des collègues regardent

Les éléments du SDK que vous allez manipuler

Deux familles de packages assurent le travail, et elles s’emboîtent.

PackageUsage
@modelcontextprotocol/ext-appsCréer des Views interactives avec la classe App
@modelcontextprotocol/ext-apps/reactHooks React pour les Views
@modelcontextprotocol/ext-apps/app-bridgeIntégrer des Views dans un client de chat
@modelcontextprotocol/ext-apps/serverEnregistrer des outils et des ressources sur votre serveur MCP
@mcp-ui/servercreateUIResource et helpers pour Ruby et Python
@mcp-ui/clientAppRenderer et AppFrame pour les hôtes

Développeur vu de dos à un bureau debout avec trois écrans affichant des éditeurs de code aux tons sobres

Côté serveur avec ext-apps

Pour un serveur MCP, la commande d’installation du dépôt se présente ainsi :

npm install -S @modelcontextprotocol/ext-apps \
  @modelcontextprotocol/client@^2.0.0 \
  @modelcontextprotocol/server@^2.0.0 \
  @modelcontextprotocol/node@^2.0.0 \
  @modelcontextprotocol/express@^2.0.0 \
  zod@^4.2.0

Le package serveur vous donne deux helpers, registerAppTool et registerAppResource, ainsi que la constante RESOURCE_MIME_TYPE. L’un ajoute les métadonnées d’interface à un outil, et l’autre sert le bundle HTML.

Côté View avec la classe App

La View est la page qui s’exécute dans l’iframe. Sa classe App communique avec l’hôte via un PostMessageTransport. Vous créez l’application, définissez des gestionnaires tels que ontoolresult, puis appelez connect(). Ensuite, la View peut appeler des outils du serveur avec callServerTool et renvoyer des notes au modèle avec updateModelContext.

Côté hôte avec AppRenderer

Si vous construisez votre propre client de chat, AppRenderer issu de @mcp-ui/client est le composant de haut niveau. Il a besoin d’un client MCP, d’un toolName, d’une URL sandbox, ainsi que des toolInput et toolResult de l’appel. Les callbacks comme onOpenLink et onMessage permettent à l’hôte de décider ce qu’une View peut faire. AppFrame est l’option de plus bas niveau pour le HTML que vous avez récupéré vous-même.

Exemples de code fonctionnels

Un outil qui renvoie l’heure

Ce code serveur suit le démarrage rapide officiel. Un outil nommé get-time est lié à une ressource ui://, et le gestionnaire de la ressource lit un fichier HTML regroupé.

import { z } from "zod";
import fs from "node:fs/promises";
import path from "node:path";
import {
  registerAppResource,
  registerAppTool,
  RESOURCE_MIME_TYPE,
} from "@modelcontextprotocol/ext-apps/server";

const DIST_DIR = path.join(process.cwd(), "dist");
const resourceUri = "ui://get-time/mcp-app.html";

registerAppTool(
  server,
  "get-time",
  {
    title: "Get Time",
    description: "Returns the current server time.",
    inputSchema: z.object({}),
    _meta: { ui: { resourceUri } },
  },
  async () => {
    const time = new Date().toISOString();
    return { content: [{ type: "text", text: time }] };
  },
);

registerAppResource(
  server,
  resourceUri,
  resourceUri,
  { mimeType: RESOURCE_MIME_TYPE },
  async () => {
    const html = await fs.readFile(path.join(DIST_DIR, "mcp-app.html"), "utf-8");
    return {
      contents: [{ uri: resourceUri, mimeType: RESOURCE_MIME_TYPE, text: html }],
    };
  },
);

Remarquez la simplicité : un outil, une ressource et un seul champ de métadonnées qui les relie.

La View qui l’appelle

La View reçoit le premier résultat via ontoolresult et peut demander au serveur des données fraîches lorsque l’utilisateur clique sur un bouton.

import { App } from "@modelcontextprotocol/ext-apps";

const app = new App({ name: "Get Time App", version: "1.0.0" });
const serverTimeEl = document.getElementById("server-time")!;

const readTime = (result: { content?: Array<{ type: string; text?: string }> }) =>
  result.content?.find((c) => c.type === "text")?.text ?? "[ERROR]";

app.ontoolresult = (result) => {
  serverTimeEl.textContent = readTime(result);
};

document.getElementById("get-time-btn")!.addEventListener("click", async () => {
  const result = await app.callServerTool({ name: "get-time", arguments: {} });
  serverTimeEl.textContent = readTime(result);
});

app.connect();

Tablette et ordinateur portable côte à côte sur une table en bois pâle affichant des mises en page de tableau de bord presque identiques

Empaqueter l’interface avec createUIResource

Avec MCP-UI, createUIResource issu de @mcp-ui/server construit l’objet ressource à votre place :

import { createUIResource } from "@mcp-ui/server";

const widgetUI = await createUIResource({
  uri: "ui://my-server/widget",
  content: { type: "rawHtml", htmlString: "<h1>Widget</h1>" },
  encoding: "text",
});

Le format transmis sur le réseau est une ressource MCP classique avec le type MIME standard :

{
  type: "resource",
  resource: {
    uri: "ui://my-server/widget",
    mimeType: "text/html;profile=mcp-app",
    text: "<h1>Widget</h1>",
  },
}

Renvoyer du contexte au modèle

Une View n’est pas une impasse. Elle peut indiquer au modèle ce que l’utilisateur vient de faire, afin que la réponse suivante tienne compte du clic :

await app.updateModelContext({
  content: [{ type: "text", text: "User selected option B" }],
});

Cet unique appel transforme un widget statique en partie de la conversation.

Lequel choisir

La réponse honnête est que la plupart des nouveaux projets devraient partir du standard MCP Apps et considérer MCP-UI comme une boîte à outils qui vient s’y ajouter.

Choisissez le SDK MCP Apps lorsque :

  • Vous démarrez un nouveau projet TypeScript et souhaitez la voie officielle, neutre vis-à-vis des hôtes.
  • Vous voulez une seule interface affichable dans plusieurs hôtes, comme Claude, VS Code, Goose et ChatGPT.
  • Vous voulez les hooks React, ou app-bridge pour intégrer des Views dans votre propre client de chat.
  • Votre outil lance des tâches longues. La génération d’images et de vidéos est asynchrone : un outil démarre une tâche, puis un processus interroge son état jusqu’à son achèvement. Une View avec une barre de progression et une galerie de résultats l’emporte à chaque fois sur un journal de texte.

Conservez les helpers MCP-UI lorsque :

  • Votre serveur est écrit en Ruby ou en Python et vous voulez mcp_ui_server ou mcp-ui-server.
  • Vous livrez déjà une sortie createUIResource et elle s’affiche correctement dans vos hôtes.
  • Vous voulez AppRenderer comme moteur de rendu prêt à l’emploi dans un client que vous contrôlez.

Une courte liste de migration :

  1. Ajoutez _meta.ui.resourceUri à chaque outil qui possède une interface.
  2. Servez le HTML depuis une ressource ui:// avec le type MIME text/html;profile=mcp-app.
  3. Remplacez les charges utiles d’interface intégrées dans les réponses d’outils par des pointeurs vers les ressources.
  4. Déplacez la logique de View dans la classe App et lisez les résultats dans ontoolresult.
  5. Testez dans au moins deux hôtes avant de publier.

Vue aérienne d’un sentier de randonnée se divisant en deux à travers une forêt de bouleaux en automne, avec un randonneur seul à la bifurcation

Comment utiliser Sonnet 5 sur PicassoIA

Les Views sont surtout du HTML, du CSS et une fine couche de TypeScript, exactement le type de travail qu’un modèle de code gère bien. Claude Sonnet 5 sur PicassoIA est conçu pour les tâches de code en plusieurs étapes et l’usage d’outils, lit les captures d’écran et les wireframes, et peut rédiger une première version d’un serveur, d’une View ou d’un wrapper d’hôte à partir d’une simple demande.

  1. Ouvrez la page du modèle. Rendez-vous sur la page Claude Sonnet 5 de PicassoIA.
  2. Remplissez le champ obligatoire. prompt est le seul paramètre requis. Essayez : "Write a TypeScript MCP server tool named show-chart that registers a ui:// resource, plus a View using the App class that renders a bar chart from the tool result."
  3. Réglez le niveau d’effort. La valeur par défaut est low, qui désactive la réflexion pour obtenir la réponse la plus rapide. Montez-le à high ou max lorsque la tâche touche plusieurs fichiers, comme un serveur, une View et une étape de build ensemble.
  4. Ajoutez un prompt système. Fixez un rôle une fois pour toutes, par exemple : « Vous écrivez du code MCP Apps avec @modelcontextprotocol/ext-apps et n’intégrez jamais de secrets dans le HTML. » Il s’applique ensuite à toute la session.
  5. Joignez une image si vous en avez une. Le paramètre facultatif image accepte un wireframe ou une capture d’écran, réduit par max_image_resolution pour gagner du temps et de l’argent.
  6. Générez et vérifiez. La sortie peut atteindre 8 192 tokens par défaut. Copiez le code, puis testez-le dans un hôte.
ParamètreObligatoireValeur par défautUsage
promptOuiAucuneLa demande elle-même
effortNonlowLe temps de réflexion du modèle avant de répondre
max_tokensNon8 192Limiter la longueur de la sortie
system_promptNonVideRôle et style de code
imageNonAucuneUn wireframe ou une capture d’écran comme contexte
max_image_resolutionNon0,5 mégapixelRéduire l’image avant son envoi

💡 Astuce : Collez les extraits de cet article dans votre prompt comme référence. Le modèle reprend alors les vrais noms d’API au lieu de les deviner.

Femme à un bureau d’atelier examinant une planche-contact imprimée avec une loupe, à côté d’un ordinateur portable affichant une grille de galerie d’images

Créez vos visuels dès aujourd’hui

Chaque MCP App finit par avoir besoin d’images : une image d’accroche pour une page d’accueil, des photos de produits pour une galerie de View, une courte vidéo pour une démo. PicassoIA réunit les modèles pour tout cela au même endroit, afin que vous puissiez tester vos idées avant de les brancher sur un serveur.

  • Commencez par des images fixes avec Seedream 5 Pro, en donnant au prompt un objectif, une direction de lumière et une texture pour obtenir un rendu photographique.
  • Transformez la meilleure image en mouvement avec Seedance 2.0, qui associe la vidéo à un son intégré.
  • Faites avancer la partie code avec Claude Sonnet 5, en suivant les étapes ci-dessus.

Choisissez un prompt, générez une image et voyez jusqu’où une seule idée peut aller. Ensuite, ouvrez la collection de modèles PicassoIA et essayez un second modèle avec le même prompt. La comparaison vous apprendra à elle seule ce que chacun fait le mieux.

Partager cet article

Choisissez votre langue