APIs & Integrationen

Shopware hat einen MCP-Server — und er ist abgeschaltet

61 Dateien, 54 Routen, elf Werkzeuge für KI-Agenten stecken im Kern von 6.7. Ab Werk antwortet der Endpunkt mit 404. Wir haben ihn eingeschaltet und benutzt.

Pixup MediaVeröffentlicht am 11 Min. Lesezeit

Ergebnis

11 Werkzeuge, 8 Ressourcen, ab Werk 404

6.7.13.1 trägt 61 MCP-Dateien und 54 Routen im Kern, 6.6.10.6 keine einzige. Ohne das Feature-Flag MCP_SERVER antwortet /api/_mcp mit 404. Mit Flag meldet der Server Protokollversion 2025-11-25 und elf Werkzeuge — drei davon schreiben, eines löscht.

Wer heute wissen will, wie ein KI-Agent an einen Shopware-Shop kommt, landet schnell bei selbst gebauten Brücken: ein Dienst, der die Admin-API spricht, ein Werkzeugkatalog, eine Authentifizierung. Wir haben nachgesehen, ob Shopware das inzwischen selbst mitbringt. Es bringt es mit — und lässt es aus.

Das Ergebnis

6.6.10.66.7.13.1
Dateien unter einem /Mcp/-Pfad im Kern061
davon Werkzeuge013
davon Ressourcen09
davon Prompts01
davon Controller05
Routen mit mcp054
davon Admin-API05
davon Store-API01
davon generierte CRUD048
Antwort von /api/_mcp ab Werk—404

Die 48 generierten CRUD-Routen gehören zu drei neuen Entitäten samt Übersetzungstabellen: app_mcp_tool, app_mcp_resource und app_mcp_prompt. Eine App kann also eigene Werkzeuge, Ressourcen und Prompts mitbringen — das ist der eigentliche Architekturhinweis.

Ab Werk 404, und warum das richtig ist

Der Server hängt am Feature-Flag MCP_SERVER. In der Flag-Definition des Kerns steht wörtlich Experimental!, der Standardwert ist false, und ohne das Flag antwortet der Endpunkt mit 404 — nicht mit 401 oder 403. Er existiert für einen Aufrufer schlicht nicht.

Das ist eine bewusste Entscheidung und eine vernünftige. Wer die Werkzeugliste unten liest, versteht sofort, warum.

Die elf Werkzeuge

Nach dem Einschalten meldet /api/_action/mcp/capabilities genau das hier:

WerkzeugRechtehängt ab von
shopware-entity-schema——
shopware-entity-searchlesenentity-schema
shopware-entity-readlesenentity-schema
shopware-entity-aggregatelesenentity-schema
shopware-entity-upsertanlegen, ändernentity-schema
shopware-entity-deletelöschenentity-search
shopware-media-upload——
shopware-order-state——
shopware-system-config-read——
shopware-system-config-write—system-config-read
shopware-theme-config——

Dazu acht Ressourcen — Business-Events, Währungen, Entitätenliste, Erweiterungen, Flow-Aktionen, Sprachen, Verkaufskanäle, State Machines — und ein Prompt namens shopware-context.

Drei Werkzeuge schreiben, eines löscht, eines ändert die Systemkonfiguration. Ein MCP-Client mit gültigem Admin-Token kann damit Produkte anlegen, Bestellstatus setzen, Medien hochladen und Konfiguration überschreiben. Genau deshalb gibt es im Kern Allowlists — je Integration und je Benutzer, über eigene Endpunkte pflegbar — und zwei eigene Ratenbegrenzungsregeln: mcp_admin_api mit 300 Aufrufen je Minute und mcp_store_api mit 120.

Der Handshake, und die Stelle, an der er scheitert

Der Server spricht Protokollversion 2025-11-25. Der Ablauf ist strikt:

POST /api/_mcp   {"method":"initialize", ...}
  → 200, und im Antwortkopf: Mcp-Session-Id: <uuid>

POST /api/_mcp   {"method":"notifications/initialized"}
  → ohne diesen Schritt bleibt die Sitzung unbrauchbar

