Les grands modèles de langage sont déjà performants pour la génération de texte. Ce qui manque encore, dans de nombreux projets, c'est une méthode simple pour transformer cette génération de texte en un véritable flux de travail : rédiger un brouillon, le relire, le corriger, le publier et l'intégrer de manière intuitive dans une application cliente d'IA.
C’est précisément là que les applications MCP deviennent intéressantes.
Dans ce projet, l'objectif n'était pas de créer « une énième intégration de chatbot ». L'objectif était de développer une véritable application MCP en PHP permettant de publier un article de blog Darkwood via un flux de travail éditorial simplifié :
générer un brouillon,
le réviser ou le corriger,
le publier,
et, si nécessaire, revenir en arrière avant la publication.
Le résultat est un serveur PHP MCP qui peut fonctionner sur stdio ou HTTP, exposer des outils, exposer des ressources d'interface utilisateur et être conditionné comme une extension Claude Desktop.
Pourquoi les applications MCP sont importantes
Un serveur MCP classique peut exposer des outils et des ressources. C'est déjà utile : un LLM peut appeler un outil, obtenir une sortie structurée et poursuivre son raisonnement.
Mais les applications MCP ajoutent quelque chose de plus pratique : elles permettent à un outil d’intégrer sa propre interface utilisateur embarquée.
Cela modifie considérablement le modèle d'interaction.
Au lieu de se contenter de renvoyer du texte, un outil peut désormais ouvrir une interface dédiée au sein du système hôte. Cette interface peut afficher l'état des entrées, présenter les résultats, guider l'utilisateur tout au long d'un flux et déclencher des appels d'outils supplémentaires. Autrement dit, l'outil cesse d'être une simple fonction distante et se comporte davantage comme une interface d'application à part entière.
Dans un flux de travail éditorial, c'est beaucoup plus adapté que le simple texte brut.
Générer un brouillon n'est pas le plus difficile. La difficulté réside dans la gestion de la transition entre le texte généré et le contenu prêt à être publié. C'est là qu'une interface utilisateur d'application MCP s'avère utile : elle structure le processus.
Le cas d'utilisation de Darkwood
Le cas d'utilisation concret est ici simple Ă expliquer.
Cette application MCP est utilisée pour faciliter la publication d'un article de blog sur Darkwood.
Le flux de travail commence par une première étape, GenerateDraft, qui produit une ébauche initiale à partir d'un sujet ou d'un contexte.
Vient ensuite la deuxième étape, PublishDraft, qui gère le processus de publication. Si le brouillon n'est pas encore satisfaisant, le processus peut se poursuivre. Il est possible de revenir en arrière et de procéder à une correction ou une révision avant de tenter une nouvelle publication.
Cette boucle est importante.
En pratique, le processus de publication est rarement linéaire. Une première ébauche peut être trop brouillonne, trop générique, trop longue, ou tout simplement ne pas correspondre à l'intention éditoriale. C'est pourquoi l'application MCP est conçue autour d'une idée réaliste : la publication est l'objectif final, mais l'itération fait partie intégrante du cheminement.
Un serveur MCP, plusieurs façons de l'utiliser
Un aspect utile de ce projet est que la même logique MCP est réutilisée dans plusieurs modes d'exécution.
Le serveur peut être utilisé :
via stdio, généralement pour les intégrations locales et le packaging Claude Desktop,
via HTTP, pour les hôtes basés sur un navigateur ou les points de terminaison MCP locaux,
via le serveur Symfony, lorsque vous souhaitez une configuration HTTP plus standard autour de public/index.php,
via une extension Claude Desktop, conditionnée sous forme de .mcpb,
et, dans tous ces cas, en tant qu'outil compatible avec l'application MCP lorsque l'hôte prend en charge l'interface utilisateur intégrée.
C'est important du point de vue de l'architecture : la logique métier n'est pas liée à un seul client ni à un seul protocole de transport. Le protocole de transport change, le modèle d'orchestration évolue légèrement, mais l'interface MCP reste la même.
Architecture
La manière la plus simple de comprendre le projet est de le diviser en quatre rôles : l’hôte, le serveur PHP MCP, l’interface utilisateur de l’application MCP et la couche d’orchestration.
Vue d'ensemble
De manière générale, le système fonctionne comme suit :
schema-architecture
un hĂ´te MCP se connecte au serveur PHP,
l'hôte découvre les outils et ressources disponibles,
l'hĂ´te appelle un outil tel que GenerateDraft ou PublishDraft,
si l'outil déclare une ressource d'interface utilisateur, l'hôte charge également la vue d'application MCP correspondante.
l'interface utilisateur et l'hĂ´te communiquent entre eux via JSON-RPC sur postMessage,
et l'outil de transfert d'appels de l'hĂ´te renvoie les appels au serveur PHP.
Voici l'idée clé : l'interface utilisateur ne communique pas directement avec le serveur. L'hôte fait office d'intermédiaire.
Cette séparation est utile car elle permet de conserver l'interface utilisateur portable sur les hôtes compatibles tout en préservant un contrat MCP propre côté serveur.
Transports
Le projet soutient deux principaux modes de transport.
Stdio
En mode stdio, l'hôte démarre le serveur PHP en tant que sous-processus et communique via STDIN et STDOUT.
C'est le cas idéal pour les extensions Claude Desktop. L'hôte lance le serveur, envoie des messages JSON-RPC via l'entrée standard et lit les réponses depuis la sortie standard.
Ce mode est simple, local et efficace lorsque le client est responsable de la gestion des processus.
HTTP
En mode HTTP, le serveur expose un point de terminaison MCP tel que POST /mcp.
Ce mode est utile pour les hôtes orientés navigateur, les tests locaux ou toute configuration où une limite HTTP est plus pratique qu'un processus enfant.
Dans ce projet, le protocole HTTP peut être servi de deux manières :
grâce à un processus dédié et durable tel que le flow worker,
ou via un point d'entrée web plus traditionnel tel que public/index.php.
Messagerie
Une fois connectés, l'hôte et le serveur communiquent avec JSON-RPC 2.0.
Cela signifie que le modèle d'interaction reste clair et explicite :
l'hĂ´te envoie des requĂŞtes,
le serveur renvoie des réponses, Des notifications peuvent être échangées lorsqu'aucune réponse n'est attendue.
Cela reste vrai, que le transport soit stdio ou HTTP. Le transport change, mais le contrat du protocole demeure le mĂŞme.
De plus, lorsque des applications MCP sont impliquées, l'interface utilisateur communique avec l'hôte via un autre canal JSON-RPC, cette fois via postMessage.
Il y a donc en réalité deux niveaux de communication :
hôte ↔ serveur via MCP,
Interface utilisateur ↔ hôte via le pont MCP Apps.
C’est cette séparation qui rend possible l’intégration d’une interface utilisateur sans coupler directement le front-end à l’environnement d’exécution PHP.
Cycle de vie
Une interaction typique se déroule en quelques étapes prévisibles.
Tout d'abord, l'hôte initialise la connexion et découvre les capacités du serveur.
Ensuite, il liste les outils et les ressources.
Lorsqu'un utilisateur déclenche un outil, l'hôte appelle cet outil sur le serveur. Si cet outil est associé à une ressource d'interface utilisateur, l'hôte lit également la ressource ui://... correspondante et l'affiche dans une iframe isolée.
À ce stade, l'application MCP devient interactive. Elle peut recevoir les données saisies par l'outil, afficher le résultat et déclencher des actions complémentaires via l'hôte.
Dans le flux de travail Darkwood, cela signifie que l'utilisateur ou l'assistant peut passer de la génération d'ébauches à la publication, et éventuellement revenir dans une boucle de correction, sans quitter le modèle d'interaction MCP.
Ce qui se passe oĂą
Le serveur PHP MCP possède la surface de protocole :
initialiser
tools/list
outils/appel
ressources/liste
ressources/lire
L’interface utilisateur de l’application MCP est responsable de l’expérience interactive.
L'hôte gère le transport, le rendu et la liaison entre l'interface utilisateur et le serveur.
La couche Flow gère l'orchestration des flux de travail lorsque celle-ci est nécessaire.
Ce dernier point est important car les flux éditoriaux impliquent souvent plus d'une action et plus d'une transition d'état.
Stdio, HTTP et le serveur Symfony ne sont pas la mĂŞme chose
Même si la logique métier reste la même, le modèle d'exécution n'est pas identique d'un mode à l'autre.
Avec stdio et un worker HTTP persistant, vous pouvez envisager un processus persistant. Cela ouvre la voie à des fonctionnalités asynchrones, des boucles d'événements et une orchestration continue au sein du même environnement d'exécution.
Avec Symfony Server, le modèle est plus classique. Chaque requête est traitée dans un cycle HTTP synchrone. C'est généralement plus simple à mettre en œuvre, mais cela implique une orchestration différente : la couche HTTP reste synchronisée, tandis que la logique de workflow est déléguée à Flow ou à une coordination externe.
Il est important de faire explicitement cette distinction, car « prend en charge HTTP » ne signifie pas automatiquement « prend en charge le même modèle d'exécution partout ».
Pourquoi cette conception est-elle efficace pour les flux de travail de publication ?
Le flux de publication d'un blog se trouve dans une situation délicate.
Il ne s'agit pas d'un simple appel de fonction, ni d'une application back-office complète. Elle nécessite une structure suffisante pour gérer l'état et les décisions, tout en restant assez légère pour être déclenchée par une conversation avec une IA.
C’est précisément pourquoi les applications MCP sont parfaitement adaptées ici.
L'interface de l'outil confère au modèle une surface d'interaction. L'interface utilisateur offre à l'utilisateur ou au client une vue contrôlée du flux de travail. Enfin, l'orchestration du flux permet au système de gérer les transitions en plusieurs étapes.
Cette combinaison est efficace car chaque couche reste ciblée :
le modèle décide quand utiliser l'outil,
l'outil expose le flux de travail,
l'interface utilisateur rend le flux de travail visible,
le serveur l'exécute sans problème.
Utilisation de l'application MCP dans Claude
L'un des résultats pratiques de ce projet est que le même serveur MCP peut être intégré sous forme d'extension Claude Desktop.
Cela signifie que le projet n'est pas seulement un prototype local ou une démo pour navigateur. Il peut être installé dans Claude et utilisé comme une véritable intégration d'outil.
Dans cette configuration :
le manifeste de l'extension définit comment Claude lance le serveur,
le serveur fonctionne via stdio,
Claude fait office d'hĂ´te du MCP,
et l'application MCP devient disponible en tant qu'outil au sein du client.
Voilà un bon exemple qui illustre l'importance de séparer les protocoles de transport de la logique métier. Un même serveur PHP MCP peut ainsi gérer le développement local, les expérimentations HTTP et l'utilisation de Claude Desktop sans qu'il soit nécessaire de réécrire son fonctionnement de base.
De la démo aux outils éditoriaux réels
Ce qui rend ce projet intéressant, ce n'est pas l'existence d'un énième générateur de brouillons.
C’est le fait que le projet définit déjà une forme réutilisable pour les outils éditoriaux :
un outil pour produire un brouillon,
un outil pour publier,
un endroit pour gérer les révisions,
une couche d'interface utilisateur pour prendre en charge l'interaction,
et un serveur MCP indépendant du transport en dessous.
C'est une base beaucoup plus durable qu'une chaîne de distribution ponctuelle.
Une fois cette structure en place, l'amélioration du flux de travail devient beaucoup plus simple. Vous pouvez optimiser la qualité de la génération, enrichir les métadonnées de publication, ajouter des validations ou intégrer un véritable CMS. Le contrat entre l'hébergeur, l'interface utilisateur et le serveur reste stable.
Open source
Le projet complet est disponible en tant que dépôt open-source sur GitHub.
https://github.com/darkwood-com/darkwood-publish-article-mcp-apps
Conclusion
Ce projet démontre que les applications MCP ne se limitent pas à proposer des outils aux titulaires d'un LLM. Elles visent également à proposer des flux de travail utilisables.
Dans le cas de Darkwood, le plus intéressant n'est pas que PHP puisse communiquer avec MCP. Le plus intéressant est qu'un serveur PHP MCP puisse désormais servir de backend à une petite application éditoriale, accessible depuis un client d'IA, avec à la fois la sémantique de l'outil et une interface utilisateur intégrée.
Cela fait passer l'intégration de « le modèle peut appeler une fonction » à « le modèle peut participer à un flux de travail de publication contrôlé ».
Et c'est un endroit bien plus utile.
Sources Démarrage rapide des applications MCP
README.md
php-mcp-apps-mvp-architecture.md
Top comments (0)