Skip to content

Order Tools

KristofersOzolinsMagebit edited this page May 13, 2026 · 2 revisions

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:flush

All 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) and allow_writes on the token. See Setup for the full write-gate explanation.
  • Destructive writes (invoice.create, shipment.create, credit_memo.create, order.cancel, order.hold) advertise requires_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.

Sample session — "find the last order by this customer and issue a full refund"

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.

Sample MCP session — operator asks the AI to find the last order placed by a customer email and issue a full refund; the AI lists the customer's orders, identifies the most recent eligible one, asks for confirmation since refunds are irreversible, and on approval calls sales.order.credit_memo.create to issue the credit memo.

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 catalog

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

Orders

sales.order.list

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.

sales.order.get

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.

sales.order.cancel

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}.

sales.order.hold

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}.

sales.order.unhold

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.

Comments

sales.order.comments

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.

sales.order.comment.add

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.

Payment

sales.order.payment

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.

Invoices

sales.order.invoices

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.

sales.order.invoice.get

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.

sales.order.invoice.create

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}.

Shipments

sales.order.shipments

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.

sales.order.shipment.get

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.

sales.order.shipment.create

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}.

sales.order.shipment.track.add

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.

Credit memos

sales.order.credit_memos

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.

sales.order.credit_memo.get

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.

sales.order.credit_memo.create

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}.

Extending

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.