{
  "markdown": "<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/brand/banner-dark.svg\">\n    <img src=\"https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/brand/banner-light.svg\" alt=\"shopware-mcp: the MCP server for Shopware 6\" width=\"100%\">\n  </picture>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/shopware-mcp\"><img src=\"https://img.shields.io/npm/v/shopware-mcp?color=cb3837&logo=npm&logoColor=white\" alt=\"npm\"></a>\n  <a href=\"https://github.com/bnymnDev/shopware-mcp/actions/workflows/ci.yml\"><img src=\"https://github.com/bnymnDev/shopware-mcp/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"https://github.com/bnymnDev/shopware-mcp/actions/workflows/e2e.yml\"><img src=\"https://github.com/bnymnDev/shopware-mcp/actions/workflows/e2e.yml/badge.svg\" alt=\"nightly e2e against a real Shopware\"></a>\n  <a href=\"https://registry.modelcontextprotocol.io\"><img src=\"https://img.shields.io/badge/MCP_registry-io.github.bnymnDev%2Fshopware--mcp-0b7bd6\" alt=\"MCP registry\"></a>\n  <img src=\"https://img.shields.io/node/v/shopware-mcp?color=339933&logo=node.js&logoColor=white\" alt=\"node\">\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-blue\" alt=\"MIT\"></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"#introducing-shopware-mcp\">Why</a> ·\n  <a href=\"#see-it-work\">Demo</a> ·\n  <a href=\"#60-seconds\">Install</a> ·\n  <a href=\"#tools\">Tools</a> ·\n  <a href=\"#safety\">Safety</a> ·\n  <a href=\"#documentation\">Docs</a> ·\n  <a href=\"README.de.md\">Deutsch</a>\n</p>\n\n---\n\n## Introducing shopware-mcp\n\nA Shopware 6 shop is about two hundred entities behind one Admin API. Ask an\nassistant \"is everything okay with the shop?\" and the honest answer takes seven\nsearches with Criteria filters, three state machines by their technical names,\na couple of aggregations, and an OAuth token it must never repeat back to you.\nWire a model straight to that API and it gets all of it, including the right to\n`PATCH` a price because a prompt said so.\n\nThe Model Context Protocol turned \"give the model real tools\" into a one-line\nconfig change. It says nothing about what a good tool for a *shop* looks like:\nwhich of the two hundred entities matter on a Tuesday morning, what \"stuck\norder\" means, or that a stock correction should be shown before it is sent.\n\n**shopware-mcp is that layer.** One small server that speaks MCP to the host\nand the Admin API to the shop, and knows Shopware well enough to answer in one\ncall what used to take an afternoon in the admin:\n\n| | |\n|---|---|\n| **Curated tools** | Products, orders, customers, categories, promotions, plugins, stock, sales channels: sixteen tools that return compact JSON with exact totals, descriptions written for a model, and Shopware's own Criteria filters. No invented query language. |\n| **An audit** | `shop_audit` runs eleven checks in one call: paid orders that never shipped, unpaid orders going stale, shipped orders never completed, products out of stock, without a cover or without a delivery time, promotions past their end date, channels in maintenance, storefronts missing a legal page, extensions with updates waiting, and which EU duties look covered by an installed extension. Prioritised, with samples and a hint per finding. |\n| **A report** | `sales_report` asks Shopware to aggregate: gross, net, average order, revenue per currency and channel, orders per state, a day/week/month timeline, the top products and, on request, the change against the period before. The figures were checked against SQL on the same database. |\n| **An escape hatch** | `entity_schema` describes any of the 200+ entities, a plugin's custom entities included, and `entity_search` queries them with the same filters. Entities that hold credentials are refused, secrets in the rest are scrubbed. |\n| **A brake** | Read-only unless you start it with `--allow-write`. Even then every write is a dry run that shows the exact request first, and a write budget can cap how many real writes a process may make. Ship, mark paid, remind, refund, correct stock, note, generate a document: eight narrow writes, nothing else. Secrets never appear in output, logs or errors. |\n\n<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/brand/architecture-dark.svg\">\n    <img src=\"https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/brand/architecture-light.svg\" alt=\"An MCP host on the left, shopware-mcp in the middle, the Shopware 6 Admin API on the right. Tool calls flow right, compact JSON flows back.\" width=\"100%\">\n  </picture>\n</p>\n\nShops are not identical, so the tool list is not either: at startup the server\nlooks up which extensions are installed and registers extra tools for the ones\nit knows. A plain shop gets the core set. A shop with more plugins gets a bigger\nagent, without configuration.\n\n---\n\n## See it work\n\nEvery recording on this page is real output from the server against a Shopware\n6.7.13 test shop with generated demo data, replayed from the transcripts in\n[`docs/demo/`](docs/demo). Tool calls and results are verbatim, shortened to\nfit the screen. The prose is what an MCP host says with them.\n\n**One question, nine checks.** Three paid orders are still waiting for shipment,\nthe storefront is in maintenance, a summer promotion outlived August. The\nanswer names order numbers and amounts, and offers the safe next step.\n\n![shop_audit: the agent asks one question, the tool returns prioritised findings with samples, the agent summarises them](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/demo/audit.svg)\n\n**Numbers the shop computed itself.** Totals, channels, states, a monthly\ntimeline and the top product for eight months, from one call. No order was\npaged through; Shopware's aggregations did the work.\n\n![sales_report: totals, revenue by channel, orders by state, a monthly timeline and top products](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/demo/report.svg)\n\n**No tool for that? There is a schema for that.** Manufacturers have no\ndedicated tool. The agent reads the entity's schema, spots `mediaId`, and\nfilters on it. The same path reaches every other entity, custom ones included.\n\n![entity_schema then entity_search: the agent discovers the mediaId field and finds 27 manufacturers without a logo](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/demo/anything.svg)\n\n**Writes show their hand first.** With `--allow-write`, a stock correction\ncomes back as the request it *would* send. Only an explicit `dryRun: false`\ntouches the shop, and the result is re-read from Shopware.\n\n![stock_set: a dry run returns the PATCH it would send, the agent asks, the real write follows and returns the re-read product](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/demo/write.svg)\n\n**A shop with more plugins gets a bigger agent.** The core tools are ready\nimmediately. The extension lookup finishes in the background, four tools appear,\nthe host is told to refresh its list, and a compliance question has an answer.\n\n![Plugin-aware tools: tools/list grows from 16 to 20 after the extension lookup, then merqo_health answers a compliance question](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/demo/plugins.svg)\n\n**Know before the agent finds out.** `shopware-mcp doctor` probes what the integration may read, reads its role for the write privileges where it can, and names the missing one per tool. An administrator gets a wall of ticks; a support-desk role gets told exactly what to grant.\n\n![shopware-mcp doctor: every tool ready for an administrator integration, then a support-desk integration with customers blocked and the privilege to grant](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/demo/doctor.svg)\n\n<details>\n<summary><b>Screenshots from the MCP Inspector against the same shop</b></summary>\n<br>\n\n![shop_audit result in the MCP Inspector](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/screenshots/shop-audit.png)\n\n![sales_report result in the MCP Inspector](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/screenshots/sales-report.png)\n\n![The tool list with plugin-aware tools registered](https://raw.githubusercontent.com/bnymnDev/shopware-mcp/main/docs/screenshots/plugin-aware-tools.png)\n\n</details>\n\n---\n\n## What's in the box\n\n| | |\n|---|---|\n| **Sixteen curated tools** | `products_search`, `orders_get`, `customers_search`, `stock_get`, `promotions_list`, `plugins_list` and friends. Each takes `{ term?, filter?, sort?, page?, limit?, fields? }` and returns `{ total, page, limit, items }`. |\n| **Health audit** | `shop_audit` with tunable thresholds (`stuckOrderDays`, `lowStockThreshold`, `maxItems`). Eleven checks including legal pages per storefront and delivery times, prioritised findings, a hint per finding, and an EU duty overview that names duties and deadlines, never products. |\n| **Sales report** | `sales_report` for any period, by day, week or month, optionally per sales channel, cancelled orders excluded. `compareWithPrevious` adds the preceding period and the change in orders, revenue and average order value. Top products resolved by exact product id so ties cannot skew revenue. |\n| **Any entity** | `entity_schema` lists all entities or describes one: fields, types, flags, associations. `entity_search` queries it. Long text values are truncated, secrets scrubbed, credential entities refused. |\n| **Plugin-aware tools** | The server detects installed, active extensions and adds tools for the ones it knows. First pack: [Merqo](https://github.com/bnymnDev/merqo). Off with `--no-extensions`. |\n| **Documents** | `order_documents_list`, `order_document_create` (invoice, delivery note, credit note, cancellation, by Shopware's own generator) and `document_download`, which hands the PDF to the host as an embedded resource while the model sees only the metadata. |\n| **Guarded writes** | `stock_set`, `product_update`, `order_state_transition`, `order_delivery_transition` (ship, with tracking codes), `order_transaction_transition` (mark paid, remind, refund), `order_note` (internal comment), `order_document_create`, `promotion_toggle`. Registered only with `--allow-write`, `dryRun: true` by default, the re-fetched entity on a real write. `SHOPWARE_MCP_MAX_WRITES` caps real writes per process. |\n| **Doctor and init** | `shopware-mcp doctor` says per tool whether this integration can use it and which privilege is missing. `shopware-mcp init` tests the credentials and prints or writes the config for Claude Desktop, Claude Code, Cursor, VS Code or Zed. |\n| **Resources and prompts** | `shopware://shop`, `shopware://sales-channels`, the templates `shopware://order/{orderNumber}` and `shopware://product/{productNumber}` so a host can attach a record as context, and three prompts: `order_summary`, `low_stock_report` and `weekly_review`. |\n| **Shopware's vocabulary** | Filters are Shopware Criteria filters (`equals`, `contains`, `range`, `equalsAny`) on Shopware field paths, including associations like `manufacturer.name`. State names are the technical names you already know. |\n| **Portable schemas** | Every tool schema is checked to avoid constructs that some MCP clients misread, so the same server works in every host. |\n| **A solid client** | OAuth client credentials with early token refresh, one retry on 401 and on 429/5xx with `Retry-After`, a per-request timeout, exact totals, inheritance and language headers, a cached entity schema. |\n| **Two transports** | stdio for desktop hosts, stateless Streamable HTTP for everything else, with an optional bearer token. |\n| **Packaged four ways** | npm with build provenance, a Docker image on GHCR for amd64 and arm64, a one-click `.mcpb` bundle for Claude Desktop that asks for the credentials and a write budget, and a listing in the official MCP registry. |\n\n---\n\n## Who it is for\n\n- **You run a shop** and want to ask it questions instead of clicking through the admin. Stuck orders, low stock, last month's numbers, one prompt each.\n- **You run an agency** and look after many shops. The core here covers one shop per server; the multi-shop, audited, hosted version is what the author builds for clients (see [Open core](#open-core)).\n- **You build Shopware plugins** and want your custom entities reachable by an agent today, and your own tools registered tomorrow. `entity_search` does the first; one file under `src/extensions/` does the second.\n- **You build agents** and want an MCP server that behaves: compact output, honest totals, dry runs, no surprises in the schema.\n\n---\n\n## 60 seconds\n\n**1.** Create an Integration in your Shopware admin: *Settings → System → Integrations → Add integration*. Copy the access key ID and the secret; the secret is shown once. For a dev shop tick *Administrator*, for production give it a read role (see [permissions](docs/self-hosting.md#shopware-permissions)).\n\n**2.** Let the wizard test the credentials and write the host config for you:\n\n```bash\nnpx shopware-mcp init                  # asks for URL, key and secret, tests them, prints the config\nnpx shopware-mcp init --for claude-desktop --write   # or merges it into the host's config file\nnpx shopware-mcp doctor                # which tools can this integration use, and what is missing\n```\n\nOr run the server by hand:\n\n```bash\nexport SHOPWARE_URL=https://shop.example.com\nexport SHOPWARE_CLIENT_ID=SWIA...\nexport SHOPWARE_CLIENT_SECRET=...\n\nnpx shopware-mcp                       # stdio (default)\nnpx shopware-mcp --http --port 3333    # Streamable HTTP on http://127.0.0.1:3333/mcp\nnpx shopware-mcp --allow-write         # also register the guarded write tools\n```\n\n**3.** Connect a host (or let `init --write` do it):\n\n<details>\n<summary><b>Claude Desktop</b></summary>\n<br>\n\nDownload `shopware-mcp.mcpb` from the [latest release](https://github.com/bnymnDev/shopware-mcp/releases/latest) and double-click it, or add this to `claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"shopware\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"shopware-mcp\"],\n      \"env\": {\n        \"SHOPWARE_URL\": \"https://shop.example.com\",\n        \"SHOPWARE_CLIENT_ID\": \"SWIA...\",\n        \"SHOPWARE_CLIENT_SECRET\": \"...\"\n      }\n    }\n  }\n}\n```\n\n</details>\n\n<details>\n<summary><b>Claude Code</b></summary>\n<br>\n\n```bash\nclaude mcp add shopware \\\n  -e SHOPWARE_URL=https://shop.example.com \\\n  -e SHOPWARE_CLIENT_ID=SWIA... \\\n  -e SHOPWARE_CLIENT_SECRET=... \\\n  -- npx -y shopware-mcp\n```\n\n</details>\n\n<details>\n<summary><b>Cursor, VS Code, Zed, Windsurf and other stdio hosts</b></summary>\n<br>\n\nThey all take the same three fields. Cursor reads `.cursor/mcp.json`, VS Code `.vscode/mcp.json` (under `servers` instead of `mcpServers`), Zed its `context_servers` block:\n\n```json\n{\n  \"mcpServers\": {\n    \"shopware\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"shopware-mcp\"],\n      \"env\": {\n        \"SHOPWARE_URL\": \"https://shop.example.com\",\n        \"SHOPWARE_CLIENT_ID\": \"SWIA...\",\n        \"SHOPWARE_CLIENT_SECRET\": \"...\"\n      }\n    }\n  }\n}\n```\n\nHosts that read the [official MCP registry](https://registry.modelcontextprotocol.io) find it as `io.github.bnymnDev/shopware-mcp`.\n\n</details>\n\n<details>\n<summary><b>Docker and HTTP hosts</b></summary>\n<br>\n\n```bash\ndocker run --rm -p 3333:3333 \\\n  -e SHOPWARE_URL=https://shop.example.com \\\n  -e SHOPWARE_CLIENT_ID=SWIA... -e SHOPWARE_CLIENT_SECRET=... \\\n  ghcr.io/bnymndev/shopware-mcp\n```\n\nThe image serves Streamable HTTP on `http://127.0.0.1:3333/mcp`. Point any HTTP-capable host at that URL. Add `-e SHOPWARE_MCP_HTTP_TOKEN=<random secret>` and the endpoint requires `Authorization: Bearer <secret>`; without a token, keep it on localhost or behind a proxy that authenticates ([self-hosting notes](docs/self-hosting.md)).\n\n</details>\n\n**4.** Ask. The first useful question is usually *\"Is everything okay with the shop?\"*\n\n---\n\n## Ask it anything\n\n| You say | The agent calls |\n|---|---|\n| \"Is everything okay with the shop?\" | `shop_audit` |\n| \"How did we do in August?\" | `sales_report { from, to, interval: \"week\" }` |\n| \"Which products are below 5 in stock?\" | `products_search` with a `range` filter, or the `low_stock_report` prompt |\n| \"Summarise order 10042 for a support reply.\" | `orders_get`, or the `order_summary` prompt |\n| \"Which customers ordered more than ten times?\" | `customers_search` with a `range` filter on `orderCount` |\n| \"Is the PayPal plugin up to date?\" | `plugins_list` |\n| \"Which manufacturers have no logo?\" | `entity_schema` then `entity_search` on `product_manufacturer` |\n| \"Set the stock of SW10084 to 40.\" | `stock_set`, dry run first, then for real |\n| \"Order 10042 shipped with DHL, tracking 00340434.\" | `order_delivery_transition { transition: \"ship\", trackingCodes }` |\n| \"The bank transfer for 10038 arrived.\" | `order_transaction_transition { transition: \"paid\" }` |\n| \"How was last week compared to the week before?\" | `sales_report { compareWithPrevious: true }`, or the `weekly_review` prompt |\n| \"Send me the invoice for 10042.\" | `order_documents_list`, then `document_download` returns the PDF |\n| \"Note on 10042: customer called, ships Monday.\" | `order_note` |\n| \"Which of my tools will fail with this integration?\" | not a tool: `npx shopware-mcp doctor` |\n\n---\n\n## Filters, in one screen\n\nEvery search tool takes the same `filter` array, and every entry is a Shopware Criteria filter:\n\n```json\n{ \"type\": \"equals\",    \"field\": \"active\",                                    \"value\": true }\n{ \"type\": \"range\",     \"field\": \"stock\",                                     \"value\": { \"lt\": 5 } }\n{ \"type\": \"range\",     \"field\": \"orderDateTime\",                             \"value\": { \"gte\": \"2026-06-01\" } }\n{ \"type\": \"equals\",    \"field\": \"transactions.stateMachineState.technicalName\", \"value\": \"paid\" }\n{ \"type\": \"contains\",  \"field\": \"name\",                                      \"value\": \"shirt\" }\n{ \"type\": \"equalsAny\", \"field\": \"id\",                                        \"value\": [\"…\", \"…\"] }\n{ \"type\": \"equals\",    \"field\": \"manufacturer.name\",                         \"value\": \"Acme\" }\n```\n\nAnything you can filter in the Admin API works here too, associations included.\nNeed a raw field that the compact output leaves out, such as `customFields`,\n`ean` or `weight`? Pass `fields: [\"customFields\", \"ean\"]` and it is added to\nevery item. Reading a shop in another language? Set `SHOPWARE_LANGUAGE_ID`.\nThe full [cheat sheet](docs/quickstart.md#filters-cheat-sheet) has more.\n\n---\n\n## Tools\n\n<!-- TOOLS:START -->\n| Tool | Access | Purpose |\n|---|---|---|\n| [`shop_info`](docs/tools.md#shop_info) | read | Shop info |\n| [`sales_channels_list`](docs/tools.md#sales_channels_list) | read | List sales channels |\n| [`products_search`](docs/tools.md#products_search) | read | Search products |\n| [`products_get`](docs/tools.md#products_get) | read | Get product |\n| [`orders_search`](docs/tools.md#orders_search) | read | Search orders |\n| [`orders_get`](docs/tools.md#orders_get) | read | Get order |\n| [`order_documents_list`](docs/tools.md#order_documents_list) | read | List order documents |\n| [`document_download`](docs/tools.md#document_download) | read | Download document PDF |\n| [`customers_search`](docs/tools.md#customers_search) | read | Search customers |\n| [`customers_get`](docs/tools.md#customers_get) | read | Get customer |\n| [`categories_list`](docs/tools.md#categories_list) | read | List categories |\n| [`promotions_list`](docs/tools.md#promotions_list) | read | List promotions |\n| [`plugins_list`](docs/tools.md#plugins_list) | read | List plugins and apps |\n| [`stock_get`](docs/tools.md#stock_get) | read | Get stock |\n| [`sales_report`](docs/tools.md#sales_report) | read | Sales report |\n| [`shop_audit`](docs/tools.md#shop_audit) | read | Shop health audit |\n| [`entity_schema`](docs/tools.md#entity_schema) | read | Entity schema |\n| [`entity_search`](docs/tools.md#entity_search) | read | Search any entity |\n| [`stock_set`](docs/tools.md#stock_set) | write (guarded) | Set stock (guarded) |\n| [`product_update`](docs/tools.md#product_update) | write (guarded) | Update product (guarded) |\n| [`order_state_transition`](docs/tools.md#order_state_transition) | write (guarded) | Transition order state (guarded) |\n| [`order_delivery_transition`](docs/tools.md#order_delivery_transition) | write (guarded) | Transition delivery state (guarded) |\n| [`order_transaction_transition`](docs/tools.md#order_transaction_transition) | write (guarded) | Transition payment state (guarded) |\n| [`order_note`](docs/tools.md#order_note) | write (guarded) | Add internal order note (guarded) |\n| [`order_document_create`](docs/tools.md#order_document_create) | write (guarded) | Create order document (guarded) |\n| [`promotion_toggle`](docs/tools.md#promotion_toggle) | write (guarded) | Toggle promotion (guarded) |\n<!-- TOOLS:END -->\n\nEvery parameter of every tool: [docs/tools.md](docs/tools.md). Searches return\n`{ total, page, limit, items }` with exact totals, `limit` is capped at 50, and\nerrors come back as `{ error: { status, code, detail } }` so the model can\nreact instead of guessing.\n\nResources: `shopware://shop`, `shopware://sales-channels`, `shopware://order/{orderNumber}`,\n`shopware://product/{productNumber}`. Prompts: `order_summary`, `low_stock_report`, `weekly_review`.\n\n### Plugin-aware tools\n\nAt startup the server asks the shop which extensions are installed and active,\nin the background, and registers extra tools for the ones it knows. A shop that\ndoes not answer simply keeps the core tools. `--no-extensions` turns the whole\nmechanism off.\n\nToday one suite is supported, [Merqo](https://github.com/bnymnDev/merqo), which\nadds `merqo_health`, `merqo_einvoice_inbox`, `merqo_returns_search` and\n`merqo_abandoned_carts`. Shops without it never see those tools, and nothing in\nthe core tools changes either way. Support for another vendor's extensions is\none file under `src/extensions/`; pull requests are welcome.\n\n---\n\n## Safety\n\n- **Read-only by default.** Without `--allow-write` (or `SHOPWARE_MCP_ALLOW_WRITE=true`) the write tools are not registered. An agent cannot discover what it cannot call.\n- **Every write is a dry run first.** `stock_set`, `product_update`, `order_state_transition`, `order_delivery_transition`, `order_transaction_transition`, `order_note`, `order_document_create` and `promotion_toggle` default to `dryRun: true` and return `{ dryRun: true, wouldSend: { method, url, body } }`, a list when one call needs several requests. A real write returns the re-fetched entity.\n- **A write budget.** `SHOPWARE_MCP_MAX_WRITES=20` refuses the twenty-first real write of a process with `WRITE_BUDGET_EXHAUSTED`; dry runs stay free. No prompt can lift it.\n- **Narrow writes.** `product_update` touches name, description, active and one currency's price. The transition tools only move state machines; nothing moves money. Documents come from Shopware's own generator and are never sent by this server. Nothing else is writable.\n- **Scrubbed reads.** `entity_search` strips passwords, keys, tokens and hashes from every payload and refuses entities that exist to hold credentials or system internals: users, integrations, ACL roles, apps, system config.\n- **No secrets anywhere.** Credentials never appear in output, logs or error messages. Logs go to stderr only, at `error` level unless you ask for more.\n- **No telemetry.** The server talks to your shop and to your host. Nothing else.\n- **HTTP transport.** Set `SHOPWARE_MCP_HTTP_TOKEN` and every call to `/mcp` needs that bearer token, compared in constant time. Without it, bind to localhost (the default) or put it behind a reverse proxy that authenticates; the server warns when it is reachable further without a token.\n- **Requests time out.** A shop that stops answering costs one request 30 seconds (`SHOPWARE_MCP_TIMEOUT_MS`), not the whole session.\n\nFound something? See [SECURITY.md](SECURITY.md).\n\n---\n\n## Configuration\n\n| Variable | Required | Notes |\n|---|---|---|\n| `SHOPWARE_URL` | yes | Shop base URL, e.g. `https://shop.example.com` (trailing slash is stripped) |\n| `SHOPWARE_CLIENT_ID` | yes | Integration access key ID |\n| `SHOPWARE_CLIENT_SECRET` | yes | Integration secret access key |\n| `SHOPWARE_MCP_ALLOW_WRITE` | no | `true` registers the write tools. Default: off |\n| `SHOPWARE_MCP_MAX_WRITES` | no | Real writes one process may perform in total; `0` (default) means no cap |\n| `SHOPWARE_MCP_DEFAULT_LIMIT` | no | Default page size for search tools (default 20, max 50) |\n| `SHOPWARE_MCP_EXTENSIONS` | no | `false` disables plugin-aware tools and the extension lookup at startup |\n| `SHOPWARE_LANGUAGE_ID` | no | Language UUID for translated fields (`sw-language-id`). Default: shop default language |\n| `SHOPWARE_MCP_TIMEOUT_MS` | no | Per-request timeout for the Admin API in milliseconds (default 30000, 1000 to 600000) |\n| `SHOPWARE_MCP_HTTP_TOKEN` | no | Bearer token the HTTP transport requires on `/mcp` (at least 16 characters). Default: none |\n| `SHOPWARE_MCP_LOG_LEVEL` | no | `error` (default), `warn`, `info`, `debug`. Logs go to stderr only |\n\nCLI flags override the environment: `--allow-write`, `--max-writes <n>`, `--no-extensions`, `--http`, `--port <n>`, `--host <addr>`, `--log-level <level>`. Commands: `doctor [--json]` and `init [--for <host>] [--write]`.\n\nThe Integration needs read permissions on the entities you query and write\npermissions on product, order and promotion for the write tools. *Administrator*\nis the quick path for a dev shop; use a dedicated role in production\n([which permissions](docs/self-hosting.md#shopware-permissions)).\n\n---\n\n## Design principles\n\n1. **Shopware's vocabulary, not ours.** Filters, field paths, state names and entity names are Shopware's. A tool call reads like the Admin API request it becomes, and a Shopware developer needs no second dictionary.\n2. **Compact by default, complete on request.** Items carry what a model needs to reason and page. Raw fields come with `fields`, more rows with `page`, and long text is truncated rather than dumped.\n3. **Reading is free, writing is explicit.** Write tools exist only when asked for, default to a dry run, and return the exact request. The model sees the consequence before the shop does.\n4. **Let the shop do the maths.** Totals, timelines and top products are Shopware aggregations with exact counts, not client-side sums over pages.\n5. **Vendor-neutral core.** Extension packs live in their own files, are registered only when the shop has the extension, and never change how the core tools behave. No telemetry, no phone-home.\n\nThe reasoning behind individual choices is in [docs/decisions.md](docs/decisions.md).\n\n---\n\n## Documentation\n\n| Document | What is in it |\n|---|---|\n| [docs/quickstart.md](docs/quickstart.md) | Integration, first run, host configs, example questions, the filters cheat sheet |\n| [docs/tools.md](docs/tools.md) | Every tool with every parameter, generated from the code |\n| [docs/self-hosting.md](docs/self-hosting.md) | Transports, Docker, reverse proxies, Shopware permissions, operations |\n| [docs/decisions.md](docs/decisions.md) | Design decisions and the reasoning behind each |\n| [CONTRIBUTING.md](CONTRIBUTING.md) | Setup, ground rules, end-to-end tests, releasing |\n| [SECURITY.md](SECURITY.md) | What to report and where |\n| [CHANGELOG.md](CHANGELOG.md) | What changed in each version |\n\n---\n\n## Open core\n\nEverything in this repository is MIT and stays that way. It covers one shop, one operator, interactive use.\n\nThe same author builds [Merqo](https://github.com/bnymnDev/merqo), a commercial suite of Shopware\nextensions for EU compliance and daily operations. This server detects them and adds matching\ntools, but it never requires them, and the core tools behave the same either way.\n\nAgencies and merchants running this at scale usually need more, and that is what I build and operate for clients:\n\n- **Multi-shop**: one MCP endpoint that routes to dozens of shops with per-shop credentials and permissions\n- **Hosted with audit trail**: every tool call logged with who, what and when, role-based access, SLA\n- **Bulk operations and migrations**: mass price and stock updates, catalogue imports, safe rollbacks\n- **Custom agents and Shopware plugins**: workflows tailored to your ERP, PIM or support desk\n\nInterested? Open an issue with the `consulting` label or reach out via [github.com/bnymnDev](https://github.com/bnymnDev). Using shopware-mcp in production and want it to stay maintained? [Sponsoring](https://github.com/sponsors/bnymnDev) helps.\n\n---\n\n## Building from source\n\n```bash\npnpm install\npnpm dev          # stdio server via tsx\npnpm test         # vitest + msw-mocked Admin API\npnpm build        # tsup → dist/ (npm) and dist/bundle/ (self-contained)\npnpm pack:mcpb    # Claude Desktop bundle → shopware-mcp.mcpb\npnpm inspect      # MCP Inspector against dist/\npnpm docs:tools   # regenerate docs/tools.md and the tool tables in both READMEs\npnpm docs:demos   # re-render the recordings in docs/demo/ from their transcripts\n```\n\nEnd-to-end tests against a real Shopware (`dockware/dev`, or any shop you point them at) run with `pnpm test:e2e`; see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## Status\n\nv0.3. Everything on this page is implemented, covered by unit tests against\nmocked Admin API responses, and exercised nightly end-to-end against a real\nShopware. The recordings above come from Shopware 6.7.13; 6.6 is supported too.\n\nNot in it, on purpose: user management for the HTTP transport (one static\ntoken, or a proxy), multi-shop routing and audit trails (the commercial part),\nand write tools beyond the eight that a support desk needs on a normal day.\n\nIdeas that fit: more extension packs, better error hints for common Shopware\nACL problems, a `products_search` example gallery. The [good first\nissues](https://github.com/bnymnDev/shopware-mcp/labels/good%20first%20issue)\nare a fine place to start.\n\n## License\n\n[MIT](LICENSE)\n\n<p align=\"center\"><sub>If shopware-mcp answered a question your admin could not, a star helps the next shop find it.</sub></p>\n",
  "bytes": 30286,
  "sha": "9f60460af227e706a6799ad91a348016bc88d0fb150ecfcc194ae87f53205720",
  "repo_slug": "bnymndev/shopware-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_bnymndev_shopware_mcp_625ace7e/readme"
}