Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
42 KiB
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
- Ein claude.ai-Connector verbindet sich per OAuth mit einer Kundenseite; nur freigegebene Rollen können Tools nutzen.
- Vom KI-Assistenten erzeugte oder geänderte Divi-Inhalte sind im Visual Builder vollständig bearbeitbar (manuell verifiziert pro Etappe).
- Unangetastete Inhalte bleiben byte-identisch erhalten. Dokumentierte Ausnahme (Ruling S7): Divi selbst normalisiert Seiten mit eigenen HTML-/Attribut-Feldern beim Speichern (
AttributeSecurity/HtmlSecurityaufwp_insert_post_data, laufen für jeden Benutzer und werden nie entfernt) – aber nur, wenn die Seite noch nicht in Divisserialize_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 (E2Edivi-write-smoke.shAbschnitt 8). - Eine neue Website (Seitenstruktur, Menü, Einstellungen, Designsystem aus einem CD) lässt sich im Dialog aufsetzen.
- 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 überModuleRegistration::get_default_attrs(). - WordPress 7.0 enthält die Abilities API im Kern.
2. Grundprinzipien
- 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.
- 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.
- Generisch vor fest verdrahtet: Post-Typen, Taxonomien und Felder werden pro Installation erkannt. Spezifische Logik nur über generische Erweiterungspunkte.
- Integrationen nach Verfügbarkeit: Jede Integration (Divi, Pods, …) registriert ihre Tools nur, wenn das Theme/Plugin aktiv ist.
- 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).
- Produktiv tauglich: Jeder Aufruf läuft mit den Rechten des verbundenen WP-Benutzers; zusätzlich Rollen-Freigabe und Rechteprüfung pro Tool.
- 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-oauthundwordpress/mcp-adapterper 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.lockfixiert; 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), dazulit/site-status(leeres Eingabeschema, Anker der Verbindungstests) undlit/media-download(eingebettete Ressource, funktioniert nur direkt).lit/divi-duplicate-nodeundlit/divi-replace-textsind 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 (dazulit/library-insert); indirekt neulit/library-list,lit/library-save,lit/divi-node-copy,lit/divi-dynamic-sources. Neue Tool-Gruppe „Divi-Bibliothek“ (lit/library-*);lit/divi-node-copyundlit/divi-dynamic-sourcesgehören zur Gruppe „Divi“. Stand nach Etappe 3b: weiterhin 22 direkte Tools; indirekt neulit/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) sowielit/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)
- Verbinden: mcp-oauth-Autorisierung (jeder eingeloggte Benutzer).
- Nutzen: Capability
lit_mcp_use(nur freigegebene Rollen) – geprüft über Adapter-Filter und in jeder Ability. - Handeln: konkrete Prüfung pro Ability, z. B.
edit_postfür die Ziel-ID,publish_postfürs Veröffentlichen,upload_files,edit_theme_optionsfür Divi-Designsystem und Menüs,manage_optionsfür WP-Einstellungen,edit_others_posts,edit_theme_optionsund Divis Rollen-Recht „Theme Builder“ für den Theme Builder (Divi-Anforderung und Gate von Divis Theme-Builder-Seite; Etappe 3b), dazuedit_postje Vorlage/Layout; Vorlagen ohneedit_postantworten 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_contentin einen Baum (auf Basis vonparse_blocks, mit Sonderbehandlung fürdivi/global-layoutundglobalModule, dieparse_blockslaut 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.htmlmithtmlBefore/htmlAfter/elementType) – Divi parst und serialisiert dann die ganze Seite neu, was nur Bytes ändert, die noch nicht in Divisserialize_blocks()-Form vorlagen; gemeldet alsCHANGED_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_Parserstattparse_blocks()– ohne WordPress testbar, jedes Byte zwischen den Delimitern bleibt erhalten. Knoten mitglobalModule,divi/global-layoutoder 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-outlineliefert 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 aktuellenpost_content(Sperre der Divi-Werkzeuge) undrev= Sperre des ganzen Eintrags (Rev::ofPost, dieselbe wie beilit/content-getundlit/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 einertree_rev. Jede Schreib-Antwort liefert die neuetree_revund die neuen Pfad-IDs der geänderten Knoten. - Buchstaben der Pfad-IDs:
sAbschnitt,rZeile (auchrow-inner),cSpalte (auchcolumn-inner),mModul (auch Kind-Module und Gruppen),gglobales Modul bzw. globales Layout,xfremder Block (z. B. Block-Editor); gezählt wird je Buchstabe innerhalb des Elternknotens,divi/placeholderist 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_pathmit Vorschlägen. - Responsive-Werte über die Schlüssel
desktop/tablet/phone(optionalhover,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-insertundlit/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 beilit/library-insertselbst (Etappe 3b, E11).
Kurzform setzt Admin-Labels automatisch (<Abschnitt> – <Modul>), sofern nicht angegeben.
5.6 Speicher-Pipeline
- Rechte prüfen (
edit_post),tree_revprüfen. - Änderung auf dem BlockTree ausführen, validieren (alles oder nichts).
- Serialisieren,
wp_slash(),wp_update_post()– Status unverändert, vorher Wiederherstellungspunkt (Revision). Für Benutzer ohneunfiltered_htmlwird 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 inpost_contentgelangt (D7): Klartext-Werte werden je Feldtyp bereinigt (Text:sanitize_text_field; Rich-Text:wp_kses_post, abhängig vonunfiltered_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 auslit/divi-node-getzurü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 mitvalidation_failedabgelehnt. Ob Divi das Dynamic-Content-before/afterbei der Ausgabe selbst escaped, wird in Etappe 2b im Divi-Quellcode verifiziert; die Bereinigung gilt unabhängig davon (Verteidigung in der Tiefe, R2). - Post-Meta
_et_pb_use_divi_5=on,_et_pb_use_builder=onsetzen (Seiten und Theme-Builder-Layouts; Bibliothekseinträge nicht). ET_Core_PageResource::remove_static_resources($post_id, 'all', true); bei globalen Library-Elementen und Theme-Builder-Änderungen('all', 'all', true)sowieet_theme_builder_clear_wp_cache('all').- Protokolleintrag,
ToolResultzurü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(danachflush_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
ToolResultund im Protokoll. - Voraussetzung:
edit_theme_options; für Variablen zusätzlich Divis Rollen-Rechtvariables_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: trueund{ 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-outlineundlit/divi-design-systemlesen; Variablen/Presets vor festen Werten; native Module vor Code-Modul; Status nie ändern ohne ausdrücklichen Wunsch; immerrev(bei Divi-Änderungentree_rev) mitgeben, - Verweis auf
lit/guide. - Etappe 3a: Zeile „Divi-Bibliothek: …“ (globale Module im Bibliothekseintrag ändern, Probelauf und
confirm: true, Guidedivi-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, Guidetheme-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: trueerforderlich; 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, sonstvalidation_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
inputSchemafür jedes Tool,outputSchemawo strukturiert (JSON Schema 2020-12); Ergebnisse alsstructuredContent+ 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_revals 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
outputSchemavalidiert. - 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.
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 Guidedivi-shortform. - Etappe 4: Format der Presets/Variablen an echten Daten verifizieren.