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

495 lines
32 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (`<!-- 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`.
- **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` 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:<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) |
| `"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-find-similar`).
Kurzform setzt Admin-Labels automatisch (`<Abschnitt> – <Modul>`), 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. (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 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.