OpenAPI 3.0 · Node.js · TypeScript

The WooCommerce REST API,
documented properly.

A hand-written OpenAPI specification for WooCommerce wc/v3 — every resource, filter and error envelope — served through Swagger UI with a live gateway so Try it out actually reaches a real store. This is the API half of an API-vs-MCP comparison.

Operations
—
Spec version
—
Gateway
checking…
Upstream store
—

Two interfaces over one store

The specification you can browse here and the companion MCP server talk to the same WooCommerce install and issue the same HTTP requests. They differ in who the interface was designed for.

REST + OpenAPI

Written for programmers

  • Resource-shaped. 133 operations across products, orders, customers, coupons, reports and settings. Every field, every filter.
  • Exhaustive by design. The spec's job is to leave nothing out, so the caller can build anything.
  • Composition is the caller's problem. "Which unfulfilled orders contain a low-stock item" is three endpoints and a join you write yourself.
  • Stable and versioned. A contract you can generate typed clients from and pin in CI.
  • Errors are codes. 403 woocommerce_rest_cannot_create means something to a developer who has read the docs.
MCP server

Written for models

  • Intent-shaped. A dozen tools — find_orders, check_stock, refund_order — instead of 133 endpoints.
  • Selective by design. Each tool exposes the handful of arguments that matter and hides the rest, because a large surface is a liability to a model, not a feature.
  • Composition lives server-side. One tool call can fan out to several REST calls and return the joined answer.
  • Descriptions are the interface. Tool text is read at runtime by a model with no prior context, so it must explain when to use the tool, not just what it does.
  • Errors are sentences. "That key is read-only, so I can't create products" is recoverable; a status code is not.

Same question, two shapes

"Which orders from the last week are still unfulfilled, and what are they worth?"

REST

You orchestrate

# 1. fetch the candidate orders
curl -u "$CK:$CS" \
  "$STORE/wp-json/wc/v3/orders?status=processing,on-hold\
&after=2026-09-07T00:00:00&per_page=100"

# 2. page until X-WP-TotalPages is exhausted
# 3. parse `total` as decimal, not float
# 4. sum, group, decide what "unfulfilled" means
# 5. handle 401 vs 403 vs 400 separately

Five decisions before you see an answer — and each one is a place to be wrong.

MCP

The server orchestrates

// one tool call from the model
{
  "tool": "find_orders",
  "arguments": {
    "status": "unfulfilled",
    "since": "7d",
    "include_totals": true
  }
}

// -> 23 orders, ₹1,84,320 outstanding,
//    oldest 6 days, already paginated and summed

The pagination, the decimal handling and the definition of "unfulfilled" live in the server.

Where each one wins

Not a competition. They solve adjacent problems, and most serious systems end up with both.

REST + OpenAPIMCP server
ConsumerA developer writing code ahead of timeA model choosing at runtime
SurfaceBroad — expose everything, hide nothingNarrow — expose intents, hide plumbing
DiscoveryRead the spec, generate a client, shipList tools over the protocol, mid-conversation
AuthConsumer key/secret held by the clientHeld by the server; the model never sees it
ErrorsStatus codes and machine-readable slugsProse a model can actually recover from
Batching/batch, non-transactional, caller-drivenServer-side, one tool call, joined result
Best atIntegrations, ETL, typed clients, contract testsAssistants, ops copilots, natural-language workflows
Worst atBeing handed to something that cannot read docsAnything needing the full, unabridged surface

The honest summary: MCP is not a replacement for a REST API — it is a curated interface layer above one. This spec is what you build the MCP server on top of. Skip the API and the MCP server has nothing to call; skip the MCP server and every model that touches your store has to learn all 133 operations first.

What's documented

Every group below is browsable, filterable and callable in the explorer.

Point it at your store

Four steps. The gateway ships read-only, so you can demo against production without holding your breath.

  1. Create REST API keys

    In wp-admin: WooCommerce → Settings → Advanced → REST API → Add key. Choose Read permission for a demo. You get a ck_… and a cs_…, shown once.
  2. Configure this app

    cp .env.example .env
    WOO_STORE_URL=https://your-store.com
    WOO_CONSUMER_KEY=ck_…
    WOO_CONSUMER_SECRET=cs_…
  3. Run it

    npm install && npm run build && npm start
  4. Try it out

    Open /docs, pick listOrders, hit Execute. The call goes through this app's gateway, which attaches your credentials server-side — they never reach the browser.