Skip to content

WooCommerce

New in v3.4.2 (Pro). When WooCommerce is active, EMCP exposes the full WooCommerce wc/v3 REST surface: around 120 operations: so an AI agent can manage the whole store: find and fulfil orders, issue refunds, create products and coupons, read sales reports, and adjust settings, shipping, taxes, and webhooks.

Every operation runs through WooCommerce’s own REST controllers, so it’s HPOS-safe (High-Performance Order Storage), always current with WooCommerce, and enforces WooCommerce’s own permission checks, the plugin never bypasses them.

For an executed content-only example, see improve WooCommerce product descriptions with AI. It includes two draft-product edits, an unchanged control and storefront verification.

To keep the MCP tool-list small, the whole domain is exposed as two dispatcher tools rather than one tool per operation:

  • woo-read: all read operations (like every Pro tool, it starts disabled on a new EMCP install, so switch it on first)
  • woo-write: all write operations (ships disabled by default)

Each takes an operation and an arguments object. Call a tool with no operation to get its catalog, then call it again to run one:

// discover
woo-read({})
// → { mode: "read", operations: [ { name: "list-orders", method: "GET", route: "wc/v3/orders", … }, … ] }
// act
woo-read({ operation: "get-order", arguments: { id: 812 } })

The dispatchers only register when WooCommerce is active, and gate on the manage_woocommerce capability; WooCommerce’s per-endpoint permission checks then apply on top.

woo-read and woo-write together span the full store:

AreaOperations
Productslist/get/create/update/delete + batch; variations; categories; tags; attributes + terms; reviews; shipping classes
Orderslist/get/create/update/delete + batch; order notes; refunds (create moves money)
Customerslist/get/create/update/delete (PII)
Couponslist/get/create/update/delete + batch
Reportssales, top sellers, and totals for orders / products / customers / coupons / reviews
Store configsettings, payment gateways, shipping zones / methods / locations, taxes + tax classes, webhooks, system status, data (countries, currencies)

Reads are enabled by default; every create/update/delete lives behind woo-write, which ships off.

New in v3.15.0 (Pro): list-brands and get-brand in woo-read, plus create-brand and update-brand in woo-write. Requires WooCommerce’s native product_brand taxonomy and /wc/v3/products/brands route. Third-party brand taxonomies are not supported.

woo-read({ operation: "list-brands", arguments: { search: "Acme", hide_empty: false } })
woo-write({ operation: "create-brand", arguments: {
name: "Acme", slug: "acme", description: "Acme products.",
logo_attachment_id: 123, dry_run: true
} })
// After reviewing validation, repeat without dry_run to create the brand.
woo-read({ operation: "get-brand", arguments: { id: 45 } })
woo-write({ operation: "update-brand", arguments: { id: 45, description: "Updated archive content." } })

Create/update support dry_run: true to validate without writing. Duplicate names/slugs and invalid IDs are rejected. Omitted fields are preserved on update. Logos must be existing image attachments: use sideload-image first for a remote logo, then pass logo_attachment_id or image: { id: 123 }. Remote image.src URLs are rejected. Set logo_attachment_id: 0 to remove a logo.

Brand responses include id, term_id, taxonomy, archive url, and logo_attachment_id. Use term_id with the active SEO plugin’s term tools for SEO title, description, canonical, and focus keyword; brand description is archive content, not an SEO meta description. SEO fields are deliberately rejected by the brand write operations.

rankmath-write({ operation: "update-term-seo", arguments: {
term_id: 45, title: "Acme products", description: "Browse the Acme collection.",
canonical: "https://your-site.com/brand/acme/", focus_keyword: "Acme"
} })
rankmath-read({ operation: "get-term-seo", arguments: { term_id: 45 } })

Enable the relevant SEO tools first, read back both brand and SEO data, and inspect the public archive. Live tests with Rank Math verified that an empty brand archive is noindexed and has no canonical under its default settings; a populated brand renders the saved canonical. This is SEO-plugin behavior, not a failed metadata save.

