🚀 Entwicklung einer PHP-MCP-App zur Veröffentlichung von Darkwood-Artikeln
der 1. März 2026
Große Sprachmodelle sind bereits gut darin, Texte zu generieren. Was in vielen Projekten noch fehlt, ist eine saubere Methode, diese Textgenerierung in einen echten Workflow zu überführen: einen Entwurf erstellen, ihn überprüfen, korrigieren, veröffentlichen und das Ganze so präsentieren, dass es sich in einem KI-Client intuitiv anfühlt.
Genau hier werden MCP-Apps interessant.
Ziel dieses Projekts war es nicht, „eine weitere Chatbot-Integration“ zu entwickeln. Ziel war es vielmehr, eine echte MCP-Anwendung in PHP zu erstellen, die die Veröffentlichung eines Darkwood-Blogartikels durch einen einfachen redaktionellen Workflow ermöglicht:
- Einen Entwurf erstellen,
- Überprüfen oder korrigieren Sie es,
- Veröffentliche es,
- und, falls erforderlich, vor der Veröffentlichung noch einmal nachhaken.
Das Ergebnis ist ein PHP MCP-Server, der über stdio oder HTTP laufen kann, Tools und UI-Ressourcen bereitstellt und als Claude Desktop-Erweiterung verpackt werden kann.
Warum MCP-Apps wichtig sind
Ein klassischer MCP-Server kann Werkzeuge und Ressourcen bereitstellen. Das ist bereits nützlich: Ein LLM kann ein Werkzeug aufrufen, eine strukturierte Ausgabe erhalten und die Argumentation fortsetzen.
MCP Apps bieten aber noch etwas Praktischeres: Sie ermöglichen es einem Tool, seine eigene eingebettete Benutzeroberfläche mitzubringen.
Das verändert das Interaktionsmodell erheblich.
Anstatt nur Text zurückzugeben, kann ein Tool nun eine eigene Benutzeroberfläche innerhalb des Hosts öffnen. Diese Oberfläche kann den Eingabestatus anzeigen, Ergebnisse präsentieren, den Benutzer durch einen Ablauf führen und weitere Tool-Aufrufe auslösen. Anders ausgedrückt: Das Tool ist nicht mehr nur eine Remote-Funktion, sondern verhält sich zunehmend wie eine fokussierte Anwendungsoberfläche.
Für einen redaktionellen Workflow ist das wesentlich besser geeignet als reiner Text.
Das Erstellen eines Entwurfs ist nicht das Schwierigste. Die Schwierigkeit liegt vielmehr darin, den Übergang zwischen „Hier ist ein generierter Text“ und „Dieser Inhalt ist bereit zur Veröffentlichung“ zu steuern. Genau hier setzt die Benutzeroberfläche einer MCP-App an: Sie strukturiert den Prozess.
Der Darkwood-Anwendungsfall
Der konkrete Anwendungsfall lässt sich hier einfach erklären.
Diese MCP-App dient der Unterstützung der Veröffentlichung eines Blogbeitrags auf Darkwood.
Der Workflow beginnt mit einem ersten Schritt, GenerateDraft, der einen ersten Entwurf aus einem Thema oder Kontext erstellt.
Im zweiten Schritt, PublishDraft, wird der Veröffentlichungsprozess gesteuert. Sollte der Entwurf noch nicht den Anforderungen genügen, muss der Vorgang nicht an dieser Stelle enden. Er kann einen Korrektur- oder Überarbeitungsschritt durchlaufen, bevor ein erneuter Veröffentlichungsversuch unternommen wird.
Diese Schleife ist wichtig.
Ein Publikationsprozess verläuft in der Praxis selten linear. Ein erster Entwurf kann zu unfertig, zu allgemein, zu lang oder schlichtweg nicht mit den redaktionellen Zielen übereinstimmen. Daher basiert die MCP-App auf einer realistischen Idee: Die Veröffentlichung ist das Ziel, aber Iteration ist Teil des Weges.
Ein MCP-Server, viele Möglichkeiten, ihn zu nutzen
Ein nützlicher Aspekt dieses Projekts ist, dass die gleiche MCP-Logik in verschiedenen Laufzeitmodi wiederverwendet wird.
Der Server kann wie folgt verwendet werden:
- über stdio, typischerweise für lokale Integrationen und Claude Desktop-Pakete,
- über HTTP, für browserbasierte Hosts oder lokale MCP-Endpunkte,
- über Symfony Server, wenn Sie eine eher standardmäßige HTTP-Konfiguration für
public/index.phpwünschen, - über eine Claude Desktop-Erweiterung, verpackt als
.mcpb, - und in all diesen Fällen als MCP App-fähiges Tool, wenn der Host eine eingebettete Benutzeroberfläche unterstützt.
Das ist architektonisch wichtig: Die Geschäftslogik ist nicht an einen bestimmten Client oder ein bestimmtes Transportprotokoll gebunden. Das Transportprotokoll ändert sich, das Orchestrierungsmodell ändert sich geringfügig, aber die MCP-Oberfläche bleibt dieselbe.
Architektur
Am einfachsten lässt sich das Projekt verstehen, indem man es in vier Rollen unterteilt: den Host, den PHP MCP-Server, die MCP App-Benutzeroberfläche und die Orchestrierungsschicht.
Das große Ganze
Im Prinzip funktioniert das System folgendermaßen:

