claude-mcp-shopwareadmin is an MCP Server (Model Context Protocol) that gives Claude direct access to the Shopware 6 Admin API. With 43 specialized tools, it covers the complete shop management workflow: from product creation through content generation and SEO optimization to order overviews and BFSG-compliant media management.
This MCP Server enables Claude to interact directly with your Shopware 6 shop - create products, generate descriptions, optimize SEO, review orders and manage media, without manual copy-paste or browser switching.
Product Management: "Create a new product named 'ITH Bag Spring Flowers', price 4.99 EUR in the Embroidery Files category" - Claude creates the product directly in the shop (inactive for review).
Content Generation: "Write a product description for product XY" - Claude automatically detects the style (Creative for embroidery files, Professional for software) and generates appropriate content.
Custom Content Styles: You can define custom style profiles (e.g. "B2B" with formal addressing) and map them to categories - without any code changes. See Configuring Content Profiles.
SEO Optimization: "Optimize the SEO data for all products in the Software category" - Claude generates meta title, description and keywords per product.
BFSG Compliance: "Check which product images are missing alt text" - Claude performs a BFSG audit and lists all affected media.
Order Analysis: "Show me the order statistics for the last 30 days" - Claude retrieves aggregated data (revenue, order count, average value).
| Requirement | Version | Notes |
|---|---|---|
| Node.js | >= 20.0.0 | LTS recommended |
| npm | >= 9 | Included with Node.js |
| Claude Desktop or CLI | Current | MCP client required |
| Shopware 6 | >= 6.5 | Admin API must be accessible |
| Shopware Integration | - | API credentials with appropriate permissions |
The Shopware integration must have read/write permissions on the relevant entities (products, categories, mail templates, media, etc.). For read-only operations, read permissions suffice.
git clone https://github.com/markus-michalski/claude-mcp-shopwareadmin.git
cd claude-mcp-shopwareadmin
npm install
npm run build
# After building, copy to the MCP server directory
mkdir -p ~/.claude/mcp-servers/shopwareadmin
cp -r dist node_modules package.json .env ~/.claude/mcp-servers/shopwareadmin/
# Optional: Customize content profiles and copy along
cp content-profiles.example.json ~/.claude/mcp-servers/shopwareadmin/content-profiles.json
Create a .env file based on .env.example:
| Variable | Required | Default | Description |
|---|---|---|---|
SHOPWARE_URL |
Yes | - | Base URL of the Shopware shop (e.g. https://shop.example.com) |
SHOPWARE_CLIENT_ID |
Yes | - | OAuth2 Client ID of the Shopware integration |
SHOPWARE_CLIENT_SECRET |
Yes | - | OAuth2 Client Secret of the Shopware integration |
SHOPWARE_DEFAULT_TAX_ID |
Yes | - | Default tax rate ID (32-char hex) |
SHOPWARE_DEFAULT_TAX_RATE |
Yes | 19 |
Default tax rate in percent |
SHOPWARE_DEFAULT_SALES_CHANNEL_ID |
Yes | - | Default sales channel ID (32-char hex) |
SHOPWARE_DEFAULT_CURRENCY_ID |
No | b7d2554b0ce847cd82f3ac9bd1c0dfca |
Currency ID (default: EUR) |
CONTENT_PROFILES_PATH |
No | - | Path to content-profiles.json (absolute or relative to cwd). See Configuring Content Profiles |
WIKIJS_BASE_URL |
No | https://faq.markus-michalski.net |
Base URL for Wiki.js links |
CACHE_TTL_CATEGORIES |
No | 3600000 |
Cache TTL for categories (ms, 1 hour) |
CACHE_TTL_PROPERTIES |
No | 3600000 |
Cache TTL for properties (ms, 1 hour) |
CACHE_TTL_SNIPPETS |
No | 300000 |
Cache TTL for snippets (ms, 5 minutes) |
LOG_LEVEL |
No | info |
Log level: debug, info, warn, error |
| Entity | Read | Write | Note |
|---|---|---|---|
| product | Yes | Yes | Create/update products |
| category | Yes | No | Read category tree |
| property_group | Yes | No | Read product properties |
| product_manufacturer | Yes | No | Read manufacturers |
| tax | Yes | No | Read tax rates |
| currency | Yes | No | Read currencies |
| mail_template | Yes | Yes | Read/update templates |
| media | Yes | Yes | Manage media, alt texts |
| order | Yes | No | Read orders |
| sales_channel | Yes | No | Sales channel context |
| seo_url | Yes | Yes | Manage SEO URLs |
| product_cross_selling | Yes | Yes | Manage cross-selling |
| flow | Yes | Yes | Control Flow Builder |
.env fileUse separate integrations for different environments (staging/production). Never share client secrets through insecure channels.
claude mcp add --scope user --transport stdio shopwareadmin -- \
node ~/.claude/mcp-servers/shopwareadmin/dist/index.js
{
"mcpServers": {
"shopwareadmin": {
"command": "node",
"args": ["/home/user/.claude/mcp-servers/shopwareadmin/dist/index.js"],
"env": {
"SHOPWARE_URL": "https://shop.example.com",
"SHOPWARE_CLIENT_ID": "SWIA...",
"SHOPWARE_CLIENT_SECRET": "...",
"SHOPWARE_DEFAULT_TAX_ID": "...",
"SHOPWARE_DEFAULT_SALES_CHANNEL_ID": "..."
}
}
}
}
cd claude-mcp-shopwareadmin
npm run dev
# Server starts with tsx watch and restarts on changes
New in v1.1.0: Content style profiles are now configurable via an external JSON file. You can define custom styles, tonalities, addressing forms and category mappings - without any code changes.
The MCP server uses content profiles to generate product descriptions and SEO texts in the appropriate style. Each profile defines tonality, addressing, text structure and target audience. A category mapping automatically selects the right profile based on the product's category.
Previously, these profiles were hardcoded. Starting with v1.1.0, they can be freely customized via a content-profiles.json file.
The server searches for the configuration file in this order:
CONTENT_PROFILES_PATH environment variable (absolute or relative)~/.claude/mcp-servers/shopwareadmin/content-profiles.json (deployment path)./content-profiles.json (local directory)If no file is found, the built-in default profiles (Creative + Software) are used.
The configuration file is loaded once at server startup and fully validated with Zod. Invalid files produce a clear error message referencing
content-profiles.example.json.
Create a content-profiles.json based on the included content-profiles.example.json:
{
"language": "de",
"defaultProfile": "creative",
"profiles": {
"creative": {
"tonality": "Personal, warm, emotional",
"addressing": "du",
"structure": [
"Emotional opening (question/anecdote)",
"What is it?",
"Technical details (format, size)",
"Usage tips"
],
"targetAudience": "Hobbyists, creatives, DIY enthusiasts",
"exampleIntro": "What would Easter be without the Easter bunny?",
"includeSnippets": false
},
"software": {
"tonality": "Professional, factual, solution-oriented",
"addressing": "Sie",
"structure": [
"Problem statement",
"Solution approach",
"Feature table",
"System requirements",
"Documentation links"
],
"targetAudience": "Shop owners, developers, agencies",
"exampleIntro": "Spam protection without Google, without cookies, without image puzzles.",
"includeSnippets": true
}
},
"categoryMapping": {
"Software": "software",
"Stickdateien": "creative",
"Genaehtes": "creative",
"3D-Druck": "creative"
}
}
| Parameter | Type | Description |
|---|---|---|
language |
string | Language of generated content (e.g. "de", "en") |
defaultProfile |
string | Fallback profile when no category mapping matches |
profiles |
object | Style profiles (at least one required) |
profiles.*.tonality |
string | Text tonality (e.g. "Personal, warm") |
profiles.*.addressing |
"du" / "Sie" |
Addressing form (informal/formal) |
profiles.*.structure |
string[] | Text structure guidelines for generation |
profiles.*.targetAudience |
string | Target audience for generated content |
profiles.*.exampleIntro |
string | Example opening as guidance for Claude |
profiles.*.includeSnippets |
boolean | Whether to include product snippets. Requires the Product Snippets plugin |
categoryMapping |
object | Mapping from category name to profile name |
All values in
categoryMappingmust reference existing profiles. ThedefaultProfilemust also exist. Zod validates this automatically on load.
You can create as many profiles as needed. Here's an example of a third B2B profile:
{
"language": "de",
"defaultProfile": "creative",
"profiles": {
"creative": { "..." : "..." },
"software": { "..." : "..." },
"b2b": {
"tonality": "Formal, factual, data-driven",
"addressing": "Sie",
"structure": [
"Business value",
"ROI argumentation",
"Technical specifications",
"Integration options"
],
"targetAudience": "Procurement managers, IT decision makers",
"exampleIntro": "Optimize your procurement processes.",
"includeSnippets": true
}
},
"categoryMapping": {
"Software": "software",
"Stickdateien": "creative",
"B2B-Loesungen": "b2b"
}
}
After editing, restart the MCP server - the new profiles are immediately available. The style parameter in product_generate_content and category_generate_content then also accepts "b2b".
| Area | Tools | Description |
|---|---|---|
| Products | 6 | CRUD, Search, Activation |
| Content | 4 | Descriptions, SEO, Variants |
| Categories | 3 | Tree, Details, SEO Update |
| Mail Templates | 4 | CRUD, Test Send |
| Orders | 3 | List, Details, Statistics |
| Media | 6 | CRUD, Search, BFSG Audit, Upload |
| Flow Builder | 3 | List, Details, Toggle |
| Cross-Selling | 5 | CRUD, AI Recommendations |
| SEO URLs | 4 | List, Audit, Update, Regeneration |
| Helpers | 3 | Properties, Manufacturers, Snippets |
| Total | 41 |
| Tool | Description | Key Parameters |
|---|---|---|
product_create |
Create a new product (always inactive!) | name, productNumber, price, categoryId |
product_get |
Get product details with variants, media, properties | id or productNumber |
product_list |
Filter and paginate products | search, categoryId, active, limit, offset |
product_update |
Update a product | id, name, price, description, stock, tags, customFields |
product_set_active |
Activate/deactivate a product | id, active |
search_products |
Full-text search across all products | query, limit |
Products are ALWAYS created as inactive. This is a deliberate safety feature - review first, then activate.
| Tool | Description | Key Parameters |
|---|---|---|
product_generate_content |
Generation prompt for product description | productId, style, maxLength |
product_generate_seo |
Generate SEO metadata | productId, maxTitleLength, maxDescriptionLength |
variant_generate_content |
Variant-specific description | variantId, inheritFromParent, focusOnOptions |
content_update |
Save generated content to product | productId, description, metaTitle, metaDescription, keywords |
The content generator automatically detects the appropriate style based on the product category. The mapping is loaded from content-profiles.json (or uses built-in defaults):
Default Configuration:
| Category | Style | Tonality | Address |
|---|---|---|---|
| Embroidery Files | creative | Personal, warm, emotional | "du" (informal) |
| Sewn Items | creative | Personal, warm, emotional | "du" (informal) |
| 3D Printing | creative | Personal, warm, emotional | "du" (informal) |
| Software | software | Professional, factual | "Sie" (formal) |
The style can also be manually overridden using the style parameter. Custom profiles can be added via content-profiles.json (see Configuring Content Profiles).
| Tool | Description | Key Parameters |
|---|---|---|
category_list |
Get category tree | depth, parentId, includeInactive |
category_get |
Category details + optional products | id, includeProducts, productLimit |
category_generate_content |
Generate SEO text for category | id, maxLength, style |
category_update |
Update category SEO data | id, description, metaTitle, metaDescription, keywords |
| Tool | Description | Key Parameters |
|---|---|---|
mail_template_list |
Browse templates | search, limit, offset |
mail_template_get |
Template details + Twig variables | id or technicalName |
mail_template_update |
Update template (Twig support) | id, subject, contentHtml, contentPlain |
mail_template_send_test |
Send test email | mailTemplateId, recipient |
Test sending is rate-limited: maximum 5 emails per template and 10 emails total per minute.
| Tool | Description | Key Parameters |
|---|---|---|
order_list |
Filter orders | orderStatus, paymentStatus, deliveryStatus, dateFrom, dateTo |
order_get |
Order details with line items | id or orderNumber |
order_stats |
Aggregated statistics | dateFrom, dateTo |
| Tool | Description | Key Parameters |
|---|---|---|
media_list |
Filter media (also by missing alt text) | hasAlt, mimeTypePrefix, limit |
media_get |
Media details + associated products | id |
media_update |
Update alt text and title | id, alt, title |
media_search |
Full-text search in media | query, limit |
media_audit_alt |
BFSG audit: products without alt text | onlyActive, limit |
media_upload_url |
Upload media from URL | url, alt, title |
The BFSG audit tool (
media_audit_alt) is essential for compliance with the German Accessibility Strengthening Act. All product images MUST have a descriptive alt text.
| Tool | Description | Key Parameters |
|---|---|---|
flow_list |
List and filter flows | active, eventName, hasMailAction, search |
flow_get |
Flow details with sequences | id or name |
flow_toggle |
Activate/deactivate flow | id, active |
| Tool | Description | Key Parameters |
|---|---|---|
cross_selling_list |
Cross-selling groups of a product | productId |
cross_selling_get |
Group details + assigned products | id |
cross_selling_create |
Create new cross-selling group | productId, name, type, assignedProductIds |
cross_selling_update |
Update group | id, name, assignedProductIds, active |
cross_selling_suggest |
AI context for recommendations | productId, limit |
| Tool | Description | Key Parameters |
|---|---|---|
seo_url_list |
Filter SEO URLs | routeName, salesChannelId, isCanonical, search |
seo_url_audit |
Audit for issues | routeName, salesChannelId, limit |
seo_url_update |
Change URL path/canonical | id, seoPathInfo, isCanonical, isDeleted |
seo_url_generate |
Regenerate SEO URLs | routeName, salesChannelId |
| Tool | Description | Key Parameters |
|---|---|---|
get_properties |
Product properties and options | groupId |
get_manufacturers |
List manufacturers/brands | search, limit |
snippet_list |
Product snippets (plugin-dependent) | activeOnly |
Create a product:
"Create a new product: Name 'ITH Bag Spring Flowers', product number 'ITH-FB-001', price 5.99 EUR, category Embroidery Files."
Generate product description:
"Generate a description for the product with number ITH-FB-001."
Claude loads the product, detects the style (Creative for embroidery files) and generates an appropriate description.
SEO optimization:
"Generate SEO metadata for the product 'OXID Sitemap Module' and save it."
Content with specific style:
"Generate a description for product XY using the 'b2b' style."
Claude uses the specified profile from content-profiles.json instead of automatic detection.
BFSG audit:
"Which active product images are missing alt text? Create a list for me."
Set up cross-selling:
"Which products would work well as accessories for product XY?"
Claude uses cross_selling_suggest to analyze category neighbors and provide recommendations.
Order statistics:
"How many orders did we have in January 2026 and what was the revenue?"
Edit mail template:
"Show me the order confirmation template and change the subject to 'Thank you for your order No. {{ order.orderNumber }}'."
Symptom: Claude does not show the server as connected or tools are not available.
Check:
npm run build in the project directorynode /path/to/dist/index.js must work directlynode --version.env file exist in the correct directory?# Test if the server starts:
node /path/to/dist/index.js
# Should wait on stdin/stdout (no error)
Symptom: Error message AUTH_FAILED or Could not authenticate with Shopware.
Check:
SHOPWARE_CLIENT_ID and SHOPWARE_CLIENT_SECRET correct?curl -s https://shop.example.com/api/oauth/tokenOAuth2 tokens are automatically cached and renewed 60 seconds before expiry. For persistent auth errors, check the integration in Shopware.
Symptom: Tool calls take very long or abort with timeout.
Check:
Symptom: API_ERROR with status 403 or Forbidden.
Check:
bin/console cache:clear)Symptom: Products/categories are not found despite existing.
Check:
b7d2554b0ce847cd82f3ac9bd1c0dfca)Symptom: Custom styles are not recognized or validation errors occur.
Check:
node -e "JSON.parse(require('fs').readFileSync('content-profiles.json','utf8'))"defaultProfile reference an existing profile?categoryMapping values reference existing profiles?tonality, addressing, structure, targetAudience, exampleIntro)?addressing exactly "du" or "Sie" (case-sensitive)?src/
├── index.ts # MCP Server Entry Point + Tool Dispatch
├── bootstrap.ts # Dependency Injection Setup
├── config/
│ ├── Configuration.ts # .env Loading and Validation
│ ├── ContentProfilesSchema.ts # Zod schema for content-profiles.json
│ ├── ContentProfilesLoader.ts # File search and loading with fallback
│ └── ContentProfilesDefaults.ts # Built-in default profiles
├── core/
│ ├── domain/ # Pure Domain Entities (13 files)
│ └── services/ # Business Logic (12 services + tests)
├── application/
│ └── schemas/ # Zod Input Validation (11 schema files)
├── infrastructure/
│ ├── shopware/ # OAuth2 Auth + HTTP Client
│ ├── cache/ # InMemory Cache with TTL
│ └── logging/ # stderr Logging (MCP-compliant)
├── tools/
│ ├── definitions.ts # All 43 tool definitions
│ └── handlers/ # Tool handlers (11 files)
└── test/ # Test fixtures and setup (MSW)
| Property | Value |
|---|---|
| Transport | stdio (stdin/stdout) |
| MCP Version | 1.0 |
| Serialization | JSON |
| Logging | stderr (no stdout contamination) |
| Tool Count | 43 |
| Data | TTL | Rationale |
|---|---|---|
| Categories | 1 hour | Rarely change |
| Properties | 1 hour | Rarely change |
| Manufacturers | 1 hour | Rarely change |
| Snippets | 5 minutes | May change |
| Individual Products | 5 minutes | Moderate change rate |
| Mail Templates | 10 minutes | Rarely changed |
| Orders | No cache | Always needs to be current |
| Media | No cache | Freshness important |
| Content Profiles | Once at startup | Only updated on restart |
The in-memory cache has a maximum of 500 entries and performs auto-pruning of expired entries every 60 seconds.
What is MCP?
MCP (Model Context Protocol) is an open standard by Anthropic that enables AI models like Claude to interact with external services. The MCP server acts as a bridge between Claude and the Shopware Admin API.
Does the server work with Shopware 5?
No. The server uses the Shopware 6 Admin API, which is fundamentally different from Shopware 5. A port is not planned.
Which Node.js version do I need?
At least Node.js 20. The CI pipeline tests against Node.js 20 and 22.
Can Claude modify orders with this?
No. The order tools are intentionally read-only. Orders can only be read and statistically analyzed. Order modifications should be done manually in the Shopware Admin.
What happens when an API error occurs?
The server returns structured error messages with an error code, description and a suggestion. For temporary errors (rate limiting, token expiry), an automatic retry is performed.
Does the server work with Claude Desktop?
Yes. Configuration is done through the claude_desktop_config.json (see Configuration section). The server uses stdio transport and is compatible with all MCP-compatible clients.
Are products immediately visible in the shop?
No. Products are always created as inactive. You must explicitly activate them via product_set_active after reviewing them.
How does content style detection work?
The server reads the product's category breadcrumbs and matches against the configured categoryMapping. The mapping and the profiles themselves can be customized via a content-profiles.json file. Without a configuration file, the built-in default profiles (Creative + Software) are used. The style can also be manually overridden via the style parameter.
How do I customize content profiles?
Copy content-profiles.example.json to content-profiles.json, customize the profiles and restart the MCP server. You can define as many profiles as needed and map categories to them. Details at Configuring Content Profiles.
Do I need to create a content-profiles.json?
No. Without a configuration file, the server uses the built-in default profiles (Creative and Software). The file is only needed if you require custom styles, tonalities or category mappings.
MIT License - License text on GitHub
Repository: github.com/markus-michalski/claude-mcp-shopwareadmin
Issues: GitHub Issues
See CHANGELOG.md on GitHub for the complete change history.