Markus Michalski FAQ

Shopware Admin: Security and privacy

Security of the Shopware Admin MCP server: credential storage, OAuth2 token, input validation, protection against internal URLs, rate limit, logging and which data goes to Claude.

Deutsche Version

Back to overview

Shopware Admin: Security and privacy

This documentation always describes the current state of the main branch.

Credentials and token

Aspect Behaviour
Storage Plain text in the .env file (or in the process environment). The file is listed in .gitignore and never belongs in a repository.
Transmission Client ID and client secret go exclusively by POST to <SHOPWARE_URL>/api/oauth/token. The server does not enforce HTTPS, with http:// only a warning appears on stderr.
Method OAuth2 client credentials. The integration's permissions in Shopware determine what the server may do.
Token Held in memory only. It is fetched on the first API call and renewed 60 seconds before expiry, concurrent renewals are merged into one request. The token request has a 15 second timeout.
Token errors If Shopware answers an API call with 401 the token is discarded and the call is repeated once with a new token.

Anyone who can read the .env can access the Admin API directly with the same permissions. Create a dedicated integration with minimal permissions for the server and use separate integrations for test and production.

Protections in the server

All tool parameters are treated as untrusted because a language model supplies them.

Protection Effect
Input validation Every call is checked with a Zod schema: types, lengths, value ranges and enumerations. Errors come back as INVALID_INPUT with a list of fields.
ID validation IDs must be 32 hex characters (or a UUID with hyphens) so nothing else ends up in an API path.
Create inactive product_create always creates an inactive product.
Orders read only No tool changes orders.
No deletion There is no delete tool. The only exception: if media_upload_url fails after creating the medium, that new medium is removed again.
Internal URL protection media_upload_url rejects addresses whose host is localhost, 0.0.0.0, a purely numeric address, a loopback, private (10., 172.16. to 172.31., 192.168.), link-local (169.254.) or shared-address (100.64. to 100.127.) network, or an IPv6 loopback, unique-local or link-local address, as well as the metadata hosts metadata.google.internal and metadata.goog. Only http and https are allowed.
Test mail limit mail_template_send_test is limited to 5 calls per template and 10 in total per minute. The recipient must neither contain localhost nor use an IP address as domain.
Timeouts and retries 30 seconds per API request. On 429 the server retries up to three times with growing delay (1, 2, 4 seconds).
Error output For server errors (500, 502, 503) the message is "Shopware API error (500): Shopware server error", the details of the Shopware response do not appear in it. Other errors show at most 200 characters of the Shopware message. For 404 only the last path segment is named.

The internal URL check only evaluates the host text of the URL. It does not resolve names. A public hostname that points to a private address internally is not detected. The download itself is performed by Shopware, not by the MCP server.

Logging

The server writes to stderr only, so the protocol channel on stdout stays clean. Each line carries a timestamp and level. The default is info.

Which data leaves the machine

Data Destination
Tool calls and results (product texts, prices, media, mail templates) Part of the conversation with Claude and therefore sent to Anthropic.
Order data order_list returns customer name and email among other things. order_get additionally returns company, phone numbers, billing and shipping address, line items and the customer comment. All of it becomes part of the conversation. Only call these tools if that is compatible with your data protection agreements. order_stats returns aggregated numbers only.
Requests to the Admin API Only to the configured SHOPWARE_URL.
Files for media_upload_url Shopware downloads them from the given URL, they do not pass through the MCP server.
Credentials Only to the shop, never to Claude.

The server contains no telemetry and no further external calls. The wiki hook exists in the code but is never called.

Recommendations