From 5cf5c42d0da282ac29ed87804025935b4b6d6d4f Mon Sep 17 00:00:00 2001 From: dfrancos-hub Date: Thu, 17 Sep 2026 15:23:35 +0200 Subject: [PATCH 01/16] docs: add mcp tool copilot approval flow --- .../tools/mcp-server/copilot-tool-approval.md | 262 ++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 products/tools/mcp-server/copilot-tool-approval.md diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md new file mode 100644 index 000000000..0af3ff116 --- /dev/null +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -0,0 +1,262 @@ +--- +nav: + title: Copilot tool approval + position: 40 + +--- + +# Making Your MCP Tools Work With Shopware Copilot + +Shopware Copilot can use the MCP tools that your plugin or app registers on a merchant's shop. This guide explains how Copilot discovers those tools and describes the `dryRun` contract a tool must follow so that the merchant gets an approval step before the tool changes data. + +::: info +This functionality is available starting with Shopware 6.7. The MCP server is experimental. +::: + +::: warning +The `dryRun` contract is a temporary solution. A future Shopware release is expected to replace it with standard MCP tool annotations. Treat this guide as a workaround until the stable solution is in place. +::: + +## Prerequisites + +This guide assumes that you know how to extend the Shopware MCP server. For more information, see [MCP Support in Shopware](../index.md). + +You need the following: + +* A Shopware 6.7 installation with the MCP server enabled +* A plugin or app that registers at least one MCP tool +* Access to Shopware Copilot in the Administration + +## Summary + +You don't need to register your tools with Copilot. Copilot finds them through the shop's own MCP catalog. + +Copilot decides how to call a tool by inspecting its input schema: + +* A tool whose schema declares a boolean `dryRun` parameter is treated as a tool that changes data. Copilot first calls it with `dryRun: true` to obtain a preview, shows the merchant an approval card in the UI, and calls it with `dryRun: false` only after the merchant approves. +* A tool without `dryRun` is treated as read-only and is called directly, even if the tool performs write operations. + +If your tool has side effects, declare `dryRun`. This is the whole contract. + +## How Copilot uses your tools + +Copilot connects to the shop's MCP endpoint with the merchant's permissions. Your tools aren't visible to the AI model by default. Shopware groups tools into toolsets using the group you declare, and Copilot enables a toolset only when the conversation needs it. + +Two things matter for your tool to be picked at all: + +* **Tool description** - Copilot searches descriptions to find a matching tool. Write the description for a reader who doesn't know your extension: what the tool does, when to use it, and what it returns. +* **Group name** - Tools that share a `McpToolGroup` become one toolset. Use a short, stable, product-specific name such as `b2b-quotes` rather than a generic one like `tools`. + +Once a toolset is enabled, Copilot calls your tool through its gateway. The gateway validates the call, applies the approval rules described below, and forwards the call to the shop. Your tool runs inside Shopware exactly as it does for any other MCP client. + +## The contract + +The contract consists of four rules. + +### R1 - Declare dryRun on tools with side effects + +A tool that creates, updates, deletes, or otherwise changes shop data must declare a boolean input parameter named `dryRun` with a default of `true`. The name is case-sensitive and must appear as a top-level property in the tool's input schema. + +### R2 - Preview without changing anything + +When called with `dryRun: true`, the tool must not change anything. It validates the arguments completely and returns a preview that describes what the real call does. The preview is what the merchant sees on the approval card in the Copilot chat. + +If validation fails, return an error at this stage. The merchant is then never asked to approve a change that can't run. + +### R3 - Commit from the arguments alone + +When called with `dryRun: false`, the tool performs the change and returns the result, including the identifiers of created or modified records. The commit call arrives with the same arguments as the preview call, apart from `dryRun`. Don't depend on any state from the preview call. + +### R4 - Keep read-only tools free of dryRun + +A tool that only reads data must not declare `dryRun`. Copilot calls such tools directly while answering a question. Adding `dryRun` to a read tool forces an unnecessary approval step and confuses the model. + +::: danger +A tool with side effects but without a `dryRun` parameter is indistinguishable from a read tool. Copilot calls it directly, without showing the merchant an approval card. Review every tool you publish against rule R1 before release. +::: + +### Behavior matrix + +The following table summarizes how Copilot treats each tool shape: + +| Tool shape | How Copilot calls it | Merchant approval | +| :--- | :--- | :--- | +| No `dryRun` in schema | Directly, during the conversation | Not shown | +| Has `dryRun`, called with `true` | Directly, to obtain the preview | Not needed | +| Has `dryRun`, called with `false` | Only after the merchant approves the preview | Required | +| Has side effects, no `dryRun` | Directly, treated as read-only | Bypassed | + +## What the merchant sees + +A change request passes through three steps: + +1. **Preview** - Copilot calls your tool with `dryRun: true`. Your tool validates the request and returns a description of the intended change. Nothing is written. +2. **Approval** - Copilot renders your preview as a change request in the Administration. The merchant approves or rejects it. +3. **Commit** - Copilot calls your tool with `dryRun: false` and the same arguments as in the first step. Your tool performs the change and returns the result, which Copilot reports back to the merchant. + +The following diagram shows the flow between the merchant, Copilot, and your tool: + +```mermaid +sequenceDiagram + participant M as Merchant + participant C as Copilot + participant T as Your tool + + M->>C: Asks for a change in plain language + C->>T: Call with dryRun: true + T-->>C: Preview (no writes) + C->>M: Shows approval card + M->>C: Approves + C->>T: Call with dryRun: false, same arguments + T-->>C: Result with record identifiers + C->>M: Reports the result +``` + +The preview and commit steps happen in separate MCP sessions, possibly minutes apart. Copilot re-enables your toolset before the commit call. Your tool must compute everything it needs from the arguments alone. + +## Implement a write tool in a plugin + +The example below is a complete write tool. It extends `McpToolResponse`, which every MCP tool must do, and follows rules R1 to R3. + +```php +contextProvider->getContext(); + + if ($error = $this->requirePrivilege($context, 'promotion:update')) { + return $error; + } + + $promotion = $this->promotions->find($promotionId, $context); + + if ($promotion === null) { + return $this->error('Promotion not found.'); + } + + if (!$promotion->isActive()) { + return $this->error('Promotion is already paused.'); + } + + if ($dryRun) { + // R2: full validation done above, no writes here. + return $this->success([ + 'promotionId' => $promotion->getId(), + 'name' => $promotion->getName(), + 'change' => ['active' => ['from' => true, 'to' => false]], + ], ['dryRun' => true]); + } + + // R3: the approved commit. + $this->promotions->pause($promotion->getId(), $context); + + return $this->success([ + 'promotionId' => $promotion->getId(), + 'active' => false, + ]); + } +} +``` + +Register the class as a service tagged `shopware.mcp.tool`. Shopware derives the input schema from the `__invoke()` signature, so the `bool $dryRun = true` parameter is all that is needed to satisfy rule R1. + +```php +// Resources/config/services.php +$services->set(PromotionPauseTool::class) + ->args([ + service(PromotionService::class), + service(McpContextProvider::class), + ]) + ->tag('shopware.mcp.tool'); +``` + +### Write the preview + +The preview payload is rendered to the merchant, so shape it for a person rather than for a machine: + +* Name the affected records by something the merchant recognizes, such as a product number or promotion name, alongside the technical id. +* Describe the change as *from* and *to* values where possible. +* Keep it small. Summarize bulk operations with counts and a few examples instead of listing every record. +* Return `error()` for anything the commit would reject. A preview that succeeds and a commit that fails is the worst experience for the merchant. + +### Read-only tools + +A read tool has the same class shape without the `dryRun` parameter. Declare the read privilege it needs and return the data directly. Don't add a `dryRun` parameter to a tool that has no side effects. + +### App-based tools + +Tools that an app exposes over a webhook follow the same contract. Declare `dryRun` as a boolean property with `"default": true` in the tool's JSON input schema, and branch on it in your webhook handler exactly as the plugin example does. + +## Requirements and limits + +* **Stateless between calls** - Preview and commit arrive in different sessions. Never store the preview and replay it on commit. Recompute from the arguments. +* **Idempotent commits where possible** - Copilot executes an approval once, but network retries can repeat a call. Design the commit so that running it twice with the same arguments is harmless. +* **Privileges are the merchant's** - Copilot acts with the permissions of the merchant who is chatting. Check the privilege your change needs with `requirePrivilege()` and declare it with `McpToolRequires` so that shop administrators can configure roles. +* **Response envelope** - Always return through `success()` or `error()`. Copilot treats `success: false` as a tool error and doesn't proceed to the commit. +* **Response size** - Shopware caps tool responses at 100 KB. Previews and results should stay well below that. +* **Timeouts** - Copilot waits a few seconds for a tool call. Long-running work should return quickly and continue asynchronously, reporting a reference the merchant can check. +* **No preview-only side effects** - Logging is fine. Creating draft records, reserving stock, or sending notifications during a preview is not. + +## Test your tool + +Follow the below steps to verify that Copilot discovers and calls your tool correctly: + +1. Confirm that your tool is registered. The following command lists your tool with its group and privileges: + + ```bash + bin/console debug:mcp + ``` + +2. Call the shop's MCP endpoint directly with an Admin API token. Enable your toolset with `shopware-toolset-enable`, call the tool with `dryRun: true`, and check that nothing changed. Then call it with `dryRun: false` and verify the change. + +3. In the Copilot chat, ask for the change in plain language. Copilot should search for your tool, show an approval card with your preview, and apply the change after approval. + +4. Ask Copilot to do something your validation rejects. The failure should surface at the preview stage, before any approval card appears. + +::: tip +To trace what Copilot does, inject a logger into the tool and log every invocation with the `dryRun` value. Tool classes that extend `McpToolResponse` are already attached to the `mcp` Monolog channel. A `dryRun: true` entry in the log proves that Copilot found the tool, enabled its toolset, and called it. +::: + +## Known limitations + +The `dryRun` contract is Copilot's first mechanism for safely running tools it hasn't seen before. It has two known gaps: + +* Tools that change data but can't offer a meaningful preview, such as file uploads, don't fit the contract yet. You can publish them, but Copilot doesn't execute them until a dedicated flow exists. +* The contract relies on a naming convention. A future Shopware release is expected to expose the standard MCP tool annotations, including `readOnlyHint`, and Copilot honors those when present. Declaring `dryRun` remains supported, so tools written against this guide don't need changes. + +## Checklist before you publish + +* Every tool with side effects declares `bool $dryRun = true`. +* No read-only tool declares `dryRun`. +* Preview calls validate fully and write nothing. +* Commit calls work from the arguments alone and are safe to repeat. +* Descriptions explain when to use the tool and mention the `dryRun` behavior. +* Privileges are declared and checked. + +Now that your tools follow the approval contract, see [MCP Support in Shopware](../index.md) for the full list of tool, resource, and prompt extension points the MCP server offers. From ae3eb4a3906bf0cd8ecb92f5cb602771052683a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 17 Sep 2026 13:27:52 +0000 Subject: [PATCH 02/16] docs: align behavior matrix table in copilot tool approval guide Co-authored-by: dfrancos-hub <98743463+dfrancos-hub@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 0af3ff116..710cdd59e 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -79,12 +79,12 @@ A tool with side effects but without a `dryRun` parameter is indistinguishable f The following table summarizes how Copilot treats each tool shape: -| Tool shape | How Copilot calls it | Merchant approval | -| :--- | :--- | :--- | -| No `dryRun` in schema | Directly, during the conversation | Not shown | -| Has `dryRun`, called with `true` | Directly, to obtain the preview | Not needed | -| Has `dryRun`, called with `false` | Only after the merchant approves the preview | Required | -| Has side effects, no `dryRun` | Directly, treated as read-only | Bypassed | +| Tool shape | How Copilot calls it | Merchant approval | +| :-------------------------------- | :------------------------------------------- | :---------------- | +| No `dryRun` in schema | Directly, during the conversation | Not shown | +| Has `dryRun`, called with `true` | Directly, to obtain the preview | Not needed | +| Has `dryRun`, called with `false` | Only after the merchant approves the preview | Required | +| Has side effects, no `dryRun` | Directly, treated as read-only | Bypassed | ## What the merchant sees From e0c9436535b736ecc2db8db467a28c8547c436eb Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:34:49 +0200 Subject: [PATCH 03/16] Clarify Shopware version for Copilot tool approval Update version information for Shopware Copilot functionality. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 710cdd59e..f8c086723 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -10,7 +10,7 @@ nav: Shopware Copilot can use the MCP tools that your plugin or app registers on a merchant's shop. This guide explains how Copilot discovers those tools and describes the `dryRun` contract a tool must follow so that the merchant gets an approval step before the tool changes data. ::: info -This functionality is available starting with Shopware 6.7. The MCP server is experimental. +This functionality is available starting with Shopware 6.7.14.0, which provides the tool groups and progressive discovery used by this guide. The MCP server is experimental. ::: ::: warning From 2d9d5b4a4d70b044a401547e880f34e5824ad0c2 Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:35:37 +0200 Subject: [PATCH 04/16] Update write tool example for plugin clarity Clarified the description of the write tool example to specify its use in a plugin and adherence to Shopware's standards. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index f8c086723..c3c1db8c3 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -116,7 +116,7 @@ The preview and commit steps happen in separate MCP sessions, possibly minutes a ## Implement a write tool in a plugin -The example below is a complete write tool. It extends `McpToolResponse`, which every MCP tool must do, and follows rules R1 to R3. +The example below is a complete write tool for a plugin. It extends `McpToolResponse` to use Shopware's standard response envelope and helpers, and follows rules R1 to R3. ```php Date: Thu, 17 Sep 2026 15:36:04 +0200 Subject: [PATCH 05/16] Revise guidelines for tool approval process Update response size handling and clarify idempotent commits. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index c3c1db8c3..40d4060df 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -219,7 +219,7 @@ Tools that an app exposes over a webhook follow the same contract. Declare `dryR * **Idempotent commits where possible** - Copilot executes an approval once, but network retries can repeat a call. Design the commit so that running it twice with the same arguments is harmless. * **Privileges are the merchant's** - Copilot acts with the permissions of the merchant who is chatting. Check the privilege your change needs with `requirePrivilege()` and declare it with `McpToolRequires` so that shop administrators can configure roles. * **Response envelope** - Always return through `success()` or `error()`. Copilot treats `success: false` as a tool error and doesn't proceed to the commit. -* **Response size** - Shopware caps tool responses at 100 KB. Previews and results should stay well below that. +* **Response size** - Responses larger than 100 KB are returned through a resource URI instead of inline. Keep previews and results compact so Copilot can use them directly. * **Timeouts** - Copilot waits a few seconds for a tool call. Long-running work should return quickly and continue asynchronously, reporting a reference the merchant can check. * **No preview-only side effects** - Logging is fine. Creating draft records, reserving stock, or sending notifications during a preview is not. From 4c6381f01f89f235550c39a3fe1e65962dcb7554 Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:36:29 +0200 Subject: [PATCH 06/16] Update `dryRun` contract limitations in approval guide Clarified the limitations of the `dryRun` contract for tools that change data without meaningful previews. Updated guidance on publishing such tools without merchant approval. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 40d4060df..97973eadb 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -247,7 +247,7 @@ To trace what Copilot does, inject a logger into the tool and log every invocati The `dryRun` contract is Copilot's first mechanism for safely running tools it hasn't seen before. It has two known gaps: -* Tools that change data but can't offer a meaningful preview, such as file uploads, don't fit the contract yet. You can publish them, but Copilot doesn't execute them until a dedicated flow exists. +* Tools that change data but can't offer a meaningful preview, such as file uploads, cannot use this approval flow. If published without `dryRun`, they are treated as read-only and may execute immediately without merchant approval, so expose them only when that behavior is acceptable. * The contract relies on a naming convention. A future Shopware release is expected to expose the standard MCP tool annotations, including `readOnlyHint`, and Copilot honors those when present. Declaring `dryRun` remains supported, so tools written against this guide don't need changes. ## Checklist before you publish From ea49f87005323901799a7070e08bda98b9801bd1 Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:36:55 +0200 Subject: [PATCH 07/16] Fix link path in MCP server approval guide Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 97973eadb..7ed86ebc5 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -19,7 +19,7 @@ The `dryRun` contract is a temporary solution. A future Shopware release is expe ## Prerequisites -This guide assumes that you know how to extend the Shopware MCP server. For more information, see [MCP Support in Shopware](../index.md). +This guide assumes that you know how to extend the Shopware MCP server. For more information, see [MCP Support in Shopware](./index.md). You need the following: From 87610642526b451ba4ca1d5863ced77e48a52579 Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:37:14 +0200 Subject: [PATCH 08/16] Fix formatting in Copilot tool approval instructions Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 7ed86ebc5..a29ccdbfb 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -225,7 +225,7 @@ Tools that an app exposes over a webhook follow the same contract. Declare `dryR ## Test your tool -Follow the below steps to verify that Copilot discovers and calls your tool correctly: +Follow these steps to verify that Copilot discovers and calls your tool correctly: 1. Confirm that your tool is registered. The following command lists your tool with its group and privileges: From 1a5d91bdf952466f3a48582df90b675d0491831a Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:37:47 +0200 Subject: [PATCH 09/16] Update dryRun property handling in webhook tools Clarify handling of 'dryRun' property in webhook tools. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index a29ccdbfb..b8c217999 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -211,7 +211,7 @@ A read tool has the same class shape without the `dryRun` parameter. Declare the ### App-based tools -Tools that an app exposes over a webhook follow the same contract. Declare `dryRun` as a boolean property with `"default": true` in the tool's JSON input schema, and branch on it in your webhook handler exactly as the plugin example does. +Tools that an app exposes over a webhook follow the same contract. Declare `dryRun` as an optional boolean property with `"default": true` in the tool's JSON input schema. Because JSON Schema defaults do not populate omitted request properties, the webhook handler must treat a missing value as `true` (for example, `$dryRun = $args['dryRun'] ?? true`) before branching. ## Requirements and limits From 6f23e09607e29d199605113e691548bf869e6206 Mon Sep 17 00:00:00 2001 From: dfrancos-hub Date: Thu, 17 Sep 2026 16:00:08 +0200 Subject: [PATCH 10/16] docs: minor fixes --- products/tools/mcp-server/copilot-tool-approval.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index b8c217999..d9ec06fca 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -118,7 +118,7 @@ The preview and commit steps happen in separate MCP sessions, possibly minutes a The example below is a complete write tool for a plugin. It extends `McpToolResponse` to use Shopware's standard response envelope and helpers, and follows rules R1 to R3. -```php +```PHP set(PromotionPauseTool::class) ->args([ @@ -200,7 +200,7 @@ $services->set(PromotionPauseTool::class) The preview payload is rendered to the merchant, so shape it for a person rather than for a machine: -* Name the affected records by something the merchant recognizes, such as a product number or promotion name, alongside the technical id. +* Name the affected records by something the merchant recognizes, such as a product number or promotion name, alongside the technical ID. * Describe the change as *from* and *to* values where possible. * Keep it small. Summarize bulk operations with counts and a few examples instead of listing every record. * Return `error()` for anything the commit would reject. A preview that succeeds and a commit that fails is the worst experience for the merchant. @@ -219,7 +219,7 @@ Tools that an app exposes over a webhook follow the same contract. Declare `dryR * **Idempotent commits where possible** - Copilot executes an approval once, but network retries can repeat a call. Design the commit so that running it twice with the same arguments is harmless. * **Privileges are the merchant's** - Copilot acts with the permissions of the merchant who is chatting. Check the privilege your change needs with `requirePrivilege()` and declare it with `McpToolRequires` so that shop administrators can configure roles. * **Response envelope** - Always return through `success()` or `error()`. Copilot treats `success: false` as a tool error and doesn't proceed to the commit. -* **Response size** - Responses larger than 100 KB are returned through a resource URI instead of inline. Keep previews and results compact so Copilot can use them directly. +* **Response size** - Responses larger than 100 KB are returned through a resource URI instead of inline. Keep previews and results compact, so Copilot can use them directly. * **Timeouts** - Copilot waits a few seconds for a tool call. Long-running work should return quickly and continue asynchronously, reporting a reference the merchant can check. * **No preview-only side effects** - Logging is fine. Creating draft records, reserving stock, or sending notifications during a preview is not. From 7f9ed57d749295e1d4d7027bd2fc8798807df704 Mon Sep 17 00:00:00 2001 From: dfrancos-hub Date: Thu, 17 Sep 2026 16:04:41 +0200 Subject: [PATCH 11/16] docs: change pos --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index d9ec06fca..d2b8647a4 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -1,7 +1,7 @@ --- nav: title: Copilot tool approval - position: 40 + position: 65 --- From 2f1bdfd046846e0ae617fa5dd0c8ab4eed8e2841 Mon Sep 17 00:00:00 2001 From: dfrancos-hub Date: Mon, 21 Sep 2026 10:05:15 +0200 Subject: [PATCH 12/16] add acl warning --- products/tools/mcp-server/copilot-tool-approval.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index d2b8647a4..f5fca01d8 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -215,6 +215,8 @@ Tools that an app exposes over a webhook follow the same contract. Declare `dryR ## Requirements and limits + + * **Stateless between calls** - Preview and commit arrive in different sessions. Never store the preview and replay it on commit. Recompute from the arguments. * **Idempotent commits where possible** - Copilot executes an approval once, but network retries can repeat a call. Design the commit so that running it twice with the same arguments is harmless. * **Privileges are the merchant's** - Copilot acts with the permissions of the merchant who is chatting. Check the privilege your change needs with `requirePrivilege()` and declare it with `McpToolRequires` so that shop administrators can configure roles. @@ -245,6 +247,10 @@ To trace what Copilot does, inject a logger into the tool and log every invocati ## Known limitations +::: warning +Copilot as a service does not have access to tables created by your plugin/app. If you need such functionality, a custom acl with the required permissions should be added via Copilot Settings -> Use custom roles for Copilot, by the Copilot users. +::: + The `dryRun` contract is Copilot's first mechanism for safely running tools it hasn't seen before. It has two known gaps: * Tools that change data but can't offer a meaningful preview, such as file uploads, cannot use this approval flow. If published without `dryRun`, they are treated as read-only and may execute immediately without merchant approval, so expose them only when that behavior is acceptable. From 45cdf6104aa5add225f01b952a334872f4c33d64 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 21 Sep 2026 08:08:06 +0000 Subject: [PATCH 13/16] fix: remove extra blank lines from copilot tool approval guide Co-authored-by: dfrancos-hub <98743463+dfrancos-hub@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index f5fca01d8..6276ef29c 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -215,8 +215,6 @@ Tools that an app exposes over a webhook follow the same contract. Declare `dryR ## Requirements and limits - - * **Stateless between calls** - Preview and commit arrive in different sessions. Never store the preview and replay it on commit. Recompute from the arguments. * **Idempotent commits where possible** - Copilot executes an approval once, but network retries can repeat a call. Design the commit so that running it twice with the same arguments is harmless. * **Privileges are the merchant's** - Copilot acts with the permissions of the merchant who is chatting. Check the privilege your change needs with `requirePrivilege()` and declare it with `McpToolRequires` so that shop administrators can configure roles. From fb951ebb29a20504cbf3a61aa822bc718ab44f39 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 21 Sep 2026 08:08:34 +0000 Subject: [PATCH 14/16] docs: clarify ACL warning in copilot tool approval guide Co-authored-by: dfrancos-hub <98743463+dfrancos-hub@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 6276ef29c..9ffca1b23 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -246,7 +246,7 @@ To trace what Copilot does, inject a logger into the tool and log every invocati ## Known limitations ::: warning -Copilot as a service does not have access to tables created by your plugin/app. If you need such functionality, a custom acl with the required permissions should be added via Copilot Settings -> Use custom roles for Copilot, by the Copilot users. +Copilot as a service does not have access to tables created by your plugin/app. If you need such functionality, Copilot users must add a custom ACL with the required permissions in Copilot Settings -> Use custom roles for Copilot. ::: The `dryRun` contract is Copilot's first mechanism for safely running tools it hasn't seen before. It has two known gaps: From da957c268a63c0dfeca6526112eeda0c3b5516fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 21 Sep 2026 08:09:01 +0000 Subject: [PATCH 15/16] docs: fix final MCP guide link target Co-authored-by: dfrancos-hub <98743463+dfrancos-hub@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index 9ffca1b23..d76102d98 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -263,4 +263,4 @@ The `dryRun` contract is Copilot's first mechanism for safely running tools it h * Descriptions explain when to use the tool and mention the `dryRun` behavior. * Privileges are declared and checked. -Now that your tools follow the approval contract, see [MCP Support in Shopware](../index.md) for the full list of tool, resource, and prompt extension points the MCP server offers. +Now that your tools follow the approval contract, see [MCP Support in Shopware](./index.md) for the full list of tool, resource, and prompt extension points the MCP server offers. From 6733e91ddc88bae87855522a131979c2b920fdc1 Mon Sep 17 00:00:00 2001 From: "D.Francos" <98743463+dfrancos-hub@users.noreply.github.com> Date: Mon, 21 Sep 2026 16:15:20 +0200 Subject: [PATCH 16/16] Update products/tools/mcp-server/copilot-tool-approval.md Co-authored-by: Su <112690947+sushmangupta@users.noreply.github.com> --- products/tools/mcp-server/copilot-tool-approval.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/tools/mcp-server/copilot-tool-approval.md b/products/tools/mcp-server/copilot-tool-approval.md index d76102d98..2d8dc5ee7 100644 --- a/products/tools/mcp-server/copilot-tool-approval.md +++ b/products/tools/mcp-server/copilot-tool-approval.md @@ -27,7 +27,7 @@ You need the following: * A plugin or app that registers at least one MCP tool * Access to Shopware Copilot in the Administration -## Summary +## Introduction You don't need to register your tools with Copilot. Copilot finds them through the shop's own MCP catalog.