From 9b4bb6331e23fde2ce974a086c41a5d5371d4cf0 Mon Sep 17 00:00:00 2001 From: Jan-Niclas Loosen Date: Fri, 25 Sep 2026 14:59:41 +0200 Subject: [PATCH] Add WP-LIT-MCP design specification Co-Authored-By: Claude Opus 5.5 (1M context) --- .../specs/2026-09-25-wp-lit-mcp-design.md | 493 ++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-25-wp-lit-mcp-design.md diff --git a/docs/superpowers/specs/2026-09-25-wp-lit-mcp-design.md b/docs/superpowers/specs/2026-09-25-wp-lit-mcp-design.md new file mode 100644 index 0000000..dc87ba6 --- /dev/null +++ b/docs/superpowers/specs/2026-09-25-wp-lit-mcp-design.md @@ -0,0 +1,493 @@ +# 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 Claude (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. Von Claude erzeugte oder geänderte Divi-Inhalte sind im Visual Builder vollständig bearbeitbar (manuell verifiziert pro Etappe). +3. Unangetastete Inhalte bleiben byte-identisch erhalten. +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 (``) 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) | Filter auf die REST-Authentifizierung: Application Passwords, die von mcp-oauth erzeugt wurden, werden außerhalb der MCP-Route abgewiesen. Entfällt, sobald upstream PR #64 veröffentlicht ist. | +| 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`. +- **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/-`. Der Adapter bildet daraus Tool-Namen (`lit--`). + +### 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() + 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` für Theme Builder (Divi-Anforderung). + +## 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. +- Reines PHP ohne WordPress-Abhängigkeit (vollständig unit-testbar). +- Attributwerte mit `$variable(...)$` werden beim Serialisieren wie von Divi erwartet escaped (`"` → `"`). + +### 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 `rev` = Hash des aktuellen `post_content`. +- Jedes Schreib-Tool verlangt `rev`. Weicht er ab, wird abgelehnt (`rev_mismatch`), nichts geschrieben; Claude liest neu. Pfad-IDs gelten immer relativ zu einem `rev`. + +### 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)): + +```json +{ "type": "button", "text": "Termin buchen", "url": "/kontakt", + "preset": "CTA primär", "label": "Hero – Button" } +``` + +**Vollform** (alle Module, alle Einstellungen, Divis Attributpfade): + +```json +{ "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:}}` | globale Farbe (`gcid-…`; Aliase primary/secondary/heading/body/link) | +| `{{var:}}` | 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:}}` | Dynamic Content `custom_meta_` (Pods/Meta) | +| `"preset": ""` | `modulePreset: [""]` | + +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-find-similar`). + +Kurzform setzt Admin-Labels automatisch (` – `), sofern nicht angegeben. + +### 5.6 Speicher-Pipeline + +1. Rechte prüfen (`edit_post`), `rev` prüfen. +2. Änderung auf dem BlockTree ausführen, validieren (alles oder nichts). +3. Serialisieren, `wp_slash()`, `wp_update_post()` – Status unverändert, WordPress legt eine Revision an. +4. Post-Meta `_et_pb_use_divi_5=on`, `_et_pb_use_builder=on` setzen. +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` | +| `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) | +| `lit/page-render-summary` | lesen | gerenderte Seite als strukturierter Auszug (Überschriften, Texte, Links, Bilder+Alt) | +| `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 ersetzen, `dry_run` (Standard `true`) | +| `lit/library-list`, `lit/library-get` | lesen | Library-Einträge nach Typ (`layout_type`) und Scope | +| `lit/library-save` | schreiben | Knoten als Library-Eintrag speichern (normal oder global) | +| `lit/library-insert` | schreiben | Library-Eintrag als Kopie oder globale Instanz einfügen | +| `lit/divi-node-copy` | schreiben | Knoten von Seite A nach Seite B kopieren | +| `lit/library-make-global` | schreiben | Knoten in globales Modul umwandeln; optional gleichartige Vorkommen ersetzen | +| `lit/library-find-similar` | lesen | ähnliche Abschnitte seitenübergreifend (Struktur-Fingerabdruck: Modultypen, Aufbau, Presets) | +| `lit/tb-list` | lesen | Vorlagen, Bedingungen, Layouts | +| `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`) | +| `lit/tb-assign` | schreiben | Bedingungen (`_et_use_on`/`_et_exclude_from`, z. B. `singular:post_type:person:all`) setzen | + +## 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): Claude 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 + +```json +{ "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", + "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; Code-Modul erlaubt ja/nein (Standard: ja, nachrangig). +- **Limits:** Upload-Größe, Protokoll-Aufbewahrung, Anzahl Snapshots. +- Umsetzung mit Settings API, ohne JS-Framework. + +## 9. Anleitungen für Claude + +### 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` mitgeben, +- Verweis auf `lit/guide`. + +### 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`, `theme-builder`, `content-types`, `workflows`. + +### 9.3 MCP-Prompts + +`corporate-design-uebernehmen`, `neue-website-aufsetzen`, `seite-pruefen`, `globale-module-vorschlagen`, `custom-post-type-vorlage`. + +## 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; Texte in Divi-Attributen mit `wp_kses_post` (Text-Module) bzw. `sanitize_text_field` (einfache Felder). +- 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` als explizites, servererzeugtes Handle 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 | Divi-Seiten mit Claude 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 | +| **4 – Designsystem** | Farben, Variablen, Presets, Theme-Optionen inkl. SEO, Snapshots, Prompts | Corporate Design in einem Rutsch übernehmen | + +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 | `rev`-Sperre | +| 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: Exakte Kurzform-Felder je Modul (aus Modul-Metadaten abgeleitet, im Guide dokumentiert). +- Etappe 4: Format der Presets/Variablen an echten Daten verifizieren.