- ein MCP-Host verbindet sich mit dem PHP-Server,
- Der Host ermittelt die verfügbaren Werkzeuge und Ressourcen,
- Der Host ruft ein Tool wie
GenerateDraftoderPublishDraftauf, - Wenn das Tool eine UI-Ressource deklariert, lädt der Host auch die entsprechende MCP-App-Ansicht.
- Die Benutzeroberfläche und der Host kommunizieren über JSON-RPC mittels
postMessagemiteinander, - und der Host leitet Tool-Aufrufe zurück an den PHP-Server.
Das ist der Kernpunkt: Die Benutzeroberfläche kommuniziert nicht direkt mit dem Server. Der Host fungiert als Vermittler und Brücke.
Diese Trennung ist nützlich, da sie die Portabilität der Benutzeroberfläche auf kompatiblen Hosts gewährleistet und gleichzeitig einen sauberen MCP-Vertrag auf Serverseite sicherstellt.
Transporte
Das Projekt unterstützt zwei Haupttransportwege.
Studio
Im stdio-Modus startet der Host den PHP-Server als Unterprozess und kommuniziert über STDIN und STDOUT.
Dies ist die ideale Anwendung für Claude Desktop-Erweiterungen. Der Host startet den Server, sendet JSON-RPC-Nachrichten über die Standardeingabe und liest Antworten von der Standardausgabe.
Dieser Modus ist einfach, lokal und effizient, wenn der Kunde für das Prozessmanagement verantwortlich ist.
HTTP
Im HTTP-Modus stellt der Server einen MCP-Endpunkt wie beispielsweise POST /mcp bereit.
Dieser Modus ist nützlich für browserorientierte Hosts, lokale Tests oder jede Konfiguration, bei der eine HTTP-Schnittstelle praktischer ist als ein untergeordneter Prozess.
In diesem Projekt kann HTTP auf zwei Arten bereitgestellt werden:
- durch einen dedizierten, langlebigen Prozess wie beispielsweise den Durchflussbearbeiter,
- oder über einen traditionelleren Web-Einstiegspunkt wie beispielsweise
public/index.php.
Messaging
Sobald die Verbindung hergestellt ist, kommunizieren Host und Server über JSON-RPC 2.0.
Das bedeutet, dass das Interaktionsmodell sauber und explizit bleibt:
- Der Host sendet Anfragen,
- Der Server sendet Antworten zurück,
- Benachrichtigungen können ausgetauscht werden, wenn keine Antwort erwartet wird.
Dies gilt unabhängig davon, ob es sich um stdio oder HTTP handelt. Die Transportmethode ändert sich, aber der Protokollvertrag bleibt derselbe.
Darüber hinaus kommuniziert die Benutzeroberfläche bei der Verwendung von MCP-Apps über einen weiteren JSON-RPC-Kanal mit dem Host, diesmal über postMessage.
Es gibt also im Grunde zwei Kommunikationsebenen:
- Host ↔ Server über MCP,
- UI ↔ Host über die MCP Apps-Brücke.
Diese Aufteilung ermöglicht eingebettete Benutzeroberflächen, ohne das Frontend direkt an die PHP-Laufzeitumgebung zu koppeln.
Lebenszyklus
Eine typische Interaktion verläuft in einigen vorhersehbaren Schritten.
Zunächst initialisiert der Host die Verbindung und ermittelt die Serverfunktionen.
Anschließend werden Werkzeuge und Ressourcen aufgelistet.
Wenn der Benutzer ein Tool auslöst, ruft der Host dieses Tool auf dem Server auf. Ist dieses Tool mit einer UI-Ressource verknüpft, liest der Host auch die entsprechende ui://...-Ressource und rendert sie in einem isolierten iFrame.
An diesem Punkt wird die MCP-App interaktiv. Sie kann die Eingaben des Tools empfangen, das Ergebnis anzeigen und über den Host Folgeaktionen initiieren.
Im Darkwood-Workflow bedeutet dies, dass der Benutzer oder Assistent von der Entwurfserstellung zur Veröffentlichung und gegebenenfalls zurück in eine Korrekturschleife gelangen kann, ohne das MCP-Interaktionsmodell zu verlassen.
Was läuft wo
Der PHP MCP-Server besitzt die Protokollschnittstelle:
initializetools/listtools/callresources/listresources/read
Die MCP App-Benutzeroberfläche bestimmt das interaktive Erlebnis.
Der Host ist für Transport, Rendering und die Verbindung zwischen Benutzeroberfläche und Server verantwortlich.
Die Flow-Schicht ist für die Workflow-Orchestrierung zuständig, wenn eine Orchestrierung erforderlich ist.
Dieser letzte Punkt ist wichtig, weil redaktionelle Abläufe oft mehr als eine Aktion und mehr als einen Zustandsübergang beinhalten.
Stdio, HTTP und Symfony-Server sind nicht dasselbe
Auch wenn die Geschäftslogik gleich bleibt, ist das Laufzeitmodell in den verschiedenen Betriebsmodi nicht identisch.
Mit stdio und einem langlebigen HTTP-Worker können Sie von einem persistenten Prozess ausgehen. Das eröffnet die Möglichkeit für asynchrone Funktionen, Ereignisschleifen und kontinuierliche Orchestrierung in derselben Laufzeitumgebung.
Mit Symfony Server ist das Modell klassischer. Jede Anfrage wird in einem synchronen HTTP-Zyklus verarbeitet. Das ist in der Regel einfacher im Betrieb, bedeutet aber, dass die Orchestrierung anders verstanden werden muss: Die HTTP-Schicht bleibt synchron, während die Workflow-Logik an Flow oder eine externe Koordination delegiert wird.
Diese Unterscheidung sollte explizit gemacht werden, denn „unterstützt HTTP“ bedeutet nicht automatisch „unterstützt überall dasselbe Ausführungsmodell“.
Warum dieses Design gut für Veröffentlichungs-Workflows geeignet ist
Der Veröffentlichungsprozess eines Blogs befindet sich in einer schwierigen Lage.
Es handelt sich nicht um einen einzelnen Funktionsaufruf. Aber auch nicht um eine vollständige Backoffice-Anwendung. Sie benötigt lediglich genügend Struktur, um Zustände und Entscheidungen zu verwalten, und bleibt gleichzeitig so schlank, dass sie durch eine KI-Konversation ausgelöst werden kann.
Genau deshalb passen MCP-Apps hier gut.
Die Werkzeugschnittstelle bietet dem Modell eine interaktive Oberfläche. Die Benutzeroberfläche ermöglicht dem Anwender oder Kunden eine kontrollierte Workflow-Ansicht. Und die Flow-Orchestrierung bietet dem Backend die Möglichkeit, mehrstufige Übergänge zu verwalten.
Diese Kombination ist so wirkungsvoll, weil jede Ebene fokussiert bleibt:
- Das Modell entscheidet, wann das Werkzeug eingesetzt wird.
- Das Tool legt den Arbeitsablauf offen,
- Die Benutzeroberfläche macht den Arbeitsablauf sichtbar,
- Das Backend führt es sauber aus.
Verwendung der MCP-App in Claude
Ein praktisches Ergebnis des Projekts ist, dass derselbe MCP-Server als Claude Desktop-Erweiterung verpackt werden kann.
Das bedeutet, dass das Projekt nicht nur ein lokaler Prototyp oder eine Browserdemo ist. Es kann tatsächlich in Claude installiert und als vollwertiges Werkzeug integriert werden.
In dieser Konfiguration:
- Das Erweiterungsmanifest definiert, wie Claude den Server startet.
- Der Server läuft über stdio,
- Claude fungiert als MCP-Moderator.
- und die MCP-App steht als Tool innerhalb des Clients zur Verfügung.
Dies ist ein gutes Beispiel dafür, warum die Trennung von Transportprotokollen und Geschäftslogik wichtig ist. Derselbe PHP-MCP-Server kann lokale Entwicklungsumgebungen, HTTP-basierte Experimente und die Nutzung von Claude Desktop unterstützen, ohne dass das Kernverhalten geändert werden muss.
Von der Demo zum echten Redaktionswerkzeug
Das Interessante an diesem Projekt ist nicht die Existenz eines weiteren Entwurfsgenerators.
Es ist die Tatsache, dass das Projekt bereits eine wiederverwendbare Form für redaktionelle Werkzeuge definiert:
- ein Werkzeug zur Erstellung eines Entwurfs,
- ein Werkzeug zum Veröffentlichen,
- ein Ort zur Bearbeitung von Überarbeitungen,
- eine UI-Schicht zur Unterstützung der Interaktion,
- und darunter ein transportunabhängiger MCP-Server.
Das ist eine wesentlich beständigere Grundlage als eine einmalige, spontane Auftragskette.
Sobald diese Struktur existiert, lässt sich der Workflow deutlich einfacher optimieren. Sie können die Generierungsqualität verbessern, Publikationsmetadaten anreichern, Validierungen hinzufügen oder ein bestehendes CMS integrieren. Die Verbindung zwischen Host, Benutzeroberfläche und Server bleibt stabil.
Opensource
Das vollständige Projekt ist als Open-Source-Repository auf GitHub verfügbar.
https://github.com/darkwood-com/darkwood-publish-article-mcp-apps
Abschluss
Dieses Projekt zeigt, dass es bei MCP-Apps nicht nur darum geht, einem LLM Werkzeuge zur Verfügung zu stellen. Es geht vielmehr darum, brauchbare Arbeitsabläufe zu ermöglichen.
Im Fall Darkwood ist nicht das Interessante daran, dass PHP MCP-Kommunikation unterstützt. Interessant ist vielmehr, dass ein PHP-MCP-Server nun als Backend einer kleinen redaktionellen Anwendung fungieren kann, die innerhalb eines KI-Clients verfügbar ist und sowohl Werkzeugsemantik als auch eine eingebettete Benutzeroberfläche bietet.
Damit verschiebt sich die Integration von „Das Modell kann eine Funktion aufrufen“ zu „Das Modell kann an einem kontrollierten Veröffentlichungsprozess teilnehmen“.
Und das ist ein wesentlich nützlicherer Ort.
Quellen
MCP Apps Quickstart
README.md
php-mcp-apps-mvp-architecture.md