-
Notifications
You must be signed in to change notification settings - Fork 1
Order Tools
The magebitcom/magento2-mcp-order-tools sub-module ships 18 order tools that let an MCP-connected AI agent read and operate every part of an order's lifecycle — orders themselves, invoices, shipments (with tracking numbers), credit memos (refunds), order comments, and the order's payment + transaction history. The same entities your team manages under Sales → Orders and the per-order detail screen in the admin.
Install on top of the base Magebit_Mcp module:
composer require magebitcom/magento2-mcp-order-tools
bin/magento module:enable Magebit_McpOrderTools
bin/magento setup:upgrade
bin/magento cache:flushAll order tools are namespaced sales.order.* and follow the same conventions:
- Each tool is gated by its own admin-role ACL under
Magebit_McpOrderTools::tool_sales_*— the admin role you give the token-issuing user must grant the tool's resource. - Write tools require both
Allow Write Tools(store config) andallow_writeson the token. See Setup for the full write-gate explanation. - Destructive writes (
invoice.create,shipment.create,credit_memo.create,order.cancel,order.hold) advertiserequires_confirmation: true. Additive / non-destructive writes (shipment.track.add,order.unhold,order.comment.add) do NOT prompt for confirmation. - Every write also enforces the underlying
Magento_Sales::*admin ACL — so MCP can never do what the admin UI would forbid for the same role. - Every per-entity tool accepts either the numeric primary id (
order_id,invoice_id,shipment_id,credit_memo_id) or the human-visible*_increment_id(e.g.000000001). - Read responses are composed from field resolvers (
OrderFieldResolverInterface,InvoiceFieldResolverInterface,ShipmentFieldResolverInterface,CreditMemoFieldResolverInterface,OrderCommentFieldResolverInterface). Third-party modules can register their own resolvers to add fields to any response without forking the tool.
The headline workflow for support: pull a customer's most recent order, confirm it's eligible, refund it. The AI lists the customer's orders sorted by created_at DESC, summarises the candidate, pauses for confirmation (refunds aren't reversible), and on approval calls sales.order.credit_memo.create with is_online: true so the payment gateway processes the refund.
Two tool calls, one confirmation. Partial refunds use the same flow — pass items: [{item_id, qty}] to credit_memo.create. Offline refunds (no gateway call) use is_online: false.
| Tool | Mode | ACL | Underlying ACL |
|---|---|---|---|
sales.order.list |
read | Magebit_McpOrderTools::tool_sales_order_list |
— |
sales.order.get |
read | Magebit_McpOrderTools::tool_sales_order_get |
— |
sales.order.cancel |
write | Magebit_McpOrderTools::tool_sales_order_cancel |
Magento_Sales::cancel |
sales.order.hold |
write | Magebit_McpOrderTools::tool_sales_order_hold |
Magento_Sales::hold |
sales.order.unhold |
write | Magebit_McpOrderTools::tool_sales_order_unhold |
Magento_Sales::unhold |
sales.order.comments |
read | Magebit_McpOrderTools::tool_sales_order_comments |
— |
sales.order.comment.add |
write | Magebit_McpOrderTools::tool_sales_order_comment_add |
Magento_Sales::comment |
sales.order.payment |
read | Magebit_McpOrderTools::tool_sales_order_payment |
— |
sales.order.invoices |
read | Magebit_McpOrderTools::tool_sales_order_invoices |
— |
sales.order.invoice.get |
read | Magebit_McpOrderTools::tool_sales_order_invoice_get |
— |
sales.order.invoice.create |
write | Magebit_McpOrderTools::tool_sales_order_invoice_create |
Magento_Sales::invoice |
sales.order.shipments |
read | Magebit_McpOrderTools::tool_sales_order_shipments |
— |
sales.order.shipment.get |
read | Magebit_McpOrderTools::tool_sales_order_shipment_get |
— |
sales.order.shipment.create |
write | Magebit_McpOrderTools::tool_sales_order_shipment_create |
Magento_Sales::ship |
sales.order.shipment.track.add |
write | Magebit_McpOrderTools::tool_sales_order_shipment_track_add |
Magento_Sales::ship |
sales.order.credit_memos |
read | Magebit_McpOrderTools::tool_sales_order_credit_memos |
— |
sales.order.credit_memo.get |
read | Magebit_McpOrderTools::tool_sales_order_credit_memo_get |
— |
sales.order.credit_memo.create |
write | Magebit_McpOrderTools::tool_sales_order_credit_memo_create |
Magento_Sales::creditmemo |
Paginated search across sales orders. Each row composed from OrderFieldResolverInterface array with the lean pipeline (identity, state, customer, totals, timestamps — no addresses or items, those are reserved for sales.order.get). Wraps OrderRepositoryInterface::getList().
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
filter |
object | no | Built-in keys: status, state, created_at_from, created_at_to, grand_total_min, grand_total_max, customer_email, increment_id, store_id, website_id (expanded to its store-view ids). Scalar or array (array → IN). |
sort |
object | no | Sortable fields published by OrderSearchCriteriaBuilder::SORTABLE_FIELDS. Default update_time desc. |
pagination |
object | no |
page (min 1) and page_size (min 1, capped by builder). |
fields |
array of string | no | Whitelist resolver keys. |
exclude |
array of string | no | Drop resolver keys. |
Single order by entity id or increment id. Full resolver pipeline: identity, state, customer, addresses, items, totals, payment, timestamps. Wraps EntityFinder::orderFrom().
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
entity_id |
integer | one-of | Numeric sales_order.entity_id (≥ 1). |
increment_id |
string | one-of | Human-visible increment id, e.g. 000000001. |
fields |
array of string | no | Whitelist. |
exclude |
array of string | no | Drop. |
Cancel an order that hasn't been fulfilled yet. Wraps OrderManagementInterface::cancel().
Write tool. Requires confirmation.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
comment |
object | no | Status-history comment: {text: string (required), is_visible_on_front: boolean, is_customer_notified: boolean}. |
Place an order on hold (reversible). Wraps OrderManagementInterface::hold().
Write tool. Requires confirmation.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
comment |
object | no | Status-history comment: {text: string (required), is_visible_on_front: boolean, is_customer_notified: boolean}. |
Release a held order. Wraps OrderManagementInterface::unHold().
Write tool. Does NOT require confirmation (non-destructive reverse of sales.order.hold).
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
Paginated list of an order's status-history comments. Wraps OrderStatusHistoryRepositoryInterface::getList() filtered by order.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
is_visible_on_front |
boolean | no | Filter to customer-visible comments only. |
page |
integer | no | 1-based. Default 1. |
page_size |
integer | no | Capped at 100. Default 50. |
fields |
array of string | no | Whitelist resolver keys. |
exclude |
array of string | no | Drop resolver keys. |
Append a status-history comment to an order, optionally with a status transition and customer email. Wraps OrderManagementInterface::addComment().
Write tool. Does NOT require confirmation (additive).
Optional status triggers a state transition — Magento rejects invalid transitions. Customer email notification is controlled separately from on-storefront visibility.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
text |
string | yes | Comment body. Min length 1. |
is_visible_on_front |
boolean | no | Expose comment to customer. Default false. |
is_customer_notified |
boolean | no | Send customer email. Default false. |
status |
string | no | Status transition target (e.g. processing, pending). Omit to leave the order status unchanged. |
Read the payment record plus transaction history for an order. Wraps OrderInterface::getPayment() plus TransactionRepositoryInterface::getList().
Response includes a payment object ({entity_id, method, cc_type, cc_last4, additional_information}) and a transactions array — each {transaction_id, parent_id, txn_id, txn_type, is_closed, created_at} — up to the 100 most recent transactions.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
Paginated list of invoices for one order. Wraps InvoiceRepositoryInterface::getList() filtered by order_id.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
page |
integer | no | 1-based. Default 1. |
page_size |
integer | no | Capped at 100. Default 25. |
fields |
array of string | no | Whitelist resolver keys. |
exclude |
array of string | no | Drop resolver keys. |
Single invoice by id or increment id. Resolver set: identity, state, totals, items. Wraps EntityFinder::invoiceFrom().
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
invoice_id |
integer | one-of | Numeric sales_invoice.entity_id (≥ 1). |
invoice_increment_id |
string | one-of | Invoice increment id. |
fields |
array of string | no | Whitelist. |
exclude |
array of string | no | Drop. |
Create an invoice for an order. Wraps InvoiceOrderInterface::execute().
Write tool. Requires confirmation.
Omit items to invoice everything that's still invoiceable; pass a partial items array for partial invoicing ({item_id, qty} pairs). capture=true (default) triggers payment capture; capture=false produces an offline invoice.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
items |
array of object | no | Partial invoice: {item_id: int (required, ≥1), qty: number (required, > 0)}. Omit for full invoice. |
capture |
boolean | no | Charge the payment record. Default true. |
notify |
boolean | no | Email the customer. Default false. |
comment |
object | no | Status-history comment: {text: string (required), is_visible_on_front: boolean}. |
Paginated list of shipments for one order. Wraps ShipmentRepositoryInterface::getList() filtered by order_id.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
page |
integer | no | 1-based. Default 1. |
page_size |
integer | no | Capped at 100. Default 25. |
fields |
array of string | no | Whitelist resolver keys. |
exclude |
array of string | no | Drop resolver keys. |
Single shipment by id or increment id. Resolver set: identity, items, tracks. Wraps EntityFinder::shipmentFrom().
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
shipment_id |
integer | one-of | Numeric sales_shipment.entity_id (≥ 1). |
shipment_increment_id |
string | one-of | Shipment increment id. |
fields |
array of string | no | Whitelist. |
exclude |
array of string | no | Drop. |
Create a shipment for an order, optionally with tracking numbers. Wraps ShipOrderInterface::execute().
Write tool. Requires confirmation.
Omit items to ship everything that's still shippable; pass a partial items array for partial fulfilment. tracks is optional — operators can also defer to sales.order.shipment.track.add later.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
items |
array of object | no | Partial shipment: {item_id: int (required, ≥1), qty: number (required, > 0)}. Omit for full shipment. |
tracks |
array of object | no | Tracking numbers: {carrier_code: string (required, min length 1), title: string (required, min length 1), track_number: string (required, min length 1)}. |
notify |
boolean | no | Email the customer. Default false. |
comment |
object | no | Status-history comment: {text: string (required), is_visible_on_front: boolean}. |
Attach one or more tracking numbers to an existing shipment. Wraps ShipmentTrackRepositoryInterface::save().
Write tool. Does NOT require confirmation (additive).
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
shipment_id |
integer | one-of | Numeric sales_shipment.entity_id (≥ 1). |
shipment_increment_id |
string | one-of | Shipment increment id. |
tracks |
array of object | yes | One or more tracking numbers: {carrier_code: string (required, min length 1), title: string (required, min length 1), track_number: string (required, min length 1)}. Min 1 item. |
Paginated list of credit memos for one order. Wraps CreditmemoRepositoryInterface::getList() filtered by order_id.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
page |
integer | no | 1-based. Default 1. |
page_size |
integer | no | Capped at 100. Default 25. |
fields |
array of string | no | Whitelist resolver keys. |
exclude |
array of string | no | Drop resolver keys. |
Single credit memo by id or increment id. Resolver set: identity, totals, items. Wraps EntityFinder::creditMemoFrom().
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
credit_memo_id |
integer | one-of | Numeric sales_creditmemo.entity_id (≥ 1). |
credit_memo_increment_id |
string | one-of | Credit memo increment id. |
fields |
array of string | no | Whitelist. |
exclude |
array of string | no | Drop. |
Issue a credit memo (refund) for an order. Wraps RefundOrderInterface::execute() plus optional CreditmemoManagementInterface::refund().
Write tool. Requires confirmation.
is_online=false (default) produces an offline credit memo (records the refund but does NOT call the payment gateway). is_online=true calls the gateway and is not reversible — use with extreme care. items accepts {item_id, qty} for partial refunds; omit for a full refund. adjustment_positive/adjustment_negative/shipping_amount can be combined.
Arguments
| Name | Type | Required | Notes |
|---|---|---|---|
order_id |
integer | one-of | Numeric order entity id (≥ 1). |
order_increment_id |
string | one-of | Order increment id. |
items |
array of object | no | Partial refund: {item_id: int (required, ≥1), qty: number (required, > 0)}. Omit for full refund. |
adjustment_positive |
number | no | Add to refund amount (≥ 0). |
adjustment_negative |
number | no | Subtract from refund amount (≥ 0). |
shipping_amount |
number | no | Shipping refund amount (≥ 0). |
is_online |
boolean | no | Online refund via the payment gateway. Default false (offline). |
notify |
boolean | no | Email the customer. Default false. |
comment |
object | no | Status-history comment: {text: string (required), is_visible_on_front: boolean}. |
Read responses are not hard-coded — they're assembled by ordered field resolvers, and list filters are translated by registered FilterTranslatorInterfaces.
To add a custom field (e.g. an external warehouse-management reference) to every sales.order.get response, register a Magebit\McpOrderTools\Api\OrderFieldResolverInterface in DI under the order tool's fieldResolvers argument. To expose a new filter on sales.order.list, register a Magebit\McpOrderTools\Api\OrderFilterTranslatorInterface under the OrderSearchCriteriaBuilder's filterTranslators array. The same field-resolver hooks exist for the other read tools via Magebit\McpOrderTools\Api\InvoiceFieldResolverInterface, Magebit\McpOrderTools\Api\ShipmentFieldResolverInterface, Magebit\McpOrderTools\Api\CreditMemoFieldResolverInterface, and Magebit\McpOrderTools\Api\OrderCommentFieldResolverInterface.
See the sub-module's docs/EXTENDING.md for the full contract.