Files
WP-LIT-MCP/docs/superpowers/specs/2026-09-25-wp-lit-mcp-design.md

42 KiB
Raw Permalink Blame History

WP-LIT-MCP – Design-Spezifikation

  • Datum: 2026-09-25
  • Status: Entwurf zur Freigabe
  • Autor: Jan-Niclas Loosen (Loosen-IT), erarbeitet mit Claude

1. Ziel und Kontext

1.1 Problem

Die Pflege von Kunden-Websites (WordPress + Divi 5 + Pods) kostet viel Handarbeit: Seiten anlegen, in Menüs hängen, Divi-Abschnitte bauen, Corporate Designs in Divi übertragen, Custom-Post-Type-Einträge befüllen. Bestehende WordPress-MCP-Plugins erzeugen nur rohes HTML, das im Divi-Builder nicht weiterbearbeitet werden kann. Der Divi AI Agent (Divi 5) arbeitet nur im Builder, läuft über das kostenpflichtige AI Wallet und bietet (Stand 2026-09) keine MCP-Schnittstelle.

1.2 Ziel

Ein WordPress-Plugin, das auf jeder Kundenseite einen MCP-Server bereitstellt, mit dem ein KI-Assistent (z. B. über den claude.ai-Connector) die Website pflegt – so, dass alle Ergebnisse native Divi-Strukturen sind, die der Mensch im Divi Visual Builder weiter verfeinern kann.

1.3 Erfolgskriterien

  1. Ein claude.ai-Connector verbindet sich per OAuth mit einer Kundenseite; nur freigegebene Rollen können Tools nutzen.
  2. Vom KI-Assistenten erzeugte oder geänderte Divi-Inhalte sind im Visual Builder vollständig bearbeitbar (manuell verifiziert pro Etappe).
  3. Unangetastete Inhalte bleiben byte-identisch erhalten. Dokumentierte Ausnahme (Ruling S7): Divi selbst normalisiert Seiten mit eigenen HTML-/Attribut-Feldern beim Speichern (AttributeSecurity/HtmlSecurity auf wp_insert_post_data, laufen für jeden Benutzer und werden nie entfernt) – aber nur, wenn die Seite noch nicht in Divis serialize_blocks()-Form gespeichert war (z. B. Import, direkter DB-Schreibzugriff); über Builder oder LIT MCP gespeicherte Seiten bleiben unverändert (E2E Abschnitt 8a); die Antwort meldet das als Warnung „Inhalt beim Speichern verändert“ (CHANGED_ON_SAVE), die Seite bleibt gültig (E2E divi-write-smoke.sh Abschnitt 8).
  4. Eine neue Website (Seitenstruktur, Menü, Einstellungen, Designsystem aus einem CD) lässt sich im Dialog aufsetzen.
  5. Jede Änderung ist nachvollziehbar (Protokoll) und umkehrbar (Revision bzw. Snapshot).

1.4 Verifizierte Grundlagen

  • Handgeschriebenes Divi-5-Block-Markup (<!-- wp:divi/section … -->) wird von Divi als native Module gerendert (et_pb_section, et_pb_heading, …) und ist im Visual Builder bearbeitbar (lokal getestet, 2026-09-25).
  • Divi liefert serverseitig alle Modul-Metadaten: ModuleRegistration::get_all_core_modules_metadata() (100 Module mit Attribut-Schemata), Default-Attribute über ModuleRegistration::get_default_attrs().
  • WordPress 7.0 enthält die Abilities API im Kern.

2. Grundprinzipien

  1. Divi-nativ: Es werden nur echte Divi-Blöcke erzeugt. Das Code-Modul ist erlaubt, wird aber nachrangig behandelt (Katalog-Hinweis „nur wenn kein natives Modul passt“, Warnung bei Verwendung). Jedes erzeugte Element erhält ein sprechendes Admin-Label.
  2. Designsystem an der Quelle: Farben, Schriften, Variablen, Presets werden immer live aus Divi/WordPress gelesen; es gibt keine doppelte Pflege. Neue Inhalte nutzen Variablen und Presets statt fester Werte.
  3. Generisch vor fest verdrahtet: Post-Typen, Taxonomien und Felder werden pro Installation erkannt. Spezifische Logik nur über generische Erweiterungspunkte.
  4. Integrationen nach Verfügbarkeit: Jede Integration (Divi, Pods, …) registriert ihre Tools nur, wenn das Theme/Plugin aktiv ist.
  5. Status bleibt erhalten: Schreib-Tools ändern nie den Veröffentlichungsstatus. Veröffentlichen/Zurückziehen/Planen sind eigene, explizite Tools. Veröffentlichte Inhalte werden live bearbeitet (mit Revision).
  6. Produktiv tauglich: Jeder Aufruf läuft mit den Rechten des verbundenen WP-Benutzers; zusätzlich Rollen-Freigabe und Rechteprüfung pro Tool.
  7. Nichts geht verloren: Revision oder Snapshot vor jeder Änderung, optimistische Sperre (rev) gegen das Überschreiben paralleler Handarbeit.

3. Umfang

3.1 v1 – Muss

# Bereich Inhalt
1 Anbindung OAuth 2.1 für claude.ai (CIMD), Rollen-Gate, Verbindungsübersicht mit Widerruf
2 Content generisch Schema-Erkennung (Post-Typen, Taxonomien, WP-Meta, Pods-Felder); Einträge suchen/lesen/anlegen/bearbeiten; veröffentlichen/zurückziehen/planen; duplizieren und Kopie gegen Original tauschen; Papierkorb; Revisionen
3 Menüs anlegen, Einträge deklarativ setzen, Positionen zuweisen
4 Medien suchen, ansehen (inkl. Vorschaubild), Upload per URL und per Datei, Download, Metadaten/Alt-Texte (auch Stapel), Löschen mit Verwendungsprüfung
5 Divi-Seiten Seitenbaum, Modul-Katalog, einfügen/ändern/verschieben/löschen/duplizieren, seitenübergreifendes Ersetzen mit Dry-Run
6 Divi Theme Builder Vorlagen auflisten/anlegen/zuweisen, Layouts bearbeiten, Dynamic Content (Pods-Felder, Meta, Post-Daten)
7 Divi Library / globale Module speichern, einfügen (Kopie/global), zwischen Seiten kopieren, in globales Modul umwandeln, ähnliche Abschnitte finden
8 Divi-Designsystem globale Farben, Variablen, Presets lesen und schreiben; Snapshots
9 Divi-Theme-Optionen Schriften, Größen, Farben, Buttons, Layout-Maße, Logo, Divi-SEO – über Whitelist
10 WP-Einstellungen Allgemein, Lesen (Startseite), Permalinks, Diskussion, Website-Icon – über Whitelist
11 Rückmeldung einheitliches ToolResult; page_render_summary
12 Protokoll Änderungsprotokoll mit Aufbewahrungsdauer, Cron-Bereinigung, Leeren
13 Anleitungen Server-Instructions, Tool lit/guide, MCP-Prompts

3.2 Kann

  • Google Fonts herunterladen und über Divis Font-Upload selbst hosten.
  • Pods-Strukturen (Pods, Felder) anlegen.
  • Signierte, zeitlich begrenzte Vorschau-Links für Entwürfe ohne Login.
  • Freitext-Hinweise pro Seite (z. B. Tonalität, Du/Sie) als Ergänzung der Server-Instructions.

3.3 Später

  • SEO-Plugins (Yoast, Rank Math) als eigene Integrationen.
  • „Fast gleich“-Erkennung von Abschnitten mit Detail-Unterschieden.
  • Tickets und wiederkehrende Termine (The Events Calendar Pro).
  • Umstieg auf MCP-Protokoll 2026-07-28 (sobald der Adapter es unterstützt, siehe §11).

3.4 Nicht im Umfang

  • Benutzerverwaltung (Sicherheitsrisiko; ggf. später mit eigenem Konzept).
  • Mehrsprachigkeit (WPML/Polylang).
  • Divi Premade Layouts.
  • Divi 4 / Shortcode-Inhalte (werden gelesen/erhalten, aber nicht bearbeitet).

4. Architektur

4.1 Bausteine auf der Kundenseite

claude.ai ──OAuth 2.1 (CIMD, PKCE)──▶ wp-media/mcp-oauth   (Autorisierung, Token → WP-Benutzer)
                                           │
                                           ▼
                                   wordpress/mcp-adapter    (MCP-Protokoll, Streamable HTTP)
                                           │
                                           ▼
                                   WP-LIT-MCP               (Abilities, Server-Konfiguration, Admin)
  • WP-LIT-MCP bindet wp-media/mcp-oauth und wordpress/mcp-adapter per Composer ein (Jetpack-Autoloader, vendor/autoload_packages.php). Ausgeliefert wird ein einzelnes Plugin.
  • WP-LIT-MCP enthält keine eigene OAuth-Implementierung. Die Anbindungsschicht ist austauschbar; Rückfalloption ist akirk/mcp-connect (separates Plugin, nutzt allerdings das inzwischen veraltete Dynamic Client Registration).
  • Versionen werden in composer.lock fixiert; jedes Update durchläuft den Konformitätstest (§11.4).

4.2 Anpassungen an wp-media/mcp-oauth

Die Bibliothek (v1.1.x) hat Lücken, die WP-LIT-MCP schließt:

Lücke Lösung
Kein Rollen-Gate (jeder eingeloggte Benutzer kann autorisieren) Eigene Capability lit_mcp_use, vergeben an die in den Einstellungen freigegebenen Rollen. Gesetzt über die Adapter-Filter mcp_adapter_{discover_abilities,get_ability_info,execute_ability}_capability und zusätzlich in jeder Ability geprüft.
Erzeugtes Application Password gilt für alle REST-Routen (Issue #62) Code-Analyse (v1.1.2): Das Klartext-Passwort wird verworfen, die Token-Prüfung läuft nur in der MCP-Route – vermutlich nicht ausnutzbar. Etappe 0 prüft das per Ende-zu-Ende-Test (Bearer-Token gegen /wp/v2/users/me muss 401 liefern). Nur falls der Test fehlschlägt: Filter auf rest_authentication_errors, der Bearer-Requests außerhalb der MCP-Route abweist.
Server fest mit drei Meta-Tools, keine direkten Tools WP-LIT-MCP registriert den Server mcp-oauth-server auf mcp_adapter_init mit Priorität < 10 selbst, mit OAuthHttpTransport und eigener Tool-Liste. Folge bis upstream PR #63: harmloser „duplicate server“-Log-Eintrag.
Adapter auf ^0.5 gepinnt Akzeptiert; Beobachtung der Upstream-Entwicklung.

Ob dieser Aufbau stabil funktioniert, entscheidet Etappe 0 (§12).

4.3 Tool-Exposition (hybrid)

  • Direkte Tools (~20): mit vollem Schema sofort sichtbar; nur direkte Tools können Bilder (ImageContent) zurückgeben. Standard-Set: lit/guide, lit/content-types, lit/content-query, lit/content-get, lit/content-create, lit/content-update, lit/post-publish, lit/media-search, lit/media-preview, lit/media-upload-from-url, lit/divi-outline, lit/divi-node-get, lit/divi-insert, lit/divi-update, lit/divi-move, lit/divi-delete, lit/divi-design-system, lit/divi-catalog, lit/library-insert, lit/page-render-summary.
  • Stand nach Etappe 2 (Entscheidung D2, 2026-09-26): 21 direkte Tools – das Standard-Set oben ohne lit/library-insert (kommt mit Etappe 3), dazu lit/site-status (leeres Eingabeschema, Anker der Verbindungstests) und lit/media-download (eingebettete Ressource, funktioniert nur direkt). lit/divi-duplicate-node und lit/divi-replace-text sind indirekt. Mit Etappe 3 sind es 22; das Budget wird dort erneut geprüft (Kosten entstehen vor allem durch große Eingabeschemas, nicht durch die Zahl). Stand nach Etappe 3a: 22 direkte Tools (dazu lit/library-insert); indirekt neu lit/library-list, lit/library-save, lit/divi-node-copy, lit/divi-dynamic-sources. Neue Tool-Gruppe „Divi-Bibliothek“ (lit/library-*); lit/divi-node-copy und lit/divi-dynamic-sources gehören zur Gruppe „Divi“. Stand nach Etappe 3b: weiterhin 22 direkte Tools; indirekt neu lit/tb-list, lit/tb-create-template, lit/tb-assign, lit/tb-activate (neue Tool-Gruppe „Divi Theme Builder“; „nur lesen“ sperrt auch Schreibzugriffe der Divi-Werkzeuge auf Theme-Builder-Layouts, deaktiviert gelten Vorlagen und Layouts als nicht vorhanden) sowie lit/library-find-similar, lit/library-make-global (Gruppe „Divi-Bibliothek“).
  • Alle übrigen Abilities: über die Meta-Tools des Adapters (discover-abilities, get-ability-info, execute-ability).
  • In den Einstellungen änderbar, welche Abilities direkt, indirekt oder deaktiviert sind.
  • Ability-Namen: lit/<bereich>-<aktion>. Der Adapter bildet daraus Tool-Namen (lit-<bereich>-<aktion>).

4.4 Plugin-Struktur

  • Composer, PSR-4 (LIT\MCP\ → src/), PHP ≥ 8.1, WordPress ≥ 6.9 (getestet mit 7.0).
  • Kein Acorn (Größe, Konfliktrisiko auf fremden Seiten, kein Nutzen für ein Plugin ohne UI-Schwerpunkt).
wp-lit-mcp.php                 Plugin-Header, Bootstrap
src/
  Core/
    Plugin.php                 Start, Hooks, Abhängigkeitsprüfung
    IntegrationRegistry.php    sammelt verfügbare Integrationen
    AbilityRegistrar.php       registriert Abilities + Kategorien, Server-Konfiguration
    Access.php                 Rollen-Gate, Capability lit_mcp_use, App-Password-Scope-Filter
    ToolResult.php             einheitliche Rückmeldung
    ToolError.php              verwertbare Fehler
    ChangeLog/                 Tabelle, Repository, Cron-Bereinigung
    Guides/                    Guide-Loader, Server-Instructions, Prompts
    Admin/                     Einstellungsseite, Protokoll-Ansicht (Settings API, WP_List_Table)
  Integrations/
    Integration.php            Interface: isAvailable(), abilities(), prompts()
                               (Sonderfälle innerhalb einer Integration: abilities() lässt nicht nutzbare Tools einfach weg)
    WordPress/                 Content, Schema, Status/Kopie, Revisionen, Menüs, Einstellungen
    Media/                     Medien-Tools, Verwendungssuche
    Divi/
      BlockTree/               Parser, Serializer, Node, Pfad-Adressierung (reines PHP)
      Schema/                  Modul-Katalog, Attributpfad-Validierung
      Compose/                 Kurzform → Blöcke, Platzhalter-Auflösung
      Pages/                   Seiten-Tools, Speicher-Pipeline
      Library/                 Library, globale Module, find_similar
      ThemeBuilder/            Vorlagen, Zuweisungen, Dynamic Content
      Design/                  Farben, Variablen, Presets, Theme-Optionen, Snapshots
    Pods/                      Feld-Adapter für die Schema-Erkennung, Schreiben via Pods-API
docs/guides/*.md               Anleitungen für lit/guide
tests/Unit, tests/Integration, tests/Fixtures

4.5 Rechte (dreistufig)

  1. Verbinden: mcp-oauth-Autorisierung (jeder eingeloggte Benutzer).
  2. Nutzen: Capability lit_mcp_use (nur freigegebene Rollen) – geprüft über Adapter-Filter und in jeder Ability.
  3. Handeln: konkrete Prüfung pro Ability, z. B. edit_post für die Ziel-ID, publish_post fürs Veröffentlichen, upload_files, edit_theme_options für Divi-Designsystem und Menüs, manage_options für WP-Einstellungen, edit_others_posts, edit_theme_options und Divis Rollen-Recht „Theme Builder“ für den Theme Builder (Divi-Anforderung und Gate von Divis Theme-Builder-Seite; Etappe 3b), dazu edit_post je Vorlage/Layout; Vorlagen ohne edit_post antworten wie fehlende IDs, aktive davon erscheinen nur als Anzahl.

5. Divi-Kern

5.1 Grundidee

Seiten, Theme-Builder-Layouts (et_header_layout, et_body_layout, et_footer_layout) und Library-Einträge (et_pb_layout) speichern Block-Markup in post_content. Alle Divi-Bearbeitungstools arbeiten auf jeder dieser Post-Arten über die post_id.

5.2 BlockTree

  • Parst post_content in einen Baum (auf Basis von parse_blocks, mit Sonderbehandlung für divi/global-layout und globalModule, die parse_blocks laut Divi-Code nicht korrekt verarbeitet).
  • Serialisiert den Baum zurück; unveränderte Knoten werden aus ihrem Original-Markup übernommen.
  • Invariante: Parse → Serialize ohne Änderung ergibt byte-identischen Inhalt. Fremde/unbekannte Blöcke bleiben unberührt. Ausnahme beim Speichern (nicht im BlockTree): Divi selbst normalisiert Seiten mit eigenen HTML-/Attribut-Feldern beim Speichern (module.decoration.attributes, module.advanced.html mit htmlBefore/htmlAfter/elementType) – Divi parst und serialisiert dann die ganze Seite neu, was nur Bytes ändert, die noch nicht in Divis serialize_blocks()-Form vorlagen; gemeldet als CHANGED_ON_SAVE (Ruling S7).
  • Reines PHP ohne WordPress-Abhängigkeit (vollständig unit-testbar).
  • Attributwerte mit $variable(...)$ werden beim Serialisieren wie von Divi erwartet escaped (" → ").
  • Umsetzung (D3): eigener Tokenizer mit dem Delimiter-Muster von WP_Block_Parser statt parse_blocks() – ohne WordPress testbar, jedes Byte zwischen den Delimitern bleibt erhalten. Knoten mit globalModule, divi/global-layout oder nicht dekodierbaren Attributen sind undurchsichtig: sie werden nicht betreten, nur als Ganzes verschoben, dupliziert oder gelöscht (bearbeitet werden globale Module seit Etappe 3a im Bibliothekseintrag, E2). Unbalanciertes Markup wird abgelehnt, nie repariert.

5.3 Adressierung und optimistische Sperre

  • lit/divi-outline liefert den Baum mit Pfad-IDs (s0, s0.r1, s0.r1.c0.m2), Modultyp, Admin-Label, Textauszug und Preset-Namen.
  • Jede Antwort enthält tree_rev = Hash des aktuellen post_content (Sperre der Divi-Werkzeuge) und rev = Sperre des ganzen Eintrags (Rev::ofPost, dieselbe wie bei lit/content-get und lit/content-update; Ruling P16).
  • Jedes Divi-Schreib-Tool verlangt tree_rev. Weicht sie ab, wird abgelehnt (rev_mismatch), nichts geschrieben; der Client liest neu. Pfad-IDs gelten immer relativ zu einer tree_rev. Jede Schreib-Antwort liefert die neue tree_rev und die neuen Pfad-IDs der geänderten Knoten.
  • Buchstaben der Pfad-IDs: s Abschnitt, r Zeile (auch row-inner), c Spalte (auch column-inner), m Modul (auch Kind-Module und Gruppen), g globales Modul bzw. globales Layout, x fremder Block (z. B. Block-Editor); gezählt wird je Buchstabe innerhalb des Elternknotens, divi/placeholder ist transparent.

5.4 Modulbeschreibung

Kurzform (kuratiertes Mapping für ~20 Module: Text, Heading, Button, Image, Blurb, CTA, Icon, Divider, Testimonial, Team Member, Accordion(+Item), Tabs(+Tab), Toggle, Gallery, Slider(+Slide), Contact Form(+Field), Map, Video, Number Counter, Social Media Follow(+Item), Icon List(+Item)):

{ "type": "button", "text": "Termin buchen", "url": "/kontakt",
  "preset": "CTA primär", "label": "Hero – Button" }

Vollform (alle Module, alle Einstellungen, Divis Attributpfade):

{ "type": "heading",
  "attrs": { "title.decoration.font.font": {
      "desktop": { "color": "{{color:primary}}" },
      "phone":   { "size": "28px" } } } }
  • Attributpfade werden gegen den Katalog (get_all_core_modules_metadata) validiert; unbekannte Pfade → invalid_attr_path mit Vorschlägen.
  • Responsive-Werte über die Schlüssel desktop / tablet / phone (optional hover, sticky, wo das Modul es unterstützt).
  • Kurz- und Vollform sind kombinierbar (Kurzform + zusätzliche attrs).

Struktur: Abschnitt → Zeilen ("columns": "1_3,2_3") → Spalten → Module. Spezialabschnitte (fullwidth) über "section_type".

Platzhalter (vom Plugin in Divis $variable(...)$-Syntax übersetzt):

Platzhalter Ergebnis
{{color:primary}}, {{color:<Name>}} globale Farbe (gcid-…; Aliase primary/secondary/heading/body/link)
{{var:<Name>}} globale Variable (gvid-…), Suche über Label
{{font:heading}}, {{font:body}} Theme-Schriften (--et_global_heading_font / --et_global_body_font)
{{post:title}}, {{post:excerpt}}, {{post:date}}, … Dynamic Content (Post-Daten)
{{field:<meta_key>}} Dynamic Content custom_meta_<meta_key> (Pods/Meta)
{{link:<ID>}} interner Link: Dynamic Content post_link_url_<Typ> mit post_id (nur Link-Felder; Ziel muss für den Benutzer lesbar sein, nicht im Papierkorb, kein automatischer Entwurf, kein Anhang; Entwürfe/private Ziele rendert Divi als ?page_id=; Etappe 3a, E13a)
"preset": "<Name>" modulePreset: ["<id>"]

Unbekannte Namen → Fehler mit Liste der vorhandenen.

5.5 Qualitätsregeln und Warnungen

Jede Schreib-Rückmeldung enthält Warnungen zu:

  • festen Farben/Schriften, wenn eine passende Variable existiert,
  • Bildern ohne Alt-Text,
  • leeren Modulen,
  • Sprüngen in der Überschriftenhierarchie,
  • Verwendung des Code-Moduls,
  • ähnlichen, bereits existierenden Abschnitten (Hinweis auf lit-library-insert und lit/library-find-similar) – verglichen wird nur ein neu eingefügter Abschnitt mit den Abschnitten der Divi-Bibliothek (Struktur-Fingerabdruck, höchstens 200 Einträge, je Anfrage einmal gelesen), nur mit Bibliothekszugang (Gruppe nicht deaktiviert, Recht „Divi-Bibliothek“; P13) und nicht bei lit/library-insert selbst (Etappe 3b, E11).

Kurzform setzt Admin-Labels automatisch (<Abschnitt> – <Modul>), sofern nicht angegeben.

5.6 Speicher-Pipeline

  1. Rechte prüfen (edit_post), tree_rev prüfen.
  2. Änderung auf dem BlockTree ausführen, validieren (alles oder nichts).
  3. Serialisieren, wp_slash(), wp_update_post() – Status unverändert, vorher Wiederherstellungspunkt (Revision). Für Benutzer ohne unfiltered_html wird kses für genau diesen Aufruf abgeschaltet: filter_block_content() würde sonst jeden unveränderten Block neu serialisieren (Byte-Identität, globale Module; in DDEV nachgewiesen). Das ist nur vertretbar, weil keine client-gelieferte Zeichenkette ungeprüft in post_content gelangt (D7): Klartext-Werte werden je Feldtyp bereinigt (Text: sanitize_text_field; Rich-Text: wp_kses_post, abhängig von unfiltered_html; URLs: esc_url_raw, geroutet über die Attribut-Metadaten des Katalogs, ersatzweise über den Schlüsselnamen). Werte mit $variable(...)$ – ob aus Platzhaltern erzeugt oder unverändert aus lit/divi-node-get zurückgegeben – werden geparst, streng geprüft (zulässiger Typ, existierende gcid-/gvid-/Dynamic-Content-Quellennamen, whitelisted Settings-Schlüssel, String-Settings bereinigt) und vom Plugin neu serialisiert; alles andere wird mit validation_failed abgelehnt. Ob Divi das Dynamic-Content-before/after bei der Ausgabe selbst escaped, wird in Etappe 2b im Divi-Quellcode verifiziert; die Bereinigung gilt unabhängig davon (Verteidigung in der Tiefe, R2).
  4. Post-Meta _et_pb_use_divi_5=on, _et_pb_use_builder=on setzen (Seiten und Theme-Builder-Layouts; Bibliothekseinträge nicht).
  5. ET_Core_PageResource::remove_static_resources($post_id, 'all', true); bei globalen Library-Elementen und Theme-Builder-Änderungen ('all', 'all', true) sowie et_theme_builder_clear_wp_cache('all').
  6. Protokolleintrag, ToolResult zurückgeben.

5.7 Tools

Ability Art Beschreibung
lit/divi-outline lesen Baum mit IDs, Labels, Textauszügen, rev und tree_rev
lit/divi-node-get lesen vollständige Attribute eines Knotens (Vollform)
lit/divi-catalog lesen Module, Kurzform-Felder, wichtige Attributpfade; Detail pro Modul
lit/divi-design-system lesen Farben, Variablen, Presets, Theme-Schriften/-Größen
lit/divi-dynamic-sources lesen verfügbare Dynamic-Content-Quellen für einen Post-Typ (über DynamicContentOptions::get_options mit einem Beispiel-Post des Typs) – Etappe 3a (E12, E14); nur textartige Felder (Antwort F4): Beziehungs-, Datei-, Tabellen- und unbekannte Felder stehen mit Grund unter omitted, Auswahlfelder liefern den gespeicherten Wert; Beispiel-Post nur einer, den der Benutzer bearbeiten darf
lit/page-render-summary lesen gerenderte Seite als strukturierter Auszug (Überschriften, Texte, Links, Bilder+Alt); Inhaltsbereich, im Prozess über the_content gerendert (ohne Header/Footer/Theme Builder); Teil der WordPress-Integration, funktioniert auch ohne Divi (D5)
lit/divi-insert schreiben Knoten (Kurz-/Vollform, auch ganze Abschnitte) an Position parent/before/after einfügen
lit/divi-update schreiben Werte setzen/entfernen (Kurz- oder Vollform)
lit/divi-move schreiben Knoten verschieben (auch zwischen Zeilen/Abschnitten)
lit/divi-delete schreiben, destruktiv Knoten entfernen
lit/divi-duplicate-node schreiben Knoten duplizieren
lit/divi-replace-text schreiben Text seitenübergreifend (je Inhaltstyp) ersetzen, dry_run (Standard true) liefert Treffer je Seite mit tree_rev; ausgeführt wird nur auf diesen targets mit confirm: true, jede Seite mit eigener Revision (D10)
lit/library-list lesen Einträge nach Typ (layout_type) und Scope, mit cursor; mit id Detail inkl. Knoten-Übersicht und betroffener Seiten (ersetzt lit/library-get, E9); nur Einträge mit edit_post
lit/library-save schreiben Knoten als Library-Eintrag speichern (normal oder global; global braucht Divis „Globale Bibliothekselemente bearbeiten“, P7); Knoten auf der Seite bleibt unverändert; StoredNodeGuard (E6)
lit/library-insert schreiben Library-Eintrag als Kopie oder globale Instanz im Format des Visual Builders (localAttrs-Schnappschuss, globalParent) einfügen; direkt
lit/divi-node-copy schreiben Knoten von Eintrag A nach Eintrag B kopieren (Seiten und Bibliothekseinträge; byte-gleich, source_tree_rev Pflicht, S7/S26-Prüfung E6)
lit/library-make-global schreiben Knoten in globales Modul umwandeln (alles oder nichts); optional gleichartige Vorkommen ersetzen: gleichartig = inhaltsgleich einschließlich aller Texte (Inhalts-Fingerabdruck und normalisierte Bytes), library_id + targets, Probelauf + confirm, P8a, Revision je Seite; Seite N scheitert → vorherige bleiben ersetzt, Fehler nennt geänderte/gescheiterte/unveränderte Seiten (E10). Nur Inhaltstypen page und post – keine Bibliothekseinträge, keine Theme-Builder-Layouts, auch nicht als Quelle; Knoten mit Verweis auf einen Eintrag (jede Schreibweise) werden kein globales Modul
lit/library-find-similar lesen ähnliche Abschnitte seitenübergreifend (Struktur-Fingerabdruck: Modultypen, Aufbau, Presets) und Inhalts-Fingerabdruck (identical); höchstens 200 Einträge je Aufruf, cursor, nur bearbeitbare Einträge, nie Bibliothekseinträge oder Theme-Builder-Layouts (E11)
lit/tb-list lesen Vorlagen, Bedingungen (Divis Beschriftungen, Objekte nur als ID), Layouts (shared_with), template_rev; detached = von einem veralteten Theme-Builder-Fenster entfernte Vorlagen; optional Divis Bedingungskatalog; nicht bearbeitbare Vorlagen fehlen, aktive nur als Anzahl
lit/tb-create-template schreiben Vorlage mit Header/Body/Footer-Layouts anlegen (et_theme_builder_insert_layout, et_theme_builder_store_template, Meta _et_template); immer deaktiviert (Antwort F1); je Bereich neu, global (Standardvorlage), leer oder ausgeblendet; alles oder nichts; abgelehnt, solange der Theme Builder einen Entwurf hat
lit/tb-assign schreiben Bedingungen (_et_use_on/_et_exclude_from, z. B. singular:post_type:person:all) setzen – nur Divis eigene, Objekte lesbar, Autoren nur mit list_users; aktive Vorlage nur nach Probelauf und confirm; reattach für vom Theme Builder entfernte Vorlagen (bleiben deaktiviert)
lit/tb-activate schreiben Vorlage aktivieren/deaktivieren – einzige Stelle, die eine Vorlage sichtbar macht; immer Probelauf, dann confirm (Antwort F1, Etappe 3b); Deaktivieren geht immer, auch bei Theme-Builder-Entwurf (mit Warnung) und im Papierkorb

6. WordPress-Basis

6.1 Schema-Erkennung (lit/content-types)

  • Post-Typen mit show_ui: Name, Labels, supports, hierarchisch, Divi-fähig, Anzahl.
  • Taxonomien pro Typ.
  • Felder pro Typ, zusammengeführt aus:
    • get_registered_meta_keys() (Kern),
    • Pods-Adapter: Feldtyp, Pflicht, Auswahlwerte, Beziehungsziel, Mehrfachwert (über Pods-API),
    • gefundenen Meta-Schlüsseln (Stichprobe; _-Schlüssel ausgeblendet, sofern kein Adapter sie kennt).
  • Status pro Feld: writable, readonly, unknown (Schreiben erlaubt, mit Warnung).

6.2 Content-Tools (jeder Post-Typ)

Ability Beschreibung
lit/content-query Filter: Typ, Status, Suche, Taxonomie, Feldwert, Datum; Cursor-Paginierung
lit/content-get Kerndaten, Terms, Felder, Beitragsbild; bei Divi-Inhalt Verweis auf lit/divi-outline
lit/content-create neuer Eintrag, Standard: Entwurf; Felder gegen Schema validiert; optional Divi-Inhalt in Kurzform
lit/content-update Kerndaten, Terms, Felder ändern (Status unverändert)
lit/post-publish, lit/post-unpublish, lit/post-schedule Statuswechsel, explizit
lit/post-duplicate Entwurfskopie inkl. Meta, Terms, Divi-Flags
lit/post-replace-with-copy Inhalt/Meta/Terms der Kopie ins Original übernehmen (ID, URL, Menüeinträge bleiben); Original erhält vorher Revision; Kopie → Papierkorb
lit/post-trash nur Papierkorb, nie endgültig löschen
lit/revisions-list, lit/revision-restore Revisionen
  • Pods-Felder werden über die Pods-API geschrieben (Beziehungen, Caches), sonstige Felder über die Meta-API.
  • Erweiterungspunkt lit_mcp_after_save (Action): Integrationen können abgeleitete Felder nachberechnen (z. B. falls The Events Calendar dies erfordert – Prüfung in Etappe 0).

6.3 Medien

Ability Beschreibung
lit/media-search Text, MIME-Typ, Datum, missing_alt, unused
lit/media-get Metadaten, Größen, URLs, Verwendungsorte
lit/media-preview verkleinertes Bild als ImageContent (direktes Tool, kein outputSchema)
lit/media-upload-from-url Import via wp_safe_remote_get (SSRF-Schutz), MIME-Whitelist, Größenlimit
lit/media-upload Base64-Upload, Limit einstellbar (Standard 5 MB)
lit/media-download Original oder Größe als eingebettete Ressource (Blob)
lit/media-update Alt, Titel, Bildunterschrift, Beschreibung – auch Stapel
lit/media-delete nur mit confirm: true; bei Verwendung abgelehnt außer force: true

Verwendungssuche: Anhang-ID in Divi-Attributen, Beitragsbildern, Galerie-Feldern und Meta.

Divi-Bildmodule, Hintergründe und Galerien referenzieren Bilder per Anhang-ID (plus URL, wie Divi es speichert).

6.4 Menüs

lit/menu-list, lit/menu-get (Baum), lit/menu-create, lit/menu-set-items (deklarativer Gesamtbaum oder Einzeloperationen hinzufügen/verschieben/entfernen), lit/menu-assign-location.

6.5 WordPress-Einstellungen

lit/wp-settings-get, lit/wp-settings-update über Whitelist:

  • Allgemein: blogname, blogdescription, WPLANG, timezone_string, date_format, time_format
  • Lesen: show_on_front, page_on_front, page_for_posts, posts_per_page
  • Diskussion: default_comment_status, default_ping_status
  • Permalinks: permalink_structure (danach flush_rewrite_rules())
  • Website-Icon: site_icon

Gesperrt: admin_email, users_can_register, default_role, siteurl, home.

7. Divi-Designsystem und Theme-Optionen

Ability Beschreibung
lit/divi-colors-set globale Farben anlegen/ändern inkl. der fünf Hauptfarben (über GlobalData::set_global_colors)
lit/divi-variables-set Variablen (numbers, strings, images, links, fonts) über GlobalData::set_global_variables
lit/divi-presets-set Modul- und Gruppen-Presets anlegen/ändern, per Name (über GlobalPreset::save_data)
lit/divi-theme-options-get, lit/divi-theme-options-update Whitelist mit Typ und Beschreibung pro Feld (s. u.)
lit/divi-design-snapshots, lit/divi-design-restore Snapshots auflisten und wiederherstellen
lit/divi-font-upload-google (Kann) Google-Schrift (TTF) laden, über FontsUtility::font_add ablegen

Theme-Options-Whitelist (Auszug, vollständige Liste in der Implementierung mit Typen):

  • Schriften: heading_font, body_font, heading_font_weight, body_font_weight, primary_nav_font, secondary_nav_font, all_buttons_font
  • Größen: body_font_size, tablet_body_font_size, phone_body_font_size, body_header_size, tablet_header_font_size, phone_header_font_size, body_font_height, body_header_height, body_header_spacing, body_header_style
  • Layout: content_width, gutter_width, section_padding, row_padding
  • Farben: accent_color, secondary_accent_color, header_color, font_color, link_color
  • Buttons: all_buttons_* inkl. *_hover
  • Logo: divi_logo
  • SEO: divi_seo_home_*, divi_seo_single_*, divi_seo_index_*

Regeln:

  • Schreiben ausschließlich über Divis eigene Funktionen; danach ET_Core_PageResource::remove_static_resources('all', 'all', true).
  • Vor jeder Änderung wird der betroffene Bereich (Farben, Variablen, Presets oder Theme-Optionen) als Snapshot gesichert (eigene Option, begrenzte Anzahl, Standard 20). Snapshot-ID im ToolResult und im Protokoll.
  • Voraussetzung: edit_theme_options; für Variablen zusätzlich Divis Rollen-Recht variables_manager.

Ablauf „Corporate Design übernehmen“ (Prompt, §9.3): der KI-Assistent liest das CD im Chat → lit/divi-design-system → schlägt Zuordnung vor → nach Bestätigung Schreiben über die Tools oben.

8. Rückmeldung, Fehler, Protokoll, Einstellungen

8.1 ToolResult

{ "ok": true,
  "summary": "Button in 'Hero' aktualisiert",
  "changed": [{ "id": "s0.r0.c0.m2", "type": "divi/button", "action": "updated", "label": "Hero – Button" }],
  "outline": "…betroffener Abschnitt…",
  "rev": "a1b2c3", "tree_rev": "d4e5f6",
  "warnings": ["Feste Farbe #ff0000 – Variable 'Primär' ist ähnlich"],
  "revision_id": 812, "snapshot_id": null, "log_id": 4711,
  "preview_url": "…", "edit_url": "…&et_fb=1" }

Rückgabe als structuredContent plus kurze Text-Zusammenfassung. Listen immer mit cursor/limit.

8.2 Fehler

  • Fachliche Fehler → Tool-Ergebnis mit isError: true und { code, message, hint, fields? }. Codes: rev_mismatch, invalid_attr_path, validation_failed, forbidden, not_found, in_use, confirm_required, unsupported.
  • Alles oder nichts pro Aufruf; Stapel-Tools melden Ergebnis pro Eintrag.
  • Ausnahmen aus WordPress/Divi werden abgefangen, protokolliert (PHP-Error-Log) und neutral gemeldet (kein Stacktrace an den Client).

8.3 Änderungsprotokoll

  • Tabelle {prefix}lit_mcp_log: id, created_at, user_id, client (Name aus OAuth), ability, object_type, object_id, summary, revision_id, snapshot_id, result.
  • Keine Inhalte, nur Verweise.
  • Aufbewahrung einstellbar (Standard 90 Tage), täglicher WP-Cron-Job, Button „Protokoll leeren“.
  • Admin-Ansicht (WP_List_Table), filterbar, Links zu Revision/Wiederherstellen.

8.4 Einstellungsseite (Einstellungen → LIT MCP)

  • Verbindung: Status Adapter/OAuth, MCP-Server-URL zum Kopieren, Site-Health-Test (Discovery-Dokumente erreichbar, 401 mit WWW-Authenticate).
  • Zugriff: erlaubte Rollen (Standard: Administrator); aktive Verbindungen je Benutzer mit Widerruf (über die von mcp-oauth erzeugten Application Passwords).
  • Tools: direkt / indirekt / deaktiviert je Ability. (Das Divi-Code-Modul ist immer erlaubt, nur nachrangig – keine Einstellung.)
  • Limits: Upload-Größe, Protokoll-Aufbewahrung, Anzahl Snapshots.
  • Umsetzung mit Settings API, ohne JS-Framework.

9. Anleitungen für den KI-Assistenten

9.1 Server-Instructions

Dynamisch pro Seite erzeugt (Server-Beschreibung → instructions), ca. 15 Zeilen:

  • aktive Integrationen und Post-Typen,
  • Kernregeln: vor dem Schreiben lit/divi-outline und lit/divi-design-system lesen; Variablen/Presets vor festen Werten; native Module vor Code-Modul; Status nie ändern ohne ausdrücklichen Wunsch; immer rev (bei Divi-Änderungen tree_rev) mitgeben,
  • Verweis auf lit/guide.
  • Etappe 3a: Zeile „Divi-Bibliothek: …“ (globale Module im Bibliothekseintrag ändern, Probelauf und confirm: true, Guide divi-library), nur wenn die Gruppe „Divi-Bibliothek“ aktiv und beschreibbar ist.
  • Etappe 3b: Zeile „Divi Theme Builder: …“ (neue Vorlagen deaktiviert, Aktivieren nur mit lit/tb-activate, Guide theme-builder), nur bei aktiver, beschreibbarer Gruppe „Divi Theme Builder“.

9.2 lit/guide(topic)

Direktes Tool; Anleitungen als Markdown in docs/guides/, mit dem Plugin versioniert, per Filter lit_mcp_guides erweiterbar. Themen: overview, divi-structure, divi-shortform, divi-attrs, divi-placeholders, divi-design-system, divi-library, theme-builder, content-types, media, workflows. Thema all liefert alle Themen in einem Aufruf (Etappe 3a).

9.3 MCP-Prompts

corporate-design-uebernehmen, neue-website-aufsetzen, seite-pruefen, globale-module-vorschlagen, custom-post-type-vorlage. (Stand Etappe 3b: noch keine MCP-Prompts im Plugin; globale-module-vorschlagen steht als Ablauf im Guide divi-library, custom-post-type-vorlage im Guide theme-builder.)

10. Sicherheit

  • OAuth 2.1 mit PKCE über mcp-oauth; Tokens an den MCP-Server gebunden; kein Token-Passthrough an Dritte.
  • Rollen-Gate + Rechteprüfung pro Ability (§4.5).
  • App-Password-Scope auf die MCP-Route beschränkt (§4.2).
  • Whitelists für WP-Einstellungen und Divi-Theme-Optionen.
  • Uploads: wp_safe_remote_get, MIME-Whitelist, Größenlimits.
  • Destruktive Aktionen: confirm: true erforderlich; kein endgültiges Löschen von Posts.
  • Eingaben werden gegen JSON Schema und fachlich validiert; Bereinigung von Divi-Schreibwerten siehe §5.6/D7 (eine Quelle der Wahrheit): je Feldtyp (sanitize_text_field/wp_kses_post/esc_url_raw, URLs geroutet über Katalog-Metadaten bzw. Schlüsselname), $variable(...)$-Werte geparst/geprüft/neu serialisiert, sonst validation_failed.
  • HTTPS erforderlich (Hinweis im Admin, wenn nicht aktiv).

11. MCP-Konformität

Referenz: https://modelcontextprotocol.io/specification

11.1 Zielversion

  • Sofort: Protokollversion 2025-11-25 (vom Adapter unterstützt).
  • Später: 2026-07-28 (zustandslos, server/discover, CIMD bevorzugt), sobald der Adapter sie unterstützt. Der Umstieg ist ein eigenes Arbeitspaket.

11.2 Verantwortung

Bereich Zuständig Sicherung
JSON-RPC, Transport (Streamable HTTP), Versionsverhandlung, Header, Origin-Prüfung MCP Adapter Versionen fixiert, Konformitätstest pro Update
Autorisierung: OAuth 2.1, PKCE, RFC 9728/8414-Discovery, CIMD, Audience-Bindung mcp-oauth Etappe 0 prüft u. a. WWW-Authenticate bei 401, resource-Parameter (RFC 8707), iss (RFC 9207); Lücken upstream melden oder per Filter ergänzen
Tools, Prompts, Ergebnisse WP-LIT-MCP §11.3

11.3 Anforderungen an WP-LIT-MCP

  • inputSchema für jedes Tool, outputSchema wo strukturiert (JSON Schema 2020-12); Ergebnisse als structuredContent + Text.
  • Fachliche Fehler als isError: true, Protokollfehler als JSON-RPC-Fehler.
  • Annotations korrekt: readOnlyHint (Lese-Tools), destructiveHint (Löschen, Ersetzen, Austausch), idempotentHint.
  • Zustandslos: kein serverseitiger Sitzungszustand; rev/tree_rev als explizite, servererzeugte Handles in Tool-Argumenten.
  • Deterministische Reihenfolge der Tool-Liste.
  • Cursor-Paginierung für Listen.
  • Tool-Namen spezifikationskonform und eindeutig (lit-…).
  • Bestätigungen vorerst über confirm: true; Multi-Round-Trip-Elicitation erst, wenn Adapter und claude.ai sie unterstützen.

11.4 Konformitätstests

  • MCP Inspector gegen den Server (Etappe 0 und bei jedem Update von Adapter/mcp-oauth).
  • Automatischer Test je Ability: Ergebnis gegen outputSchema validiert.
  • Ende-zu-Ende-Test mit echtem claude.ai-Connector.

12. Etappen

Etappe Inhalt Ergebnis
0 – Anbindung testen Plugin-Gerüst, Composer, mcp-oauth + Adapter, Rollen-Gate, App-Password-Scope-Filter, eigener Server mit direkten Tools, lit/guide (overview), ein Test-Tool; claude.ai-Connector über ddev share/Staging; MCP Inspector; Test: The Events Calendar-Eintrag generisch anlegen Entscheidung: mcp-oauth bleibt oder Wechsel zu mcp-connect; Events-Erweiterungspunkt nötig ja/nein
1 – WordPress-Basis Schema-Erkennung inkl. Pods, Content-Tools, Status/Kopie/Austausch, Revisionen, Medien, Menüs, WP-Einstellungen, ToolResult, Protokoll, Einstellungsseite Seiten/Beiträge/Pods-Einträge pflegen, Medien verwalten, Websites mit Struktur und Menü aufsetzen
2 – Divi-Seiten BlockTree, Katalog, Kurz-/Vollform, Platzhalter, Outline/Insert/Update/Move/Delete/Duplicate/Replace, Warnungen, page-render-summary, Divi-Guides (umgesetzt in 2a: lesen, 2b: schreiben) Divi-Seiten mit dem KI-Assistenten bauen und pflegen
3 – Library & Theme Builder Library-Tools, Node-Copy, Make-Global, Find-Similar, Theme-Builder-Tools, Dynamic Content CPT-Vorlagen bauen, globale Module einführen (3a Bibliothek, 3b Theme Builder und Konsolidierung)
4 – Designsystem Farben, Variablen, Presets, Theme-Optionen inkl. SEO, Snapshots, Prompts Corporate Design in einem Rutsch übernehmen
U – Auslieferung & Updates (nach Etappe 1) OFFEN – bewusst noch nicht spezifiziert. Bekannt: Build mit composer install --no-dev (~3,3 MB vendor), Updates nur anzeigen (manueller Klick), plugin-update-checker; Hosting (Gitea / GitHub / eigene Subdomain mit update.json) und Signaturprüfung werden später entschieden –

Kann-Kriterien nach Etappe 4 oder bei freier Kapazität.

  • Divi-Bibliothek: Einträge (Module, Abschnitte, Layouts) per Tool löschen und umbenennen. Heute gibt es nur list/save/insert/make-global/find-similar. Löschen ist destruktiv und trifft globale Module samt Verwendungen, braucht also Probelauf und confirm: true.

13. Tests

  • Unit (PHPUnit, Brain Monkey, Mockery): BlockTree (Roundtrip-Invariante), Kurzform → Markup, Attributpfad-Validierung, Platzhalter, Schema-Merge, Whitelists, ToolResult.
  • Fixtures: echte, im Divi Builder gebaute Seiten (inkl. globaler Module, Presets, Variablen, Dynamic Content) als Roundtrip- und Änderungs-Testdaten.
  • Integration (DDEV, WP-CLI/REST): jede Ability gegen die lokale Installation; gerenderte Ausgabe enthält et_pb_*-Klassen.
  • Konformität: §11.4.
  • Manuelle Abnahme pro Etappe: Bearbeitbarkeit im Visual Builder, claude.ai-Ablauf.
  • Qualitätswerkzeuge: phpcs (WPCS), PHPCompatibilityWP.

14. Risiken

Risiko Gegenmaßnahme
mcp-oauth jung, Lücken (Rollen, Scope, direkte Tools) eigene Absicherungen (§4.2), Etappe 0 als Entscheidungspunkt, Rückfall mcp-connect
Adapter 0.7 bricht API, rät vom Bundling ab Versionen fixieren, Konformitätstest, Umstieg geplant
Divi ändert Speicherformat Divi-eigene Metadaten/Funktionen nutzen, Fixtures, Tests je Divi-Update, builderVersion setzen
.well-known/POST auf /wp-json/ durch Hoster/WAF blockiert Site-Health-Test, Fehlersuche-Doku
Design-Qualität neuer Abschnitte ohne Vorlagen Library-first-Arbeitsweise, Designsystem-Platzhalter, Guides, Warnungen
Parallele Bearbeitung im Builder tree_rev-Sperre
Veraltetes Theme-Builder-Fenster speichert und entfernt neue Vorlagen Ablehnung bei Theme-Builder-Entwurf, detached in lit/tb-list, reattach (deaktiviert); Warnung in jeder Anlege-Antwort (Etappe 3b)
Ungewöhnliche Schreibweisen globaler Verweise (P25), z. B. ein maskierter divi/global-layout-Block in einem Modulwert, den Divi in Shortcode-Modulen und WooCommerce-Textmodulen erneut auswertet bekanntes Restrisiko, dokumentiert im Guide divi-library; braucht Bearbeitungsrechte auf der verweisenden Seite; UsageMatcher erkennt die übrigen Schreibweisen fail-closed
Datenformate Designsystem nur aus Code abgeleitet (lokal keine Daten) vor Etappe 4 echte Daten im Builder anlegen und als Fixtures sichern

15. Offene Punkte (in Etappen zu klären)

  • Etappe 0: Funktioniert der Workaround für direkte Tools mit mcp-oauth stabil? Erfüllt mcp-oauth iss/resource-Anforderungen?
  • Etappe 0: Erscheinen generisch angelegte The Events Calendar-Einträge korrekt?
  • Etappe 2: erledigt – Kurzform-Felder aus Divis Conversion-Outlines abgeleitet (ShortformMap), gegen den Live-Katalog geprüft (tests/Integration/divi-shortform-check.php), dokumentiert im Guide divi-shortform.
  • Etappe 4: Format der Presets/Variablen an echten Daten verifizieren.