Dies ist die kompakte deutsche Fassung. Die vollständige Dokumentation, die Parameterreferenz und alle Aufnahmen sind auf Englisch: README.md.
---
## Worum es geht
Ein Shopware-6-Shop sind rund zweihundert Entitäten hinter einer Admin-API.
Wer einen Assistenten fragt „Ist im Shop alles in Ordnung?", braucht für eine
ehrliche Antwort sieben Suchen mit Criteria-Filtern, drei State Machines mit
ihren technischen Namen, ein paar Aggregationen und ein OAuth-Token, das der
Assistent niemals wiederholen darf. Hängt man ein Modell direkt an diese API,
bekommt es all das, samt dem Recht, einen Preis per `PATCH` zu ändern, weil ein
Prompt es so wollte.
Das Model Context Protocol hat „gib dem Modell echte Werkzeuge" zu einer
Zeile Konfiguration gemacht. Es sagt nichts darüber, wie ein gutes Werkzeug
für einen *Shop* aussieht: welche der zweihundert Entitäten an einem
Dienstagmorgen zählen, was „hängende Bestellung" heißt, oder dass eine
Bestandskorrektur erst gezeigt und dann gesendet gehört.
**shopware-mcp ist diese Schicht.** Ein kleiner Server, der zum Host MCP
spricht und zum Shop die Admin-API, und Shopware gut genug kennt, um mit
einem Aufruf zu beantworten, was früher einen Nachmittag im Admin gekostet hat.
Er merkt auch, wenn keine Bestellungen mehr kommen, und probiert den Checkout
aus wie ein Kunde, um herauszufinden, warum:
| | |
|---|---|
| **Kuratierte Werkzeuge** | Produkte, Bestellungen samt Verlauf, Belege, Kunden, Kategorien, Aktionen, Bewertungen, Zahlungs- und Versandarten, Plugins, Bestand, Verkaufskanäle, geplante Aufgaben, die Shop-Einstellungen: zwanzig Werkzeuge mit kompaktem JSON, exakten Trefferzahlen, Beschreibungen für ein Modell und Shopwares eigenen Criteria-Filtern. Keine erfundene Abfragesprache. |
| **Die Sicht des Kunden** | `checkout_simulate` legt Produkte und Codes in einen Wegwerf-Warenkorb, über Shopwares eigene Store API, als Gast mit Lieferland oder als bestimmter Kunde mit Gruppe, Preisen und Regeln, und erklärt jeden Warenkorbfehler in Klartext: ein Land, in das der Kanal nicht liefert, ein abgelaufener Code, eine Zahlungsart, die eine Regel ausblendet, ein Hauptprodukt, das eine Variante braucht, ein Kunde, der sich dort nicht anmelden kann. `storefront_search` sucht wie ein Kunde und sagt, warum ein Produkt nicht auftaucht. Bestellt wird nichts; der Warenkorb wird gelöscht. |
| **Ein Puls** | `shop_pulse` stellt heute neben dieselben Stunden desselben Wochentags der letzten Wochen und bewertet die aktuelle Stille: wie viele Bestellungen diese Stunden sonst bringen und wie wahrscheinlich es ist, zufällig keine zu sehen. „Seit sechs Stunden nichts, wo sonst immer drei bis sieben kamen" ist ein kaputter Checkout, kein ruhiger Sonntag. Am Aktionstag vergleicht er mit demselben Wochentag im Vorjahr oder mit dem, was der Tag bringen soll. |
| **Bereit für die Aktion** | `promotions_check` prüft jede Aktion, die bis zu einem Stichtag läuft oder startet, eingeschaltet oder nicht, und nennt, was sie stoppen würde: inaktiv zum Start, kein Rabatt, kein Kanal oder nur Kanäle im Wartungsmodus, keine Codes mehr, das Einlöselimit, 60 % statt gemeinter 6 %, zwei automatische Rabatte, die sich addieren. Der Prompt `campaign_ready` nimmt Checkout, Bestand und den Plan für den Tag dazu. |
| **Eine Wache, die sagt warum** | `shopware-mcp watch` schaut alle paar Minuten auf Bestellungen und Zahlungen und schreibt nur bei einer Änderung nach Slack: Bestellungen bleiben aus, Zahlungen scheitern, der Shop antwortet nicht, und wenn alles wieder normal ist. Der Alarm bringt die wahrscheinliche Ursache mit: `shop_diagnose` schaut auf die üblichen Verdächtigen auf einmal (ein Verkaufskanal im Wartungsmodus, ein Testkauf des Bestsellers, eine Erweiterung, die vor einer Stunde aktualisiert wurde, Fehler im Shopware-Log, ein stehender Worker). Feiertage in den Vergleichswochen zählen nicht als „üblich“. Am Black Friday: `--baseline last-year --expect 3`. |
| **Synthetische Kunden** | `journeys_run` geht feste Kaufwege durch den echten Warenkorb, „Schweizer Gast mit Code SUMMER26“, „Stammkunde zahlt auf Rechnung“, und sagt, welcher gebrochen ist und warum. `watch --journeys journeys.json` prüft sie bei jedem Blick, damit eine nach einem Plugin-Update verschwundene Zahlungsart Alarm schlägt, bevor der erste Kunde aufgibt. |
| **Bereit für KI-Einkäufer** | `agent_readiness` baut den Produkt-Feed, den KI-Shopping-Agenten lesen (den Agentic-Commerce-Feed von OpenAI und Stripe, Feld für Feld wie Google Merchant), und sagt, was Produkte draußen hält: keine Marke, kein Bild, eine GTIN mit falscher Prüfziffer, kein Gewicht, eine Storefront ohne HTTPS oder ohne die Datenschutz-, AGB- und Widerrufsseiten, auf die ein Agenten-Checkout verlinkt. `shopware-mcp feed --out feed.jsonl` schreibt den ganzen Feed. |
| **Vor dem nächsten Update** | `update_check` fragt Shopwares eigenen Update-Dienst, was als Nächstes kommt, welche Sicherheitslücken es schließt und ob jede Erweiterung damit läuft: kompatibel, Erweiterung zuerst aktualisieren, kompatible Version angekündigt oder nicht kompatibel. Für 6.8 und jedes Major danach. |
| **Seiten im Chat** | In Hosts mit MCP Apps (Claude, ChatGPT, VS Code) kommen `shop_brief`, `shop_pulse`, `shop_audit` und `sales_report` mit einer interaktiven Seite neben der Antwort: Kacheln, Diagramme und Befunde, im hellen oder dunklen Theme des Hosts. Das Modell bekommt weiter kompaktes JSON. |
| **Gehostet, nichts zu installieren** | `shopware-mcp hosted` bedient viele Shops unter einer Adresse: Ein Assistent nimmt die URL als Connector, die Person verbindet ihren Shop per OAuth mit den Schlüsseln einer Integration, fertig. Nur lesend, Schlüssel mit AES-256-GCM versiegelt, Tokens nur als Hash gespeichert. Zum Ausprobieren: `https://p-h07rka.project.space/mcp`. |
| **Was ein Rabatt kostet** | `promotion_impact` spielt einen Rabatt oder eine bestehende Aktion auf den echten Bestellungen der letzten Wochen durch: was er auf jeder berechtigten Bestellung und bei der üblichen Code-Nutzung gekostet hätte und wie oft eine Obergrenze greift. `margin_check` findet Produkte unter Einkaufspreis, dünne Margen und was der laufende automatische Rabatt davon übrig lässt. |
| **Ein Audit** | `shop_audit` prüft achtzehn Dinge in einem Aufruf, dazu fertige Regelpakete für die GPSR, das Barrierefreiheitsgesetz und Shopping-Feeds sowie eigene Regeln des Shops aus einer JSON-Datei mit Shopware-Filtern, ganz ohne Code: einen Checkout, der ungewöhnlich still geworden ist, Aktionen der nächsten zwei Wochen, die nicht funktionieren werden, bezahlte Bestellungen, die nie versandt wurden oder keine Rechnung haben, unbezahlte Bestellungen, die alt werden, versandte Bestellungen, die nie abgeschlossen wurden, Produkte ohne Bestand, die beim aktuellen Absatz ausgehen, ohne Bild, ohne Lieferzeit oder in keinem Verkaufskanal sichtbar, abgelaufene Aktionen, Kanäle im Wartungsmodus, Storefronts ohne Impressum, AGB, Datenschutz, Widerruf oder Versandhinweise, Bewertungen, die auf Freigabe warten, geplante Aufgaben, die nicht mehr laufen, Erweiterungen mit Update, und welche EU-Pflichten abgedeckt scheinen, auch ob Shopware selbst für ZUGFeRD-E-Rechnungen eingerichtet ist. Priorisiert, mit Beispielen und einem Hinweis je Befund. Dasselbe Audit läuft als `shopware-mcp audit` aus Cron oder CI, ganz ohne MCP-Host. |
| **Reports und eine Prognose** | `sales_report` lässt Shopware rechnen: brutto, netto, Durchschnittsbestellung, Umsatz je Währung und Kanal, Bestellungen je Status, eine Zeitreihe nach Tag, Woche oder Monat, die Top-Produkte und auf Wunsch die Veränderung zum Vorzeitraum. `customer_report` macht dasselbe für Menschen: neue Konten, Gastanteil, Wiederkäuferanteil, Top-Kunden nach Umsatz. `stock_forecast` macht aus Absatzgeschwindigkeit und Bestand Reichweite in Tagen, Ausverkaufsdatum und Nachbestellmenge. `returns_report` sagt, wie viele Bestellungen zurückkamen und welche Produkte am häufigsten, aus Shopwares eigenen Lieferzuständen. Die Zahlen wurden gegen SQL auf derselben Datenbank geprüft. |
| **Eine Hintertür** | `entity_schema` beschreibt jede der über 200 Entitäten, auch die eigenen Entitäten von Plugins, und `entity_search` fragt sie mit denselben Filtern ab und lässt Shopware über die Treffermenge aggregieren: Bestellungen je Zahlungsart, Umsatz je Monat, alles, was terms, sum oder histogram hergeben. Entitäten mit Zugangsdaten werden verweigert, Geheimnisse im Rest entfernt. |
| **Eine Bremse** | Nur lesend, solange der Server nicht mit `--allow-write` gestartet wird. Und selbst dann ist jeder Schreibzugriff zuerst ein Probelauf, der den genauen Request zeigt, und ein Schreib-Budget kann die echten Schreibzugriffe je Prozess begrenzen. Versenden, als bezahlt markieren, erinnern, erstatten, Bestand korrigieren, Notiz, Beleg erzeugen, Produkt oder Aktion anlegen, Produktbild setzen, Bewertung freigeben, Kunde ändern, fünfzig Rechnungen auf einmal, ein Tag setzen: fünfzehn schmale Schreibzugriffe, sonst nichts. Geheimnisse tauchen nie in Ausgaben, Logs oder Fehlern auf. |
Shops sind nicht gleich, also ist es die Werkzeugliste auch nicht: Beim Start
schaut der Server nach, welche Erweiterungen installiert sind, und registriert
zusätzliche Werkzeuge für die, die er kennt. Ein schlichter Shop bekommt den
Kern. Ein Shop mit mehr Plugins bekommt einen größeren Agenten, ohne
Konfiguration.
---
## So sieht es aus
Jede Aufnahme ist echte Ausgabe des Servers gegen einen Shopware-6.7.13-Testshop
mit generierten Demodaten, abgespielt aus den Transkripten in
[`docs/demo/`](docs/demo). Die Aufnahmen sind auf Englisch; Werkzeugaufrufe und
Ergebnisse sind wörtlich, zum Lesen gekürzt.
**Sechs Stunden ohne Bestellung, und warum.** Sonntagabend. Der Puls vergleicht
die Stille mit denselben Stunden der letzten acht Sonntage, die immer drei bis
sieben Bestellungen brachten, und schätzt die Wahrscheinlichkeit für Zufall auf
etwa eins zu 170. Dann versucht der Agent, wie ein Kunde etwas zu kaufen, und
findet die Storefront im Wartungsmodus. Bestellt und geändert wurde nichts.

