A modern, type-safe TypeScript monorepo for WooCommerce:
- Admin REST client (
wc/v3) for back-office / ERP / automation - Store API client (
wc/store/v1) for headless cart, checkout, and catalog - MCP server so AI agents can operate a store through validated admin tools
| Package | Role | Auth |
|---|---|---|
woocommerce-rest-ts-api |
Typed admin REST client wc/v3 (OAuth 1.0a, retries, throttling, ESM + CJS) |
Consumer key + secret |
woo-store-ts-api |
Typed Store API client wc/store/v1 (cart, checkout, storefront catalog) |
Cart-Token / Nonce (no API keys) |
woo-mcp-server |
MCP STDIO server β 80+ tools, resources, prompts, token usage for Claude / agents | Same as admin library |
| Command | URL | |
|---|---|---|
| Developer presentation β setup, features, 6 use-case scenarios | make ui-presentation |
http://127.0.0.1:8765/presentation.html |
| Tool explorer β catalog, mock tester, Claude config generator | make ui |
http://127.0.0.1:8765/ |
make ui-presentation # slide deck (β β Β· O overview Β· F fullscreen)
make ui # interactive MCP tool dashboardSource files: ui/presentation.html Β· ui/index.html
Talk to any WooCommerce store from Claude Desktop, custom agents, or any MCP client β without giving models a raw HTTP free-for-all.
# from npm (after publish)
npm i -g woo-mcp-server
# or monorepo dev
pnpm install && pnpm run build
export WC_URL=https://mystore.com WC_KEY=ck_β¦ WC_SECRET=cs_β¦
npx -y woo-mcp-serverPublished packages (separate npm names):
| Package | npm | Role |
|---|---|---|
woocommerce-rest-ts-api |
npm | Admin REST wc/v3 |
woo-store-ts-api |
packages/store-api | Store API wc/store/v1 (cart / checkout) |
woo-mcp-server |
npm | MCP STDIO server for AI agents |
Release: pnpm run publish:packages (or GitHub Action Release npm packages).
Highlights
- 80+ purpose-built tools (
woo_products_list,woo_orders_get, refunds, reviews, β¦) with Zod I/O validation - Always-on token usage β every tool result includes estimated payload tokens; hosts can record LLM rounds and audit with
woo_usage_stats - Lean agent payloads β compact JSON, list
detail=summary(_fields), slim system status, bounded error/usage memory - Single rate limiter β token bucket via
WC_RATE_LIMIT_PER_SECOND(no double-throttle with the REST library) - Resources:
woo://store/info,woo://api/schema - Prompts:
store-audit,order-report,inventory-check - Fail-fast env config, structured errors
- Live-tested on WooCommerce 10.9.3 (Docker stack under
scripts/live-wc/) - Perf proof:
pnpm --filter woo-mcp-server bench:perf
Token usage (summary) β full guide: packages/mcp-server/README.md#token-usage
| What | How |
|---|---|
| Tool response cost | Every JSON tool result includes usage.estimated_response_tokens (+ _meta["woo.usage"]) |
| Host model (Claude/GPT) cost | Call woo_model_usage_record after each API round, or use exported ModelUsageTracker |
| Session audit | woo_usage_stats returns tool + model totals for the process |
| Low-cost Anthropic smoke | node packages/mcp-server/scripts/anthropic-mcp-smoke.mjs (always prints token totals) |
Full package docs: packages/mcp-server/README.md
Claude Desktop snippet
{
"mcpServers": {
"woocommerce": {
"command": "npx",
"args": ["woo-mcp-server"],
"env": {
"WC_URL": "https://mystore.com",
"WC_KEY": "ck_xxxxxxxx",
"WC_SECRET": "cs_xxxxxxxx"
}
}
}
}Headless / storefront traffic uses a different WooCommerce surface than admin REST. This monorepo ships a dedicated client so concerns stay cleanly separated.
Admin (woocommerce-rest-ts-api) |
Store (woo-store-ts-api) |
|
|---|---|---|
| Namespace | wc/v3 |
wc/store/v1 |
| Auth | Consumer key + secret (OAuth) | Cart-Token (preferred) or Nonce |
| Audience | Back-office, ERP, MCP | Storefront, mobile, BFF |
| Typical ops | Products CRUD, orders, refunds, settings | Cart, coupons, shipping rates, checkout, catalog |
| Types | Admin product/order models | StoreCart, StoreProduct, StoreCheckout, β¦ |
Full package docs: packages/store-api/README.md
Store API reference (endpoints, tokens): docs/STORE_API.md
Design / issue: #62
pnpm add woo-store-ts-api
# monorepo: pnpm --filter woo-store-ts-api buildimport { WooCommerceStoreApi, StoreApiError } from "woo-store-ts-api";
const store = new WooCommerceStoreApi({
url: "https://shop.example",
// cartToken: process.env.CART_TOKEN, // optional restore
});
// Bootstrap session β captures Cart-Token from GET /cart response headers
await store.ensureSession();
const products = await store.products.list({ per_page: 10, on_sale: true });
const cart = await store.cart.addItem({
id: products[0]!.id,
quantity: 1,
variation: [], // simple products: empty array
});
await store.cart.updateCustomer({
billing_address: {
first_name: "Jane",
last_name: "Doe",
address_1: "1 Main St",
city: "Austin",
state: "TX",
postcode: "78701",
country: "US",
email: "jane@example.com",
},
});
const order = await store.checkout.process({ payment_method: "bacs" });
console.log(order.order_id, order.status, await store.getCartToken());| Resource | Methods |
|---|---|
| Session | ensureSession(), getCartToken(), session (CartSession: snapshot, headers, clear) |
| Cart | get, addItem, updateItem, removeItem, applyCoupon, removeCoupon, updateCustomer, selectShippingRate, listItems, clearItems |
| Products | list, get, collectionData, listCategories, listTags, listAttributes, listReviews |
| Checkout | get, process, update, payForOrder |
| Low-level | request(method, endpoint, opts?), batch(requests) β covers brands, order-by-key, coupon collection, attribute terms, etc. |
Session model: Cart-Token first (Nonce absorbed as fallback). Constructor rejects consumerKey / consumerSecret so admin credentials cannot be mixed in by accident.
Full endpoint β method matrix, types, errors, troubleshooting: packages/store-api/README.md Β· docs/STORE_API.md
import {
WooCommerceStoreApi,
type SessionStore,
type SessionSnapshot,
} from "woo-store-ts-api";
const store = new WooCommerceStoreApi({
url: "https://shop.example",
sessionStore: {
async get(): Promise<SessionSnapshot> {
return { cartToken: loadFromCookie(), nonce: null };
},
async set(s: SessionSnapshot) {
if (s.cartToken) saveToCookie(s.cartToken);
},
},
});import WooCommerceRestApi from "woocommerce-rest-ts-api";
import { WooCommerceStoreApi } from "woo-store-ts-api";
const admin = new WooCommerceRestApi({
url: process.env.WC_URL!,
consumerKey: process.env.WC_KEY!,
consumerSecret: process.env.WC_SECRET!,
version: "wc/v3",
});
const storefront = new WooCommerceStoreApi({ url: process.env.WC_URL! });
// Admin: back-office product
await admin.get("products", { id: 34 });
// Store: shopper cart (no keys)
await storefront.ensureSession();
await storefront.cart.addItem({ id: 34, quantity: 1 });pnpm --filter woo-store-ts-api build
pnpm --filter woo-store-ts-api test # or: pnpm test:store
pnpm --filter woo-store-ts-api typecheckProduction-grade TypeScript client with security hardening, modular types, DI-friendly internals, and tree-shakable ESM-first builds. High-severity Dependabot issues addressed via upgrades, overrides, and runtime sanitization β see SECURITY.md and MIGRATION.md.
- Type-safe β comprehensive TypeScript definitions and
WooCommerceApiResponse<T> - Modern β ES2020+, async/await, full ESM + CommonJS dual build
- Secure β OAuth 1.0a + path sanitization, resource limits, hardened HTTP stack
- Resilient β pluggable throttling & 429-aware retries, timeouts, keep-alive
- Modular β separated types,
RequestSanitizer,ErrorNormalizer,PaginationHelper - DX β convenience methods for common product/order flows
- Complete Dependabot resolution for high/critical transitive issues (see
SECURITY.md) - Runtime validation for
url/version/wpAPIPrefix/endpoint - Type layout under
src/types/{core,requests,responses,errors,models} - Deterministic nock-based test suite (live WC not required for CI)
pnpm (recommended β the project is now pnpm-exclusive):
pnpm add woocommerce-rest-ts-apinpm / yarn (still supported for consumers):
npm install --save woocommerce-rest-ts-api
# or
yarn add woocommerce-rest-ts-apiSee PERFORMANCE_SECURITY_AUDIT.md and FINAL_REVIEW.md for the latest production-grade analysis. New reusable helpers (collectAllPages, parsePaginationHeaders) are exported for pagination use-cases.
Generate API credentials (Consumer Key & Consumer Secret) following this instructions http://docs.woocommerce.com/document/woocommerce-rest-api/.
Check out the WooCommerce API endpoints and data that can be manipulated in http://woocommerce.github.io/woocommerce-rest-api-docs/.
import WooCommerceRestApi, { WooRestApiOptions } from "woocommerce-rest-ts-api";
const options: WooRestApiOptions = {
url: "https://your-store.com",
consumerKey: "ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumerSecret: "cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
version: "wc/v3",
queryStringAuth: false // Force Basic Authentication as query string when using HTTPS
};
const api = new WooCommerceRestApi(options);const WooCommerceRestApi = require("woocommerce-rest-ts-api").default;
const api = new WooCommerceRestApi({
url: "https://your-store.com",
consumerKey: "ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumerSecret: "cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
version: "wc/v3",
queryStringAuth: false
});| Option | Type | Required | Description |
|---|---|---|---|
url |
String |
yes | Your Store URL, example: https://your-store.com |
consumerKey |
String |
yes | Your API consumer key |
consumerSecret |
String |
yes | Your API consumer secret |
wpAPIPrefix |
String |
no | Custom WP REST API URL prefix, used to support custom prefixes created with the rest_url_prefix filter |
version |
String |
no | API version, default is wc/v3 |
encoding |
String |
no | Encoding, default is 'utf-8' |
queryStringAuth |
Bool |
no | When true and using under HTTPS force Basic Authentication as query string, default is false |
port |
string |
no | Provide support for URLs with ports, eg: 8080 |
timeout |
Integer |
no | Define the request timeout (enforced default: 30000ms if unset) |
axiosConfig |
Object |
no | Define the custom Axios config, also override this library options |
maxContentLength |
Integer |
no | Max response body size (bytes). Default 10MB. Mitigates resource exhaustion (CVE-2026-44488). -1 disables. |
maxBodyLength |
Integer |
no | Max request body size (bytes). Default 10MB. |
maxConcurrentRequests |
Integer |
no | Max in-flight requests for client throttling (0=unlimited, default for compat). Enables internal queue. |
retryConfig |
Object |
no | {retries?: number, retryDelay?: number, retryOn?: number[]} for exp backoff + 429/RateLimit awareness. Default: 0 (disabled). Recommended: retries:3+ for production resilience against rate limits/transients. |
All API methods now return a WooCommerceApiResponse<T> object with the following structure:
interface WooCommerceApiResponse<T> {
data: T; // The actual response data
status: number; // HTTP status code
statusText: string; // HTTP status text
headers: any; // Response headers
}The library now includes enhanced error handling with custom error classes:
import { WooCommerceApiError, AuthenticationError } from "woocommerce-rest-ts-api";
try {
const products = await api.getProducts();
} catch (error) {
if (error instanceof WooCommerceApiError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
console.error('Endpoint:', error.endpoint);
console.error('Response:', error.response);
} else if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.message);
}
}This library fully addresses the high-severity Axios CVE-2026-44488 ("Allocation of Resources Without Limits or Throttling").
- Axios upgraded to 1.18.0 (the secure version that properly enforces body limits under the fetch adapter as well as the http adapter).
- Resource limits (
maxContentLength/maxBodyLength) default to 10 MiB in the core_requestimplementation. These are always applied and respected even when users supplyaxiosConfig. - Timeout enforcement: 30 second default timeout is applied when none is configured.
- Throttling:
maxConcurrentRequestsoption + internal semaphore/queue in the HTTP client. - Resilience: Automatic retries (default 3) using exponential backoff + jitter. 429 responses intelligently respect
Retry-Afterheaders for rate-limit awareness.
const api = new WooCommerceRestApi({
url: "https://your-store.com",
consumerKey: "...",
consumerSecret: "...",
// Security / resilience options (all optional; safe defaults applied)
timeout: 45000,
maxContentLength: 5 * 1024 * 1024, // 5MB responses
maxBodyLength: 2 * 1024 * 1024, // 2MB uploads
maxConcurrentRequests: 4, // Throttle to 4 parallel requests
retryConfig: {
retries: 3, // Enable for resilience (default 0 for strict backward compat)
retryDelay: 800,
retryOn: [429, 500, 502, 503, 504]
},
// You can still pass raw axios options (they take precedence for provided keys)
axiosConfig: {
// headers, adapter, etc.
}
});Recommendation: Leave the size limits at their defaults (or lower them) unless you have a legitimate need for very large payloads. Never set to -1 in untrusted environments.
The implementation lives in the _request method and honors values passed through axiosConfig while providing safe library-level guardrails.
The project performed a complete audit for Dependabot #91 (Handlebars.js "JavaScript Injection via AST Type Confusion", CVE-2026-33937). handlebars is not used by this library for any templating, error messages, logs, or dynamic content (runtime or tests). It exists only as an indirect devDependency of conventional-changelog-writer (used by semantic-release to produce changelog entries from commit messages at release time, using only trusted inputs).
To resolve the vulnerability in the tooling chain:
- Added top-level
"overrides": { "handlebars": "^4.7.9" }inpackage.json(supported by both npm and pnpm). - This pins the secure version (4.7.9+) that includes the necessary AST type validation fixes.
- Updated lockfiles accordingly. No production impact, no code changes required, full backward compatibility preserved. See the Security section of CHANGELOG.md for the exhaustive audit details and verification steps performed.
const response = await api.get<ProductType[]>("products", { per_page: 10 });const response = await api.post<ProductType>("products", productData);const response = await api.put<ProductType>("products", updateData, { id: 123 });const response = await api.delete<ProductType>("products", { force: true }, { id: 123 });const response = await api.options("products");// Get all products with type safety
const products = await api.getProducts({ per_page: 20, status: 'publish' });
// Get a single product
const product = await api.getProduct(123);
// Create a new product
const newProduct = await api.createProduct({
name: "New Product",
type: "simple",
regular_price: "29.99"
});
// Update a product
const updatedProduct = await api.updateProduct(123, {
name: "Updated Product Name"
});// Get all orders
const orders = await api.getOrders({ status: 'processing' });
// Get a single order
const order = await api.getOrder(123);
// Create a new order
const newOrder = await api.createOrder({
payment_method: "bacs",
billing: {
first_name: "John",
last_name: "Doe",
// ... other billing details
},
line_items: [
{
product_id: 93,
quantity: 2
}
]
});// Get all customers
const customers = await api.getCustomers();
// Get a single customer
const customer = await api.getCustomer(123);// Get coupons
const coupons = await api.getCoupons();
// Get system status
const systemStatus = await api.getSystemStatus();import WooCommerceRestApi, {
WooRestApiOptions,
Products,
WooCommerceApiError
} from "woocommerce-rest-ts-api";
const api = new WooCommerceRestApi({
url: "https://your-store.com",
consumerKey: "ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumerSecret: "cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
version: "wc/v3"
});
async function manageProducts() {
try {
// List products with pagination
const products = await api.getProducts({
per_page: 20,
page: 1,
status: 'publish'
});
console.log(`Found ${products.data.length} products`);
console.log(`Total pages: ${products.headers['x-wp-totalpages']}`);
// Create a new product
const newProduct = await api.createProduct({
name: "Premium Quality Product",
type: "simple",
regular_price: "29.99",
description: "A premium quality product description",
short_description: "Premium quality product",
categories: [{ id: 9 }],
images: [{
src: "https://example.com/image.jpg"
}]
});
console.log(`Created product with ID: ${newProduct.data.id}`);
// Update the product
const updatedProduct = await api.updateProduct(newProduct.data.id, {
regular_price: "39.99",
sale_price: "34.99"
});
console.log(`Updated product price to: ${updatedProduct.data.regular_price}`);
} catch (error) {
if (error instanceof WooCommerceApiError) {
console.error(`API Error: ${error.message} (Status: ${error.statusCode})`);
} else {
console.error('Unexpected error:', error);
}
}
}
manageProducts();async function manageOrders() {
try {
// Get recent orders
const orders = await api.getOrders({
status: 'processing',
orderby: 'date',
order: 'desc',
per_page: 10
});
console.log(`Found ${orders.data.length} processing orders`);
// Create a new order
const newOrder = await api.createOrder({
payment_method: "bacs",
payment_method_title: "Direct Bank Transfer",
set_paid: true,
billing: {
first_name: "John",
last_name: "Doe",
address_1: "969 Market",
city: "San Francisco",
state: "CA",
postcode: "94103",
country: "US",
email: "john.doe@example.com",
phone: "555-555-5555"
},
line_items: [
{
product_id: 93,
quantity: 2
}
]
});
console.log(`Created order with ID: ${newOrder.data.id}`);
} catch (error) {
if (error instanceof WooCommerceApiError) {
console.error(`Order creation failed: ${error.message}`);
}
}
}The library includes comprehensive TypeScript definitions for all WooCommerce entities:
Products- Product data structureOrders- Order data structureCustomers- Customer data structureCoupons- Coupon data structureSystemStatus- System status data structure- And many more...
WooCommerceApiError- General API errors with status codes and response dataAuthenticationError- Authentication-specific errorsOptionsException- Configuration/setup errors
If you're upgrading from an earlier version, note these changes:
- No Breaking Changes: Fully backward compatible. New security/resilience options (
max*Length,maxConcurrentRequests,retryConfig) are optional. - Axios Upgrade:
axiosis now ^1.18.0. All prioraxiosConfigusage continues to work. - Improved Resilience (opt-in controls): Timeouts, body limits, throttling and retries are now active with safe defaults. Existing behavior for explicitly supplied
timeoutetc. is preserved.
- No Breaking Changes: v7.1.0 is fully backward compatible
- Improved Stability: Better build process and dependency management
- Enhanced Tooling: Updated TypeScript and ESLint configurations
- Response Structure: All methods now return
WooCommerceApiResponse<T>instead of raw Axios responses - Error Handling: New custom error classes replace generic errors
- Convenience Methods: New methods like
getProducts(),getOrders()etc. are available - Type Safety: Better TypeScript support with generic types
- π‘οΈ CVE-2026-44488: Axios upgraded to 1.18.0. Full implementation of request throttling, enforced timeouts (default 30s), 10MB body size limits, and exponential backoff retry logic (opt-in via retryConfig, default 0 for compat) inside
_request+axiosConfig. - All existing authentication, convenience methods, and error handling remain 100% backward compatible.
- Added
maxContentLength,maxBodyLength,maxConcurrentRequests,retryConfigoptions + comprehensive docs + CHANGELOG. - Verified: clean build, type-check, lint, and tests.
- β¨ Added enhanced error handling with custom error classes
- π§ Improved type safety with
WooCommerceApiResponse<T> - π Added convenience methods for common operations
- π¦ Fixed TypeScript configuration issues and ESLint compatibility
- π‘οΈ Better input validation and error messages
- π§ Resolved build and publishing pipeline issues
- π Updated to TypeScript 5.8.3 with latest dependencies
- π― Improved developer experience with better tooling
We welcome contributions via pull requests.
- AI PR reviews (free): open a non-draft PR and CodeRabbit reviews it automatically on the free public-repo tier. Setup and commands: docs/CODERABBIT.md. Config:
.coderabbit.yaml. - Publishing: docs/PUBLISHING.md
- Security: SECURITY.md
This project is licensed under the MIT License - see the LICENSE file for details.
woocommerce-rest-api-ts-lib/
βββ src/ # Admin REST client (woocommerce-rest-ts-api, wc/v3)
βββ packages/
β βββ mcp-server/ # woo-mcp-server (MCP tools over admin REST)
β βββ store-api/ # woo-store-ts-api (Store API client, wc/store/v1)
βββ docs/
β βββ STORE_API.md # Store API endpoint / token reference
β βββ PUBLISHING.md # npm dual/triple package publish
β βββ CODERABBIT.md
βββ scripts/live-wc/ # Free Docker WooCommerce for live tests
βββ ui/
βββ presentation.html # Developer slide deck (make ui-presentation)
βββ index.html # MCP tool explorer (make ui)
- WooCommerce REST API Documentation
- WooCommerce Store API
- Model Context Protocol
- Axios HTTP Client
- TypeScript
- OAuth 1.0a
If you need help or have questions, please:
- Check the WooCommerce REST API Documentation (admin) or Store API (cart/checkout)
- Package guides: admin README Β· store-api README Β· MCP README
- Open an issue on GitHub
- Contact via email (use subject: "WooCommerce TS Library - [Your Issue]")
| Name | |
|---|---|
| Yuri Lima | y.m.lima19@gmail.com |
Made with β€οΈ by Yuri Lima
