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.
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
.envcan 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.
- At startup "Starting claude-mcp-shopwareadmin server" appears with the shop URL and the hard-coded version string, followed by "Server connected and ready".
- The token is fetched on the first API call, only then "OAuth2 token acquired" appears.
- At
debuglevel method and endpoint of every API call are logged, request bodies only as a length. - Credentials and token are not written.
- Shopware API errors appear with status, endpoint and the first 200 characters of the response.
- When sending a test mail the recipient address appears once shortened (
ab***@domain) and in full in the success message of the log.
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
- Use a dedicated integration with the minimum permissions needed, see Configuration.
- Use
https://forSHOPWARE_URL. - Change the client secret or recreate the integration if the
.envwas shared. - Only activate new products with
product_set_activeafter review.