POST /api/_mcp   {"method":"tools/call", ...}
  → jetzt erst wird gearbeitet

Wer die Session-ID nicht mitschickt, bekommt:

{"jsonrpc":"2.0","error":{"code":-32600,
 "message":"A valid session id is REQUIRED for non-initialize requests."}}

Das ist protokollkonform und trotzdem der Punkt, an dem ein selbst gebauter Client als Erstes hängenbleibt.

Ein Fallstrick, der Zeit kostet

Die Werkzeugparameter sehen nach JSON aus und sind es an einer Stelle nicht. aggregations und ids werden als Zeichenkette erwartet, die JSON enthält — nicht als Array. Ein nativ übergebenes Array wird abgewiesen:

Property '/ids': Invalid type. Expected `string`, but received `array`.

Richtig ist also "ids": "[\"<uuid>\"]" und nicht "ids": ["<uuid>"]. Wer seinen Client generisch aus dem Schema baut, merkt das sofort; wer ihn von Hand schreibt, sucht eine Weile.

Die Probe aufs Exempel

Zwei Aufrufe, weil eine Werkzeugliste noch nichts darüber sagt, ob die Werkzeuge arbeiten.

Lesend, mit Gegenprobe. shopware-entity-aggregate auf product mit einer count-Aggregation:

{"success":true,"data":{"aggregations":{"anzahl":{"count":18}}}}

Die Datenbank derselben Installation meldet für SELECT COUNT(*) FROM product ebenfalls 18. Die Messung prüft sich damit selbst.

Schreibend, im Trockenlauf. shopware-entity-delete auf ein vorhandenes Produkt. Der Trockenlauf ist der Standard — man muss ihn nicht einschalten, sondern ausschalten. Zurück kam die vollständige Kaskade:

product               1 Datensatz
product_price         2
product_media         1
product_visibility    1
product_search_keyword …

Und die Zeilenzahl: 18 vorher, 18 nachher. Nichts gelöscht.

Dass ein Löschwerkzeug für KI-Agenten den Trockenlauf als Standard hat und die Folgen vorher ausgibt, ist die durchdachteste Einzelentscheidung in diesem ganzen Paket.

Was das praktisch bedeutet

Für Händler. Nichts ist an, nichts muss abgeschaltet werden. Wer eine 6.7-Installation betreibt, hat keinen offenen KI-Endpunkt — der Server antwortet mit 404, solange das Flag nicht gesetzt ist. Die Frage lautet nicht „Wie mache ich das zu?", sondern „Wann und mit welchen Rechten mache ich das auf?".

Für Integrationen. Wer heute eine eigene Brücke zwischen Agent und Shop baut, sollte wissen, dass der Kern in diese Richtung arbeitet. Ein Eigenbau, der genau die elf Werkzeuge nachbildet, wird mittelfristig doppelte Arbeit. Sinnvoller ist ein Eigenbau für das, was diese elf nicht abdecken.

Für Rechte. Die Allowlists sind der Teil, den man zuerst versteht, nicht zuletzt. Ein Agent mit shopware-entity-upsert und ohne Einschränkung auf Entitäten darf alles schreiben, was die DAL kennt — das sind in 6.7 231 Kernentitäten.

Grenzen dieser Messung

Gemessen wurde eine dev-Runtime mit neun installierten Plugins. Zwei der elf Werkzeuge wurden tatsächlich aufgerufen; über die übrigen neun sagt dieser Text nur, dass sie registriert sind und welche Rechte sie deklarieren. Der Store-API-Endpunkt wurde nicht bis zum Werkzeugaufruf durchgespielt.

Und der wichtigste Vorbehalt steht im Kern selbst: Das Flag ist als Experimental gekennzeichnet. Wer heute dagegen baut, baut gegen eine Schnittstelle, die sich in der nächsten Minor-Version ändern darf.

Nach dem Test wurde die Runtime zurückgesetzt und gegengeprüft: .env byte-identisch zur Sicherung, /api/_mcp wieder 404.

Technische UnterstützungApp- und Plugin-Entwicklung