**Der Checkout, wie ein Kunde ihn sieht.** Ein Kunde aus der Schweiz sagt, ein
Code funktioniert nicht. Ein Wegwerf-Warenkorb über Shopwares eigene Store API
erklärt beide Probleme auf einmal: Die Schweiz ist kein Land dieses Kanals, und
die Aktion hinter dem Code endete im August. Danach erklärt die Suche, warum
ein Produkt nie auftaucht.

**Jeden Morgen eine Seite.** `shopware-mcp brief --html brief.html` schreibt
Puls, Audit und die letzten sieben Tage als eine eigenständige Seite, die
nichts von irgendwo nachlädt und dem Dunkelmodus des Lesers folgt. Per Cron,
mit `--slack` als kurze Zusammenfassung in einem Kanal.
[Ein echtes Beispiel öffnen](https://bnymndev.github.io/shopware-mcp/brief/).
**Minimale Rechte in einem Befehl.** `shopware-mcp setup` meldet sich einmal
als Admin an, legt eine Rolle mit genau den Rechten an, die die Werkzeuge
brauchen, gemessen an einem echten Shop statt geraten, dazu eine Integration
ohne Administratorrechte. Es zeigt das Secret einmal, prüft beides und zeigt
die Host-Konfiguration. Nach einem Update noch einmal ausgeführt, bringt es die
Rolle auf den neuen Stand, die Schlüssel bleiben.

**Eine Frage, ein Aufruf.** Drei bezahlte Bestellungen warten auf den
Versand, die Storefront ist im Wartungsmodus, eine Sommeraktion hat den August
überlebt. Die Antwort nennt Bestellnummern und Beträge und bietet den sicheren
nächsten Schritt an.

**Zahlen, die der Shop selbst gerechnet hat.** Summen, Kanäle, Status, eine
Monatsreihe und das Top-Produkt für acht Monate, aus einem Aufruf.

**Kein Werkzeug dafür? Dafür gibt es ein Schema.** Für Hersteller gibt es kein
eigenes Werkzeug. Der Agent liest das Schema der Entität, findet `mediaId` und
filtert darauf. Derselbe Weg führt zu jeder anderen Entität, eigene inklusive.

**Schreibzugriffe zeigen erst ihre Karten.** Mit `--allow-write` kommt eine
Bestandskorrektur als der Request zurück, den sie senden *würde*. Erst ein
ausdrückliches `dryRun: false` verändert den Shop, und das Ergebnis wird aus
Shopware neu gelesen.

**Versenden, dann belegen.** Eine Lieferungs-Transition sind zwei Requests, die
vor dem Senden gezeigt werden: die Sendungsnummer auf die Lieferung, dann der
Statuswechsel. Der Verlauf der Bestellung nennt danach Transition, Status und
wer sie ausgelöst hat.

**Ein Produkt und sein Startcode, aus einem Satz.** `product_create` nimmt den
Standardsteuersatz des Shops, leitet den Nettopreis ab und sagt das im
Probelauf. Die Aktion kommt inaktiv an, damit niemand einen Code sieht, bevor
er geprüft wurde.

**Moderation mit Antwort.** Zwei Bewertungen warten auf Freigabe. Der Spam
bleibt verborgen, die Beschwerde wird zusammen mit der öffentlichen Antwort des
Shops freigegeben, und niemand musste in den Admin.

**Menschen, nicht nur Umsatz.** Neue Konten je Gruppe, wie viele Kunden
bestellt haben und wie viele wiederkamen, der Gastanteil und die Top-Kunden mit
ihrem Anteil am Zeitraum, neben dem Zeitraum davor.

**Ein Shop mit mehr Plugins bekommt einen größeren Agenten.** Die Kernwerkzeuge
sind sofort da. Die Erweiterungssuche endet im Hintergrund, vier Werkzeuge
kommen dazu, der Host wird zum Aktualisieren aufgefordert, und eine
Compliance-Frage hat eine Antwort.

**Nachbestellen, bevor es weh tut.** `stock_forecast` liest sechs Monate
Bestellpositionen über eine Aggregation, verbindet sie mit dem aktuellen
Bestand und sagt je Produkt, wie viele Tage bleiben, wann der Bestand auf null
fällt und wie viel zu bestellen ist. Neun davon sind schon überverkauft, zwei
sind heute noch in Ordnung und im Oktober nicht mehr.

**Dasselbe Audit, ganz ohne Host.** `shopware-mcp audit` gibt die Befunde als
Markdown aus und endet mit Exit-Code 1, wenn etwas kritisch ist (oder mit
`--fail-on warning` schon bei einer Warnung). In Cron gehängt, kommt die Mail;
in CI gehängt, bricht der Job ab. `shopware-mcp report` macht dasselbe für die
Zahlen.

**Ein Shop mit Betriebs-Plugin bekommt einen Betriebs-Agenten.** FroshTools ist
die quelloffene Werkzeugkiste, die viele Shopware-Hoster installieren. Ist sie
da, kommen drei Werkzeuge dazu: die Gesundheitsprüfungen der Plattform, die
Message-Queue samt Worker und die Sicherheitshinweise zu Abhängigkeiten. Der
Agent unterscheidet veraltete Suchergebnisse von einem toten Worker.

**Sechsundfünfzig Rechnungen, drei auf einmal.** `order_documents_bulk_create`
findet die bezahlten Bestellungen ohne Rechnung, älteste zuerst, und zeigt den
einen Request, der sie erzeugen würde, bevor er läuft. Jede Bestellung zählt
gegen das Schreib-Budget. Dann erklärt `scheduled_tasks_list`, wie der Rückstau
entstand: 31 von 33 Aufgaben überfällig, keine je gelaufen, der Scheduler steht.
`tag_assign` markiert die Bestellung für das Team und legt das Tag dabei an.

**Vorher wissen, was geht.** `shopware-mcp doctor` prüft, was die Integration lesen darf, liest ihre Rolle für die Schreibrechte, wo das erlaubt ist, und nennt je Werkzeug das fehlende Recht. Ein Administrator bekommt lauter Haken, eine Support-Rolle erfährt genau, was zu vergeben ist.

---
## In 60 Sekunden
**1.** `setup` die Integration anlegen lassen. Es meldet sich einmal als Admin an (das Passwort wird nie gespeichert), legt eine Leserolle mit genau den Rechten an, die die Werkzeuge brauchen, und eine Integration dazu, prüft beides und zeigt oder schreibt die Host-Konfiguration:
```bash
npx shopware-mcp setup --url https://shop.example.com --user admin --for claude-desktop --write
```
Mit `--allow-write` kommen die Schreibwerkzeuge dazu, mit `--settings` auch `shop_settings`; `--dry-run` zeigt vorher die Rechte der Rolle. Nach einem Update denselben Befehl noch einmal ausführen: Er aktualisiert die Rolle und behält die Schlüssel. Lieber selbst klicken? Unter *Einstellungen → System → Integrationen* eine Integration mit Rolle anlegen ([welche Rechte](docs/self-hosting.md#shopware-permissions)) und mit Schritt 2 weitermachen.
**2.** Oder den Assistenten vorhandene Zugangsdaten prüfen und die Host-Konfiguration schreiben lassen:
```bash
npx shopware-mcp init # fragt URL, Schlüssel und Geheimnis ab, testet sie, zeigt die Konfiguration
npx shopware-mcp init --for claude-desktop --write # oder trägt sie direkt in die Datei des Hosts ein
npx shopware-mcp doctor # welche Werkzeuge diese Integration nutzen kann, und was fehlt
npx shopware-mcp brief --html brief.html # Puls, Audit und die letzten 7 Tage als eine HTML-Seite
```
Oder den Server von Hand starten:
```bash
export SHOPWARE_URL=https://shop.example.com
export SHOPWARE_CLIENT_ID=SWIA...
export SHOPWARE_CLIENT_SECRET=...
npx shopware-mcp # stdio (Standard)
npx shopware-mcp --http --port 3333 # Streamable HTTP auf http://127.0.0.1:3333/mcp
npx shopware-mcp --allow-write # zusätzlich die abgesicherten Schreibwerkzeuge
```
**3.** Host verbinden (oder `init --write` machen lassen):
Claude Desktop
`shopware-mcp.mcpb` aus dem [aktuellen Release](https://github.com/bnymnDev/shopware-mcp/releases/latest) laden und doppelklicken, oder in `claude_desktop_config.json` eintragen:
```json
{
"mcpServers": {
"shopware": {
"command": "npx",
"args": ["-y", "shopware-mcp"],
"env": {
"SHOPWARE_URL": "https://shop.example.com",
"SHOPWARE_CLIENT_ID": "SWIA...",
"SHOPWARE_CLIENT_SECRET": "..."
}
}
}
}
```
Claude Code
```bash
claude mcp add shopware \
-e SHOPWARE_URL=https://shop.example.com \
-e SHOPWARE_CLIENT_ID=SWIA... \
-e SHOPWARE_CLIENT_SECRET=... \
-- npx -y shopware-mcp
```
Cursor, VS Code, Zed, Windsurf und andere stdio-Hosts
Alle nehmen dieselben drei Felder. Cursor liest `.cursor/mcp.json`, VS Code `.vscode/mcp.json` (unter `servers` statt `mcpServers`), Zed seinen `context_servers`-Block. Der Eintrag entspricht dem von Claude Desktop oben. Hosts, die die [offizielle MCP-Registry](https://registry.modelcontextprotocol.io) lesen, finden den Server als `io.github.bnymnDev/shopware-mcp`.
Docker und HTTP-Hosts
```bash
docker run --rm -p 3333:3333 \
-e SHOPWARE_URL=https://shop.example.com \
-e SHOPWARE_CLIENT_ID=SWIA... -e SHOPWARE_CLIENT_SECRET=... \
ghcr.io/bnymndev/shopware-mcp
```
Das Image liefert Streamable HTTP unter `http://127.0.0.1:3333/mcp`. Mit `-e SHOPWARE_MCP_HTTP_TOKEN=` verlangt der Endpunkt `Authorization: Bearer `; ohne Token auf localhost lassen oder hinter einen Proxy stellen, der authentifiziert ([Hinweise zum Betrieb](docs/self-hosting.md)).
**4.** Fragen. Die erste nützliche Frage ist meist *„Ist im Shop alles in Ordnung?"*
---
## Fragen, die es beantwortet
| Sie sagen | Der Agent ruft auf |
|---|---|
| „Ist heute ein normaler Tag?" | `shop_pulse` |
| „Warum kann Kunde 10009 nicht bestellen?" | `checkout_simulate { customerNumber: "10009", items }` |
| „Warum funktioniert der Code SUMMER26 nicht?" | `checkout_simulate { promotionCodes: ["SUMMER26"], items }` |
| „Was kostet der Versand in die Schweiz?" | `checkout_simulate { country: "CH", items }` |
| „Warum findet niemand das Steel Shirt?" | `storefront_search { term: "steel shirt", explain: "SW10002" }` |
| „Ist im Shop alles in Ordnung?" | `shop_audit` |
| „Wie lief der August?" | `sales_report { from, to, interval: "week" }` |
| „Welche Produkte haben weniger als 5 auf Lager?" | `products_search` mit einem `range`-Filter, oder der Prompt `low_stock_report` |
| „Fasse Bestellung 10042 für eine Support-Antwort zusammen." | `orders_get`, oder der Prompt `order_summary` |
| „Welche Kunden haben mehr als zehnmal bestellt?" | `customers_search` mit einem `range`-Filter auf `orderCount` |
| „Ist das PayPal-Plugin aktuell?" | `plugins_list` |
| „Welche Hersteller haben kein Logo?" | `entity_schema`, dann `entity_search` auf `product_manufacturer` |
| „Setze den Bestand von SW10084 auf 40." | `stock_set`, erst als Probelauf, dann echt |
| „Bestellung 10042 ist mit DHL raus, Sendungsnummer 00340434." | `order_delivery_transition { transition: "ship", trackingCodes }` |
| „Die Überweisung zu 10038 ist da." | `order_transaction_transition { transition: "paid" }` |
| „Wie war die letzte Woche im Vergleich zur Vorwoche?" | `sales_report { compareWithPrevious: true }`, oder der Prompt `weekly_review` |
| „Schick mir die Rechnung zu 10042." | `order_documents_list`, dann liefert `document_download` die PDF |
| „Notiz zu 10042: Kunde hat angerufen, Versand Montag." | `order_note` |
| „Was ist mit Bestellung 10042 passiert, und wer war das?" | `order_history` |
| „Wer ist Kunde 10042 und was hat er zuletzt bestellt?" | `customers_get` und `orders_search`, oder der Prompt `customer_profile` |
| „Wer waren unsere besten Kunden im Quartal?" | `customer_report { from, to, topCustomers: 20 }` |
| „Welche Bewertungen warten auf Freigabe?" | `reviews_search` mit `status: false`, oder der Prompt `review_moderation` |
| „Gib die Bewertung von Dominique frei und bedank dich." | `review_moderate { approved: true, comment }` |
| „Welche Zahlungsarten bietet die Storefront an?" | `payment_methods_list`, `shipping_methods_list` |
| „Lege einen 10-%-Code AUTUMN10 für Oktober an." | `promotion_create`, inaktiv, bis Sie es anders sagen |
| „Lege das Produkt Bank, SW10200, 119 Euro, 3 auf Lager an." | `product_create`, Nettopreis aus dem Steuersatz abgeleitet |
| „Zwei kamen vom Kunden zurück, buche sie auf SW10084." | `stock_set { delta: 2 }` |
| „Was muss ich in den nächsten zwei Wochen nachbestellen?" | `stock_forecast`, oder der Prompt `reorder_list` |
| „Bestellungen je Zahlungsart im letzten Monat, mit Umsatz?" | `entity_search` auf `order` mit einer `terms`-Aggregation und einer `sum` darin |
| „Welche bezahlten Bestellungen haben noch keine Rechnung? Erzeuge sie." | `shop_audit`, dann `order_documents_bulk_create { type: "invoice" }`, zuerst als Probelauf |
| „Laufen die Cronjobs überhaupt?" | `scheduled_tasks_list { onlyProblems: true }` |
| „Markiere diesen Kunden als VIP." | `tag_assign { entity: "customer", add: ["VIP"] }` |
| „Ist der Gastkauf an, und was ist der Standardsteuersatz?" | `shop_settings` |
| „Gib SW10084 dieses Bild: https://…/bank.jpg" | `product_cover_set`, der Shop lädt es selbst |
| „Thumbnails fehlen, ist die Plattform in Ordnung?" | `frosh_health` und `frosh_queue`, wenn FroshTools installiert ist |
| „Richte es mit den kleinstmöglichen Rechten ein." | kein Werkzeug: `npx shopware-mcp setup` |
| „Welche Werkzeuge scheitern mit dieser Integration?" | kein Werkzeug: `npx shopware-mcp doctor` |
| „Schick mir jeden Morgen eine Seite." | `shopware-mcp brief --html brief.html --slack ` per Cron |
| „Funktionieren unsere Black-Friday-Codes?" | `promotions_check` oder der Prompt `campaign_ready` |
| „Sag Bescheid, wenn am Black Friday keine Bestellungen mehr kommen." | `shopware-mcp watch --baseline last-year --expect 3 --slack ` |
| „Was schicken Kunden am häufigsten zurück?" | `returns_report` |
| „Es kommen keine Bestellungen. Warum?" | `shop_diagnose` |
| „Kann ein Schweizer Gast noch mit PayPal zahlen?" | `journeys_run`, oder `watch --journeys journeys.json` |
| „Was hätten 20 % ab 50 Euro letzten Monat gekostet?" | `promotion_impact { discount: { type: "percentage", value: 20 }, minCartValue: 50 }` |
| „Verkaufen wir etwas unter Einkaufspreis?" | `margin_check` |
| „Wird der Shop besser oder schlechter?" | `shopware-mcp brief --history health.json` speichert einen Wert pro Tag |
| „Wie läuft der Shop?" | `shop_brief`, als Seite in Hosts mit MCP Apps |
| „Können ChatGPT und Gemini unsere Produkte verkaufen?" | `agent_readiness`, dann `shopware-mcp feed --out feed.jsonl` |
| „Können wir schon auf 6.8?" | `update_check` |
| „Sind wir bereit für die GPSR?" | `shop_audit { rulePacks: ["gpsr", "eaa"] }` |
| „Schick mir jeden Montag das Audit." | auch kein Werkzeug: `shopware-mcp audit --fail-on warning` per Cron |
Filter sind Shopware-Criteria-Filter (`equals`, `contains`, `range`, `equalsAny`) auf Shopware-Feldpfaden, Assoziationen wie `manufacturer.name` eingeschlossen. Was sich in der Admin-API filtern lässt, lässt sich auch hier filtern. Der [Spickzettel](docs/quickstart.md#filters-cheat-sheet) zeigt die üblichen Fälle.
---
## Werkzeuge
| Werkzeug | Zugriff | Zweck |
|---|---|---|
| [`shop_info`](docs/tools.md#shop_info) | read | Shop info |
| [`shop_settings`](docs/tools.md#shop_settings) | read | Shop settings |
| [`sales_channels_list`](docs/tools.md#sales_channels_list) | read | List sales channels |
| [`products_search`](docs/tools.md#products_search) | read | Search products |
| [`products_get`](docs/tools.md#products_get) | read | Get product |
| [`orders_search`](docs/tools.md#orders_search) | read | Search orders |
| [`orders_get`](docs/tools.md#orders_get) | read | Get order |
| [`order_history`](docs/tools.md#order_history) | read | Order history |
| [`order_documents_list`](docs/tools.md#order_documents_list) | read | List order documents |
| [`document_download`](docs/tools.md#document_download) | read | Download document PDF |
| [`customers_search`](docs/tools.md#customers_search) | read | Search customers |
| [`customers_get`](docs/tools.md#customers_get) | read | Get customer |
| [`categories_list`](docs/tools.md#categories_list) | read | List categories |
| [`promotions_list`](docs/tools.md#promotions_list) | read | List promotions |
| [`promotions_check`](docs/tools.md#promotions_check) | read | Check promotions before a campaign |
| [`promotion_impact`](docs/tools.md#promotion_impact) | read | What would a discount cost? |
| [`margin_check`](docs/tools.md#margin_check) | read | Margins: below cost and thin |
| [`reviews_search`](docs/tools.md#reviews_search) | read | Search product reviews |
| [`payment_methods_list`](docs/tools.md#payment_methods_list) | read | List payment methods |
| [`shipping_methods_list`](docs/tools.md#shipping_methods_list) | read | List shipping methods |
| [`plugins_list`](docs/tools.md#plugins_list) | read | List plugins and apps |
| [`scheduled_tasks_list`](docs/tools.md#scheduled_tasks_list) | read | Scheduled tasks |
| [`stock_get`](docs/tools.md#stock_get) | read | Get stock |
| [`stock_forecast`](docs/tools.md#stock_forecast) | read | Stock forecast |
| [`storefront_search`](docs/tools.md#storefront_search) | read | Search like a customer |
| [`checkout_simulate`](docs/tools.md#checkout_simulate) | read | Simulate a checkout |
| [`journeys_run`](docs/tools.md#journeys_run) | read | Run customer journeys |
| [`agent_readiness`](docs/tools.md#agent_readiness) | read | Ready for AI shopping agents? |
| [`update_check`](docs/tools.md#update_check) | read | Ready for the next Shopware update? |
| [`shop_diagnose`](docs/tools.md#shop_diagnose) | read | Why are orders not coming in? |
| [`sales_report`](docs/tools.md#sales_report) | read | Sales report |
| [`customer_report`](docs/tools.md#customer_report) | read | Customer report |
| [`returns_report`](docs/tools.md#returns_report) | read | Returns report |
| [`shop_pulse`](docs/tools.md#shop_pulse) | read | Shop pulse |
| [`shop_brief`](docs/tools.md#shop_brief) | read | Shop brief |
| [`shop_audit`](docs/tools.md#shop_audit) | read | Shop health audit |
| [`entity_schema`](docs/tools.md#entity_schema) | read | Entity schema |
| [`entity_search`](docs/tools.md#entity_search) | read | Search any entity |
| [`stock_set`](docs/tools.md#stock_set) | write (guarded) | Set stock (guarded) |
| [`product_update`](docs/tools.md#product_update) | write (guarded) | Update product (guarded) |
| [`product_create`](docs/tools.md#product_create) | write (guarded) | Create product (guarded) |
| [`product_cover_set`](docs/tools.md#product_cover_set) | write (guarded) | Set product cover image (guarded) |
| [`order_state_transition`](docs/tools.md#order_state_transition) | write (guarded) | Transition order state (guarded) |
| [`order_delivery_transition`](docs/tools.md#order_delivery_transition) | write (guarded) | Transition delivery state (guarded) |
| [`order_transaction_transition`](docs/tools.md#order_transaction_transition) | write (guarded) | Transition payment state (guarded) |
| [`order_note`](docs/tools.md#order_note) | write (guarded) | Add internal order note (guarded) |
| [`order_document_create`](docs/tools.md#order_document_create) | write (guarded) | Create order document (guarded) |
| [`order_documents_bulk_create`](docs/tools.md#order_documents_bulk_create) | write (guarded) | Create documents for many orders (guarded) |
| [`promotion_toggle`](docs/tools.md#promotion_toggle) | write (guarded) | Toggle promotion (guarded) |
| [`promotion_create`](docs/tools.md#promotion_create) | write (guarded) | Create promotion (guarded) |
| [`customer_update`](docs/tools.md#customer_update) | write (guarded) | Update customer (guarded) |
| [`review_moderate`](docs/tools.md#review_moderate) | write (guarded) | Moderate review (guarded) |
| [`tag_assign`](docs/tools.md#tag_assign) | write (guarded) | Assign tags (guarded) |
Jeder Parameter jedes Werkzeugs: [docs/tools.md](docs/tools.md). Suchen liefern
`{ total, page, limit, items }` mit exakten Trefferzahlen, `limit` ist auf 50
begrenzt, und Fehler kommen als `{ error: { status, code, detail } }` zurück.
Ressourcen: `shopware://shop`, `shopware://sales-channels`, `shopware://order/{orderNumber}`,
`shopware://product/{productNumber}`, `shopware://customer/{customerNumber}`. Prompts:
`order_summary`, `customer_profile`, `low_stock_report`, `reorder_list`, `review_moderation`,
`weekly_review`.
**Plugin-Werkzeuge.** Beim Start fragt der Server im Hintergrund, welche
Erweiterungen installiert und aktiv sind, und registriert zusätzliche Werkzeuge
für die, die er kennt. Zwei Pakete gibt es heute:
[FroshTools](https://github.com/FriendsOfShopware/FroshTools), das quelloffene
Betriebs-Plugin, mit `frosh_health` (Plattform- und Performance-Prüfungen),
`frosh_queue` (Message-Queue, wartende Nachrichten, Worker) und
`frosh_composer_audit` (Sicherheitshinweise zu Abhängigkeiten), alle nur lesend;
und [Merqo](https://github.com/bnymnDev/merqo) mit `merqo_health`,
`merqo_einvoice_inbox`, `merqo_returns_search` und `merqo_abandoned_carts`.
Shops ohne das Plugin sehen dessen Werkzeuge nie, und die Kernwerkzeuge verhalten
sich in beiden Fällen gleich. `--no-extensions` schaltet den Mechanismus ab.
Unterstützung für die Erweiterungen eines anderen Anbieters ist eine Datei
unter `src/extensions/`; Pull Requests sind willkommen.
---
## Sicherheit
- **Standardmäßig nur lesend.** Ohne `--allow-write` (oder `SHOPWARE_MCP_ALLOW_WRITE=true`) werden die Schreibwerkzeuge gar nicht registriert. Was ein Agent nicht sieht, kann er nicht aufrufen.
- **Jeder Schreibzugriff ist zuerst ein Probelauf.** Alle fünfzehn Schreibwerkzeuge, von `stock_set` bis `tag_assign`, stehen auf `dryRun: true` und liefern `{ dryRun: true, wouldSend: { method, url, body } }`, als Liste, wenn ein Aufruf mehrere Requests braucht. Ein echter Schreibzugriff liefert die neu gelesene Entität.
- **Ein Schreib-Budget.** `SHOPWARE_MCP_MAX_WRITES=20` weist den einundzwanzigsten echten Schreibzugriff eines Prozesses mit `WRITE_BUDGET_EXHAUSTED` ab; Probeläufe bleiben frei. Kein Prompt kann das aufheben.
- **Schmale Schreibzugriffe.** `product_update` ändert Name, Beschreibung, Aktiv-Status und den Preis einer Währung; `product_create` legt ein einfaches Produkt an, mehr nicht; `product_cover_set` fügt ein Bild hinzu (JPEG, PNG, WebP, GIF oder AVIF, nie SVG), das der Shop selbst lädt. `promotion_create` erzeugt einen Warenkorbrabatt, inaktiv, solange nichts anderes gesagt wird. `customer_update` ändert Aktiv-Status und Kundengruppe. Die Transition-Werkzeuge bewegen nur Status, nie Geld. Belege erzeugt Shopwares eigener Generator, versendet werden sie von diesem Server nie; `order_documents_bulk_create` macht höchstens fünfzig je Aufruf und belastet das Schreib-Budget je Bestellung. `tag_assign` setzt oder entfernt Tags nach Namen und lässt den Rest des Datensatzes in Ruhe. Nichts löscht. Sonst nichts.
- **Ein simulierter Warenkorb ist keine Bestellung.** `checkout_simulate` und `storefront_search` gehen über Shopwares eigenen Admin-Proxy zur Store API, mit einem zufälligen Kontext-Token, das kein Besucher hat. Die Bestellroute wird nie aufgerufen, der Warenkorb danach gelöscht; übrig bleibt eine Kontextzeile, die Shopware selbst verfallen lässt. Die Simulation als Kunde berührt weder dessen Sitzung noch seinen gespeicherten Warenkorb. Erweiterungen, die auf gespeicherte Warenkörbe reagieren, etwa Mails zu abgebrochenen Warenkörben, sehen den simulierten Warenkorb aber als den des Kunden; als echter Kunde also nur simulieren, wo das in Ordnung ist.
- **Minimale Rechte als Standard.** `shopware-mcp setup` vergibt jedem Werkzeug genau die Rechte, die an einer sonst leeren Rolle gemessen wurden, und nie Administratorrechte. Zwei Rechte reichen weiter als ihr Werkzeug und bleiben draußen, außer auf Wunsch: die ganze Systemkonfiguration lesen, SMTP-Passwörter und Zahlungsschlüssel eingeschlossen (`--settings`), und Erweiterungen installieren (`--plugin-updates`). Setup ändert nur eine Rolle, die es selbst angelegt hat, nennt jedes Recht, das es hinzufügt oder entfernt, und zeigt das neue Secret, bevor irgendetwas anderes scheitern kann. Das Admin-Passwort dient einer einzigen Anmeldung über https, unverschlüsselt nur zum eigenen Rechner, und wird nie gespeichert.
- **Bereinigte Lesezugriffe.** `entity_search` entfernt Passwörter, Schlüssel, Tokens und Hashes aus jeder Antwort und verweigert Entitäten, die Zugangsdaten oder Systeminterna enthalten: Benutzer, Integrationen, ACL-Rollen, Apps, Systemkonfiguration.
- **Nirgends Geheimnisse.** Zugangsdaten erscheinen nie in Ausgaben, Logs oder Fehlermeldungen. Logs gehen nur nach stderr.
- **Keine Telemetrie.** Der Server spricht mit Ihrem Shop und mit Ihrem Host. Mit niemandem sonst.
- **HTTP-Transport.** Mit `SHOPWARE_MCP_HTTP_TOKEN` verlangt `/mcp` diesen Bearer-Token, verglichen in konstanter Zeit. Ohne Token auf localhost lassen (Standard) oder hinter einen authentifizierenden Reverse Proxy stellen; der Server warnt, wenn er ohne Token weiter erreichbar ist.
- **Requests laufen ab.** Ein Shop, der nicht mehr antwortet, kostet einen Request 30 Sekunden (`SHOPWARE_MCP_TIMEOUT_MS`), nicht die ganze Sitzung.
Etwas gefunden? Siehe [SECURITY.md](SECURITY.md).
---
## Konfiguration
| Variable | Pflicht | Hinweise |
|---|---|---|
| `SHOPWARE_URL` | ja | Basis-URL des Shops, z. B. `https://shop.example.com` |
| `SHOPWARE_CLIENT_ID` | ja | Zugangsschlüssel-ID der Integration |
| `SHOPWARE_CLIENT_SECRET` | ja | Geheimschlüssel der Integration |
| `SHOPWARE_MCP_ALLOW_WRITE` | nein | `true` registriert die Schreibwerkzeuge. Standard: aus |
| `SHOPWARE_MCP_MAX_WRITES` | nein | Echte Schreibzugriffe, die ein Prozess insgesamt ausführen darf; `0` (Standard) heißt keine Grenze |
| `SHOPWARE_MCP_DEFAULT_LIMIT` | nein | Standard-Seitengröße für Suchen (Standard 20, maximal 50) |
| `SHOPWARE_MCP_EXTENSIONS` | nein | `false` schaltet Plugin-Werkzeuge und die Erweiterungssuche beim Start ab |
| `SHOPWARE_LANGUAGE_ID` | nein | Sprach-UUID für übersetzte Felder (`sw-language-id`). Standard: Shopsprache |
| `SHOPWARE_MCP_TIMEOUT_MS` | nein | Timeout je Admin-API-Request in Millisekunden (Standard 30000, 1000 bis 600000) |
| `SHOPWARE_MCP_HTTP_TOKEN` | nein | Bearer-Token, den der HTTP-Transport auf `/mcp` verlangt (mindestens 16 Zeichen). Standard: keiner |
| `SHOPWARE_MCP_LOG_LEVEL` | nein | `error` (Standard), `warn`, `info`, `debug`. Logs gehen nur nach stderr |
| `TZ` | nein | Zeitzone für „heute" in `shop_pulse` und `brief`, z. B. `Europe/Berlin`. Standard: die des Systems. Sie wählt auch die Feiertage, die der Puls auslässt (DE, AT, CH) |
| `SHOPWARE_MCP_RULES` | nein | Regelpakete und Dateien für das Audit, z. B. `gpsr,eaa,feeds,./rules.json` ([Beispiel](docs/examples/rules.json)) |
| `SHOPWARE_MCP_JOURNEYS` | nein | JSON-Datei mit Kaufwegen für `journeys_run` ([Beispiel](docs/examples/journeys.json)) |
| `SHOPWARE_ADMIN_USER`, `SHOPWARE_ADMIN_PASSWORD` | nur `setup` | Die Admin-Anmeldung, mit der `setup` einmal Rolle und Integration anlegt. Wird nie gespeichert; ohne sie fragt `setup` nach |
CLI-Flags überschreiben die Umgebung: `--allow-write`, `--max-writes `, `--no-extensions`, `--http`, `--port `, `--host `, `--log-level `. Befehle: `setup`, `doctor`, `init`, `brief`, `audit` und `report`; `npx shopware-mcp --help` zeigt ihre Optionen.
---
## Open Core
Alles in diesem Repository ist MIT und bleibt es. Es deckt einen Shop, einen Betreiber und interaktive Nutzung ab.
Vom selben Autor stammt [Merqo](https://github.com/bnymnDev/merqo), eine kommerzielle Suite von
Shopware-Erweiterungen für EU-Compliance und den täglichen Betrieb. Dieser Server erkennt sie und
ergänzt passende Werkzeuge, setzt sie aber nie voraus.
Agenturen und Händler, die das im großen Stil betreiben, brauchen meist mehr, und genau das baue und betreibe ich für Kunden:
- **Multi-Shop**: ein MCP-Endpunkt, der auf Dutzende Shops mit eigenen Zugangsdaten und Rechten routet
- **Gehostet mit Audit-Trail**: jeder Werkzeugaufruf protokolliert mit Wer, Was und Wann, rollenbasierter Zugriff, SLA
- **Massenoperationen und Migrationen**: Preis- und Bestandsupdates in Masse, Katalogimporte, sichere Rollbacks
- **Eigene Agenten und Shopware-Plugins**: Workflows für Ihr ERP, PIM oder Ihren Support-Desk
Interesse? Ein Issue mit dem Label `consulting` oder eine Nachricht über [github.com/bnymnDev](https://github.com/bnymnDev). Sie setzen shopware-mcp produktiv ein und wollen, dass es gepflegt bleibt? [Sponsoring](https://github.com/sponsors/bnymnDev) hilft.
---
## Dokumentation
Alle weiteren Dokumente sind auf Englisch:
| Dokument | Inhalt |
|---|---|
| [docs/quickstart.md](docs/quickstart.md) | Integration, erster Start, Host-Konfigurationen, Beispielfragen, Filter-Spickzettel |
| [docs/tools.md](docs/tools.md) | Jedes Werkzeug mit jedem Parameter, aus dem Code generiert |
| [docs/self-hosting.md](docs/self-hosting.md) | Transporte, Docker, Reverse Proxies, Shopware-Rechte, Betrieb |
| [docs/decisions.md](docs/decisions.md) | Designentscheidungen und ihre Begründung |
| [CONTRIBUTING.md](CONTRIBUTING.md) | Einrichtung, Grundregeln, End-to-End-Tests, Releases |
| [SECURITY.md](SECURITY.md) | Was melden und wohin |
| [CHANGELOG.md](CHANGELOG.md) | Was sich in jeder Version geändert hat |
## Lizenz
[MIT](LICENSE)
Wenn shopware-mcp eine Frage beantwortet hat, die der Admin nicht konnte, hilft ein Stern dem nächsten Shop, es zu finden.