New in v3.16.0 (Pro): plan-product-import and upsert-products, both in woo-write (the plan step only validates, it writes nothing, but it lives in the write dispatcher since it’s part of the same confirm-gated flow). Same pattern as ACF’s document imports: a PDF, spreadsheet, CSV, or DOCX product list is parsed by the connected agent, not uploaded to WordPress. The agent sends bounded structured JSON; WooCommerce only ever validates and writes that JSON.

woo-write({ operation: "plan-product-import", arguments: {
items: [
{ client_ref: "row-1", data: { sku: "ACME-100", regular_price: "29.99", stock_quantity: 40 } },
{ client_ref: "row-2", data: { id: 812, regular_price: "34.99" } }
]
} })
// → { plan_hash: "…", items: [ … per-row validation … ] }
woo-write({ operation: "upsert-products", arguments: {
items: [ /* same items */ ],
plan_hash: "<hash returned above>",
confirm: true
} })

Up to 100 rows per call. Each row resolves to a product by explicit id first, then exact sku, never by name, so a typo in a product title can’t silently create a duplicate or edit the wrong item. upsert-products never deletes, only creates or updates. The exact item list and plan_hash from plan-product-import must match what’s sent to upsert-products, changing anything between plan and apply invalidates the hash.

Money-moving and irreversible operations require an explicit confirm: true in arguments, on top of woo-write being disabled by default:

  • create-refund (moves money)
  • every delete-* (products, orders, customers, coupons, …)
  • every *-batch (bulk create/update/delete)

Without it you get a confirmation_required error, so an agent has to be deliberate about anything that spends money or deletes data.

// 1. find processing orders
woo-read({ operation: "list-orders", arguments: { status: "processing", per_page: 10 } })
// 2. read one
woo-read({ operation: "get-order", arguments: { id: 812 } })
// 3. mark it completed
woo-write({ operation: "update-order", arguments: { id: 812, status: "completed" } })
// 4. refund $20 on it (money, needs confirm)
woo-write({ operation: "create-refund",
arguments: { order_id: 812, amount: "20.00", reason: "partial refund", api_refund: true, confirm: true } })
// 5. create a simple product
woo-write({ operation: "create-product",
arguments: { name: "Blue Mug", type: "simple", regular_price: "12.00", sku: "MUG-BLUE" } })

Path parts go in arguments (get-order → { id }, list-variations → { product_id }, get-settings → { group }); everything else is passed straight to the WooCommerce endpoint, list filters for reads, the record body for writes.

  • WooCommerce’s own REST. Every call is executed by WooCommerce’s wc/v3 controllers as the authenticated admin, no privilege escalation, and HPOS is handled transparently.
  • Writes off by default. woo-write ships disabled; an admin opts in under EMCP Tools → Tools → Plugins, in the WooCommerce section of the E-Commerce group.
  • Confirm gate. Refunds, deletes, and batch operations refuse to run without confirm: true.
  • Capability-gated. Both dispatchers require manage_woocommerce; each operation then passes through WooCommerce’s per-endpoint capability check.
  • Only when active. The tools don’t register at all unless WooCommerce is installed and active.

The dispatchers appear under EMCP Tools → Tools → Plugins, in the WooCommerce section of the E-Commerce group, as two cards: WooCommerce Read (woo-read) and WooCommerce Write (woo-write, off by default). Each card shows how many operations it lists; select that line to see them. Switch a tool to allow or block all of its operations at once, then choose Save changes in the save bar and reconnect your AI client. While WooCommerce is not active, both cards carry a Needs WooCommerce badge and cannot be switched on.

Pro ships an emcp-plugins Agent Skill that teaches a connected agent this whole model, the two-dispatcher pattern, the discover→act flow, the confirm: true requirement, and the WooCommerce operation reference, so it drives the store correctly without you spelling it out.