Skip to content

[6.x] Add MCP support - #4401

Draft
lukeholder wants to merge 2 commits into
6.xfrom
feature/6.x-mcp
Draft

lukeholder wants to merge 2 commits into
6.xfrom
feature/6.x-mcp

Conversation

@lukeholder

@lukeholder lukeholder commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Summary

Commerce data and operations are now available through Craft's authenticated MCP server. Each MCP tool calls a Commerce service, and that service checks permissions and store access itself, so the same rules apply without MCP. The RequiresPermission/RequiresAdmin attributes on the tools only decide which tools are listed.

MCP tool (src/Mcp)                      Commerce service (does the permission check)
───────────────────────────────────     ──────────────────────────────────────────────
elements.* products|variants|orders|transfers → element adapters + OrderPolicy / existing policies
commerce.resources.*      (store records)     → Management\Resources   (granular perms + store access)
commerce.configuration.*  (admin config)      → Management\Resources   (admin, writes need allowAdminChanges)
commerce.inventory.*                          → Inventory\InventoryManagement
commerce.orders.*                             → Order\OrderManagement
commerce.payments.capture|refund              → Payment\PaymentManagement
commerce.transfers.*                          → Transfer\TransferManagement
commerce.stores.*                             → Store\StoreManagement
commerce.reports.get                          → Stats\Reports
  • Output uses explicit allowlists. Order numbers, payment-source tokens, transaction hashes/references/responses, and gateway settings are never returned.
  • Gateways can't be created or edited, and inventory locations can't be deleted, through MCP.
  • Writes to orders, payments, inventory, and transfers take cache locks.
  • composer.lock updates craftcms/cms to current 6.x, because the MCP scope enum and route registration this needs landed there.

Evidence

tests/Feature/Mcp/CommerceTest.php calls the real MCP HTTP route:

✓ discovers Commerce resources and all element adapters
✓ creates reads partially updates and deletes store-management records
✓ lists every resource type without exposing gateway settings
✓ enforces administrative changes in the Commerce service without MCP
✓ does not let a read token call mutations or a write token call configuration
✓ rejects undeclared attributes and ambiguous identifiers
✓ manages products variants and carts through the shared element tools
✓ updates inventory and dispatches and receives transfers without overreceiving
✓ replaces discount coupons and applies cart details and coupons
✓ reads and updates store settings, topology and reports
✓ denies order changes and customer reports in Commerce for users without those permissions
Tests: 11 passed

Removing the commerce-editOrders check from OrderPolicy::save(), or the commerce-manageCustomers check from Reports, makes the denial test fail.

The CMS lock bump breaks 11 existing control panel index/edit controller tests (OrderIndexTest, ProductIndexTest, ProductsControllerTest, TransfersControllerTest, VariantsControllerTest), because CMS 6.x changed the Inertia props on element index screens (for example, data is no longer present). These need updating for current CMS 6.x regardless of MCP. The TopProducts/TopProductTypes today failures also occur on 6.x.

Thread: https://ampcode.com/threads/T-01a18b1b-bd8d-7188-8a6c-600b320a710c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant