MCP-Server ki-web

Dies ist ein Model Context Protocol-Server, der den drei lokal installierten AI-CLIs (Claude Code, Codex, qwen-code) Werkzeuge zum Verwalten von Seiten auf ki.karlkratz.com bereitstellt. Wenn der KI z. B. mitgeteilt wird „lege eine Seite an", ruft sie das Tool create_page auf, der Server schreibt in die Datenbank, die Seite ist sofort live.

Datenfluss

  1. KI-CLI erkennt aus dem Prompt, dass ein Tool gebraucht wird.
  2. Sie startet den MCP-Server ki-web als stdio-Subprozess und sendet JSON-RPC.
  3. Die Python-Schicht ruft die PHP-JSON-API unter /api/pages auf.
  4. PHP validiert (Slug-Regex, Längen-Limits), sanitisiert das HTML und schreibt nach Postgres (Datenbank ki_web).
  5. Die Antwort läuft denselben Pfad zurück bis zur KI.

Tools

ToolWirkung
list_pagesAlle Seiten, mit Suche, Sortierung, Pagination
get_pageEine Seite per Slug
create_pageNeue Seite anlegen
update_pageFelder einer bestehenden Seite überschreiben
delete_pageSeite per Slug löschen

Architektur, DDD / Hexagonal

Beide Codebases, die PHP-App und der Python-MCP, folgen demselben Muster, jede Datei unter 100 Zeilen.

PHP unter /var/www/ki.karlkratz.com/src/

Python unter /var/www/mcp/

DRY: wo passiert Validierung?

Ausschließlich in der PHP-Schicht. Der Python-MCP ist ein dünner HTTP-Adapter. Slug-Regex, Längen-Limits und die HTML-Tag-Whitelist (h1, h2, h3, p, ol, ul, li, a, strong, table, pre, code) leben ausschließlich im PHP-Code. Das Python-Modul kennt diese Regeln nicht und muss sie auch nicht kennen, fügt man später eine zweite Schnittstelle hinzu (CLI-Tool, Webhook), bleibt die Regel weiterhin an genau einer Stelle.

HTML-Sanitization im Detail

Der DomHtmlSanitizer in PHP parst den eingehenden Body mit DOMDocument, läuft den Baum rückwärts ab und entfernt jeden Tag, der nicht auf der Whitelist steht. Das a-Tag darf nur die Attribute href und title behalten; href muss http(s), mailto oder ein relativer Pfad sein. Damit kann auch eine halluzinierende KI keinen Schaden anrichten, ein eingeschleustes Script-Tag wird vor dem INSERT entfernt.

Selbst ausprobieren

  1. In Claude Code, Codex oder qwen-code formulieren: „lege eine Seite mit Slug foo, Titel ‚Foo‘, kurzer Meta-Description und H1+Absatz an".
  2. Die CLI ruft create_page auf.
  3. Die Seite ist sofort unter ki.karlkratz.com/foo erreichbar.
  4. Oder direkt suchen in /admin.

Wichtigste Pfade

PfadInhalt
/var/www/mcp/Python-MCP-Quellen
/var/www/ki.karlkratz.com/src/PHP-Codebase
/var/www/ki.karlkratz.com/public/index.phpFront-Controller
/var/www/_credentials/ki_web/credentials.jsonDB-Zugang für PHP-App
/usr/local/bin/ki-webWrapper, startet den MCP über venv-Python