claude-plugin-wordpress-manager 1.7.2 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.claude-plugin/plugin.json +7 -3
  2. package/CHANGELOG.md +55 -0
  3. package/agents/wp-ecommerce-manager.md +136 -0
  4. package/agents/wp-site-manager.md +27 -0
  5. package/docs/plans/2026-02-28-multisite-v1.9.0-design.md +258 -0
  6. package/docs/plans/2026-02-28-multisite-v1.9.0.md +1604 -0
  7. package/docs/plans/2026-02-28-roadmap-v1.8-v2.1-design.md +314 -0
  8. package/docs/plans/2026-02-28-woocommerce-v1.8.0.md +2012 -0
  9. package/package.json +8 -3
  10. package/servers/wp-rest-bridge/build/tools/index.d.ts +1187 -0
  11. package/servers/wp-rest-bridge/build/tools/index.js +26 -2
  12. package/servers/wp-rest-bridge/build/tools/multisite-network.d.ts +132 -0
  13. package/servers/wp-rest-bridge/build/tools/multisite-network.js +157 -0
  14. package/servers/wp-rest-bridge/build/tools/multisite-sites.d.ts +150 -0
  15. package/servers/wp-rest-bridge/build/tools/multisite-sites.js +160 -0
  16. package/servers/wp-rest-bridge/build/tools/wc-coupons.d.ts +144 -0
  17. package/servers/wp-rest-bridge/build/tools/wc-coupons.js +92 -0
  18. package/servers/wp-rest-bridge/build/tools/wc-customers.d.ts +141 -0
  19. package/servers/wp-rest-bridge/build/tools/wc-customers.js +92 -0
  20. package/servers/wp-rest-bridge/build/tools/wc-orders.d.ts +186 -0
  21. package/servers/wp-rest-bridge/build/tools/wc-orders.js +128 -0
  22. package/servers/wp-rest-bridge/build/tools/wc-products.d.ts +324 -0
  23. package/servers/wp-rest-bridge/build/tools/wc-products.js +177 -0
  24. package/servers/wp-rest-bridge/build/tools/wc-reports.d.ts +117 -0
  25. package/servers/wp-rest-bridge/build/tools/wc-reports.js +94 -0
  26. package/servers/wp-rest-bridge/build/tools/wc-settings.d.ts +72 -0
  27. package/servers/wp-rest-bridge/build/tools/wc-settings.js +70 -0
  28. package/servers/wp-rest-bridge/build/types.d.ts +98 -0
  29. package/servers/wp-rest-bridge/build/wordpress.d.ts +28 -0
  30. package/servers/wp-rest-bridge/build/wordpress.js +85 -0
  31. package/servers/wp-rest-bridge/build/wpcli.d.ts +23 -0
  32. package/servers/wp-rest-bridge/build/wpcli.js +72 -0
  33. package/skills/wordpress-router/references/decision-tree.md +6 -2
  34. package/skills/wp-audit/SKILL.md +1 -0
  35. package/skills/wp-backup/SKILL.md +1 -0
  36. package/skills/wp-deploy/SKILL.md +1 -0
  37. package/skills/wp-multisite/SKILL.md +92 -0
  38. package/skills/wp-multisite/references/domain-mapping.md +70 -0
  39. package/skills/wp-multisite/references/migration-multisite.md +76 -0
  40. package/skills/wp-multisite/references/network-plugins.md +66 -0
  41. package/skills/wp-multisite/references/network-setup.md +69 -0
  42. package/skills/wp-multisite/references/site-management.md +67 -0
  43. package/skills/wp-multisite/references/user-roles.md +73 -0
  44. package/skills/wp-multisite/scripts/multisite_inspect.mjs +160 -0
  45. package/skills/wp-security/SKILL.md +4 -0
  46. package/skills/wp-woocommerce/SKILL.md +110 -0
  47. package/skills/wp-woocommerce/references/analytics-reports.md +75 -0
  48. package/skills/wp-woocommerce/references/coupon-marketing.md +92 -0
  49. package/skills/wp-woocommerce/references/order-workflow.md +88 -0
  50. package/skills/wp-woocommerce/references/payment-gateways.md +69 -0
  51. package/skills/wp-woocommerce/references/product-management.md +61 -0
  52. package/skills/wp-woocommerce/references/shipping-setup.md +79 -0
  53. package/skills/wp-woocommerce/references/tax-configuration.md +91 -0
  54. package/skills/wp-woocommerce/references/wc-extensions.md +97 -0
  55. package/skills/wp-woocommerce/scripts/woocommerce_inspect.mjs +181 -0
  56. package/skills/wp-wpcli-and-ops/SKILL.md +4 -0
@@ -0,0 +1,2012 @@
1
+ # WooCommerce v1.8.0 Implementation Plan
2
+
3
+ > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
4
+
5
+ **Goal:** Add WooCommerce management to wordpress-manager plugin — 30 new MCP tools, skill, agent, and detection script.
6
+
7
+ **Architecture:** Extend WP REST Bridge with WC-specific authentication (Consumer Key/Secret via separate AxiosInstance), create 6 TypeScript tool files using `wc/v3` namespace, add `wp-woocommerce` skill with 8 reference files, `wp-ecommerce-manager` agent, and `woocommerce_inspect.mjs` detection script.
8
+
9
+ **Tech Stack:** TypeScript, zod, axios, MCP SDK, Node.js ESM (.mjs)
10
+
11
+ ---
12
+
13
+ ### Task 1: Extend types.ts with WooCommerce types
14
+
15
+ **Files:**
16
+ - Modify: `servers/wp-rest-bridge/src/types.ts` (append after line 174)
17
+
18
+ **Step 1: Add WC types**
19
+
20
+ Append at end of file:
21
+
22
+ ```typescript
23
+ // ── WooCommerce Types ──────────────────────────────────────────────
24
+
25
+ export interface WCProduct {
26
+ id: number;
27
+ name: string;
28
+ slug: string;
29
+ type: string;
30
+ status: string;
31
+ description: string;
32
+ short_description: string;
33
+ sku: string;
34
+ price: string;
35
+ regular_price: string;
36
+ sale_price: string;
37
+ stock_quantity: number | null;
38
+ stock_status: string;
39
+ categories: { id: number; name: string; slug: string }[];
40
+ tags: { id: number; name: string; slug: string }[];
41
+ images: { id: number; src: string; name: string; alt: string }[];
42
+ attributes: { id: number; name: string; options: string[] }[];
43
+ variations: number[];
44
+ date_created: string;
45
+ date_modified: string;
46
+ }
47
+
48
+ export interface WCOrder {
49
+ id: number;
50
+ status: string;
51
+ currency: string;
52
+ total: string;
53
+ customer_id: number;
54
+ billing: Record<string, string>;
55
+ shipping: Record<string, string>;
56
+ line_items: { id: number; name: string; product_id: number; quantity: number; total: string }[];
57
+ date_created: string;
58
+ date_modified: string;
59
+ payment_method: string;
60
+ payment_method_title: string;
61
+ }
62
+
63
+ export interface WCCustomer {
64
+ id: number;
65
+ email: string;
66
+ first_name: string;
67
+ last_name: string;
68
+ username: string;
69
+ billing: Record<string, string>;
70
+ shipping: Record<string, string>;
71
+ orders_count: number;
72
+ total_spent: string;
73
+ date_created: string;
74
+ }
75
+
76
+ export interface WCCoupon {
77
+ id: number;
78
+ code: string;
79
+ discount_type: string;
80
+ amount: string;
81
+ date_created: string;
82
+ date_expires: string | null;
83
+ usage_count: number;
84
+ usage_limit: number | null;
85
+ individual_use: boolean;
86
+ product_ids: number[];
87
+ minimum_amount: string;
88
+ maximum_amount: string;
89
+ }
90
+ ```
91
+
92
+ **Step 2: Compile check**
93
+
94
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
95
+ Expected: No errors
96
+
97
+ **Step 3: Commit**
98
+
99
+ ```bash
100
+ git add servers/wp-rest-bridge/src/types.ts
101
+ git commit -m "feat(wc): add WooCommerce types (WCProduct, WCOrder, WCCustomer, WCCoupon)
102
+
103
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
104
+ ```
105
+
106
+ ---
107
+
108
+ ### Task 2: Extend wordpress.ts with WC auth infrastructure
109
+
110
+ **Files:**
111
+ - Modify: `servers/wp-rest-bridge/src/wordpress.ts`
112
+
113
+ **Step 1: Extend SiteConfig** (line 4-9)
114
+
115
+ Replace:
116
+ ```typescript
117
+ interface SiteConfig {
118
+ id: string;
119
+ url: string;
120
+ username: string;
121
+ password: string;
122
+ }
123
+ ```
124
+
125
+ With:
126
+ ```typescript
127
+ interface SiteConfig {
128
+ id: string;
129
+ url: string;
130
+ username: string;
131
+ password: string;
132
+ wc_consumer_key?: string;
133
+ wc_consumer_secret?: string;
134
+ }
135
+ ```
136
+
137
+ **Step 2: Add wcSiteClients map** (after line 41, after `siteLimiters`)
138
+
139
+ ```typescript
140
+ const wcSiteClients = new Map<string, AxiosInstance>();
141
+ ```
142
+
143
+ **Step 3: Add initWcClient function** (after `initSiteClient` function, after line 139)
144
+
145
+ ```typescript
146
+ /**
147
+ * Initialize a WooCommerce client for a site (Consumer Key/Secret auth).
148
+ */
149
+ async function initWcClient(id: string, url: string, consumerKey: string, consumerSecret: string) {
150
+ let baseURL = url.endsWith('/') ? url : `${url}/`;
151
+ const wpJsonIdx = baseURL.indexOf('/wp-json');
152
+ if (wpJsonIdx !== -1) {
153
+ baseURL = baseURL.substring(0, wpJsonIdx + 1);
154
+ }
155
+ baseURL = baseURL + 'wp-json/';
156
+
157
+ const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64');
158
+ const client = axios.create({
159
+ baseURL,
160
+ headers: {
161
+ 'Content-Type': 'application/json',
162
+ 'Authorization': `Basic ${auth}`,
163
+ },
164
+ timeout: DEFAULT_TIMEOUT_MS,
165
+ });
166
+
167
+ // Verify WooCommerce connection
168
+ try {
169
+ await client.get('wc/v3');
170
+ } catch (error: any) {
171
+ logToStderr(`Warning: Could not verify WooCommerce connection for ${id}: ${error.message}`);
172
+ }
173
+
174
+ wcSiteClients.set(id, client);
175
+ }
176
+ ```
177
+
178
+ **Step 4: Initialize WC clients in initWordPress()** (after the `for` loop at line 93, before `activeSiteId =`)
179
+
180
+ ```typescript
181
+ // Initialize WooCommerce clients for sites with WC credentials
182
+ for (const site of sites) {
183
+ if (site.wc_consumer_key && site.wc_consumer_secret) {
184
+ await initWcClient(site.id, site.url, site.wc_consumer_key, site.wc_consumer_secret);
185
+ logToStderr(`Initialized WooCommerce for site: ${site.id}`);
186
+ }
187
+ }
188
+ ```
189
+
190
+ **Step 5: Add WC request functions** (before `// ── Plugin Repository` section)
191
+
192
+ ```typescript
193
+ // ── WooCommerce Request Interface ────────────────────────────────
194
+
195
+ /**
196
+ * Check if a site has WooCommerce credentials configured.
197
+ */
198
+ export function hasWooCommerce(siteId?: string): boolean {
199
+ const id = siteId || activeSiteId;
200
+ return wcSiteClients.has(id);
201
+ }
202
+
203
+ /**
204
+ * Get the WooCommerce client for a site.
205
+ */
206
+ function getWcClient(siteId?: string): AxiosInstance {
207
+ const id = siteId || activeSiteId;
208
+ const client = wcSiteClients.get(id);
209
+ if (!client) {
210
+ throw new Error(
211
+ `WooCommerce not configured for site "${id}". ` +
212
+ `Add wc_consumer_key and wc_consumer_secret to WP_SITES_CONFIG.`
213
+ );
214
+ }
215
+ return client;
216
+ }
217
+
218
+ /**
219
+ * Make a request to the WooCommerce REST API.
220
+ * Uses Consumer Key/Secret auth and wc/v3 namespace by default.
221
+ */
222
+ export async function makeWooCommerceRequest(
223
+ method: string,
224
+ endpoint: string,
225
+ data?: any,
226
+ options?: WordPressRequestOptions
227
+ ): Promise<any> {
228
+ const siteId = options?.siteId || activeSiteId;
229
+ const client = getWcClient(siteId);
230
+ const limiter = getLimiter(siteId);
231
+ const namespace = options?.namespace || 'wc/v3';
232
+
233
+ const cleanEndpoint = endpoint.startsWith('/') ? endpoint.substring(1) : endpoint;
234
+ const path = `${namespace}/${cleanEndpoint}`;
235
+
236
+ await limiter.acquire();
237
+ try {
238
+ return await executeWithRetry(client, method, path, data, siteId, options);
239
+ } finally {
240
+ limiter.release();
241
+ }
242
+ }
243
+ ```
244
+
245
+ **Step 6: Compile check**
246
+
247
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
248
+ Expected: No errors
249
+
250
+ **Step 7: Commit**
251
+
252
+ ```bash
253
+ git add servers/wp-rest-bridge/src/wordpress.ts
254
+ git commit -m "feat(wc): add WooCommerce auth infrastructure to WP REST Bridge
255
+
256
+ - Extend SiteConfig with optional wc_consumer_key/wc_consumer_secret
257
+ - Add wcSiteClients map + initWcClient() for Consumer Key/Secret auth
258
+ - Add makeWooCommerceRequest() reusing executeWithRetry() logic
259
+ - Add hasWooCommerce() utility for credential detection
260
+
261
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
262
+ ```
263
+
264
+ ---
265
+
266
+ ### Task 3: Create wc-products.ts (7 tools)
267
+
268
+ **Files:**
269
+ - Create: `servers/wp-rest-bridge/src/tools/wc-products.ts`
270
+
271
+ **Step 1: Write the complete file**
272
+
273
+ ```typescript
274
+ // src/tools/wc-products.ts
275
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
276
+ import { makeWooCommerceRequest } from '../wordpress.js';
277
+ import { z } from 'zod';
278
+
279
+ // ── Schemas ──────────────────────────────────────────────────────────
280
+
281
+ const wcListProductsSchema = z.object({
282
+ per_page: z.number().optional().default(10).describe("Results per page (1-100)"),
283
+ page: z.number().optional().default(1).describe("Page number"),
284
+ search: z.string().optional().describe("Search products by keyword"),
285
+ status: z.enum(['draft', 'pending', 'private', 'publish', 'any']).optional().describe("Product status filter"),
286
+ category: z.number().optional().describe("Filter by category ID"),
287
+ tag: z.number().optional().describe("Filter by tag ID"),
288
+ sku: z.string().optional().describe("Filter by exact SKU"),
289
+ stock_status: z.enum(['instock', 'outofstock', 'onbackorder']).optional().describe("Filter by stock status"),
290
+ orderby: z.enum(['date', 'id', 'title', 'slug', 'price', 'popularity', 'rating']).optional().describe("Sort by field"),
291
+ order: z.enum(['asc', 'desc']).optional().default('desc').describe("Sort order"),
292
+ }).strict();
293
+
294
+ const wcGetProductSchema = z.object({
295
+ id: z.number().describe("Product ID"),
296
+ }).strict();
297
+
298
+ const wcCreateProductSchema = z.object({
299
+ name: z.string().describe("Product name"),
300
+ type: z.enum(['simple', 'grouped', 'external', 'variable']).optional().default('simple').describe("Product type"),
301
+ status: z.enum(['draft', 'pending', 'private', 'publish']).optional().default('publish').describe("Product status"),
302
+ regular_price: z.string().optional().describe("Regular price (e.g. '19.99')"),
303
+ sale_price: z.string().optional().describe("Sale price"),
304
+ description: z.string().optional().describe("Full product description (HTML)"),
305
+ short_description: z.string().optional().describe("Short product description (HTML)"),
306
+ sku: z.string().optional().describe("Stock Keeping Unit"),
307
+ manage_stock: z.boolean().optional().describe("Enable stock management"),
308
+ stock_quantity: z.number().optional().describe("Stock quantity (requires manage_stock: true)"),
309
+ categories: z.array(z.object({ id: z.number() })).optional().describe("Category IDs, e.g. [{id: 15}]"),
310
+ tags: z.array(z.object({ id: z.number() })).optional().describe("Tag IDs, e.g. [{id: 3}]"),
311
+ images: z.array(z.object({ src: z.string() })).optional().describe("Image URLs, e.g. [{src: 'https://...'}]"),
312
+ }).strict();
313
+
314
+ const wcUpdateProductSchema = z.object({
315
+ id: z.number().describe("Product ID to update"),
316
+ name: z.string().optional().describe("Product name"),
317
+ status: z.enum(['draft', 'pending', 'private', 'publish']).optional().describe("Product status"),
318
+ regular_price: z.string().optional().describe("Regular price"),
319
+ sale_price: z.string().optional().describe("Sale price"),
320
+ description: z.string().optional().describe("Full description"),
321
+ short_description: z.string().optional().describe("Short description"),
322
+ sku: z.string().optional().describe("SKU"),
323
+ manage_stock: z.boolean().optional().describe("Enable stock management"),
324
+ stock_quantity: z.number().optional().describe("Stock quantity"),
325
+ stock_status: z.enum(['instock', 'outofstock', 'onbackorder']).optional().describe("Stock status"),
326
+ }).strict();
327
+
328
+ const wcDeleteProductSchema = z.object({
329
+ id: z.number().describe("Product ID to delete"),
330
+ force: z.boolean().optional().default(false).describe("True to permanently delete, false to move to trash"),
331
+ }).strict();
332
+
333
+ const wcListProductCategoriesSchema = z.object({
334
+ per_page: z.number().optional().default(10).describe("Results per page (1-100)"),
335
+ page: z.number().optional().default(1).describe("Page number"),
336
+ search: z.string().optional().describe("Search categories by keyword"),
337
+ parent: z.number().optional().describe("Filter by parent category ID"),
338
+ orderby: z.enum(['id', 'name', 'slug', 'count']).optional().describe("Sort by field"),
339
+ order: z.enum(['asc', 'desc']).optional().default('asc').describe("Sort order"),
340
+ }).strict();
341
+
342
+ const wcListProductVariationsSchema = z.object({
343
+ product_id: z.number().describe("Parent product ID"),
344
+ per_page: z.number().optional().default(10).describe("Results per page (1-100)"),
345
+ page: z.number().optional().default(1).describe("Page number"),
346
+ status: z.enum(['draft', 'pending', 'private', 'publish', 'any']).optional().describe("Variation status"),
347
+ }).strict();
348
+
349
+ // ── Tool Definitions ─────────────────────────────────────────────────
350
+
351
+ export const wcProductTools: Tool[] = [
352
+ {
353
+ name: "wc_list_products",
354
+ description: "Lists WooCommerce products with filtering, sorting, and pagination",
355
+ inputSchema: { type: "object", properties: wcListProductsSchema.shape },
356
+ },
357
+ {
358
+ name: "wc_get_product",
359
+ description: "Retrieves a single WooCommerce product by ID with full details",
360
+ inputSchema: { type: "object", properties: wcGetProductSchema.shape },
361
+ },
362
+ {
363
+ name: "wc_create_product",
364
+ description: "Creates a new WooCommerce product (simple, grouped, external, or variable)",
365
+ inputSchema: { type: "object", properties: wcCreateProductSchema.shape },
366
+ },
367
+ {
368
+ name: "wc_update_product",
369
+ description: "Updates an existing WooCommerce product's fields",
370
+ inputSchema: { type: "object", properties: wcUpdateProductSchema.shape },
371
+ },
372
+ {
373
+ name: "wc_delete_product",
374
+ description: "Deletes a WooCommerce product (trash or permanent)",
375
+ inputSchema: { type: "object", properties: wcDeleteProductSchema.shape },
376
+ },
377
+ {
378
+ name: "wc_list_product_categories",
379
+ description: "Lists WooCommerce product categories with hierarchy support",
380
+ inputSchema: { type: "object", properties: wcListProductCategoriesSchema.shape },
381
+ },
382
+ {
383
+ name: "wc_list_product_variations",
384
+ description: "Lists variations of a variable WooCommerce product",
385
+ inputSchema: { type: "object", properties: wcListProductVariationsSchema.shape },
386
+ },
387
+ ];
388
+
389
+ // ── Handlers ─────────────────────────────────────────────────────────
390
+
391
+ export const wcProductHandlers = {
392
+ wc_list_products: async (params: z.infer<typeof wcListProductsSchema>) => {
393
+ try {
394
+ const response = await makeWooCommerceRequest("GET", "products", params);
395
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
396
+ } catch (error: any) {
397
+ const errorMessage = error.response?.data?.message || error.message;
398
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing products: ${errorMessage}` }] } };
399
+ }
400
+ },
401
+
402
+ wc_get_product: async (params: z.infer<typeof wcGetProductSchema>) => {
403
+ try {
404
+ const response = await makeWooCommerceRequest("GET", `products/${params.id}`);
405
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
406
+ } catch (error: any) {
407
+ const errorMessage = error.response?.data?.message || error.message;
408
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error retrieving product: ${errorMessage}` }] } };
409
+ }
410
+ },
411
+
412
+ wc_create_product: async (params: z.infer<typeof wcCreateProductSchema>) => {
413
+ try {
414
+ const response = await makeWooCommerceRequest("POST", "products", params);
415
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
416
+ } catch (error: any) {
417
+ const errorMessage = error.response?.data?.message || error.message;
418
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error creating product: ${errorMessage}` }] } };
419
+ }
420
+ },
421
+
422
+ wc_update_product: async (params: z.infer<typeof wcUpdateProductSchema>) => {
423
+ try {
424
+ const { id, ...data } = params;
425
+ const response = await makeWooCommerceRequest("PUT", `products/${id}`, data);
426
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
427
+ } catch (error: any) {
428
+ const errorMessage = error.response?.data?.message || error.message;
429
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error updating product: ${errorMessage}` }] } };
430
+ }
431
+ },
432
+
433
+ wc_delete_product: async (params: z.infer<typeof wcDeleteProductSchema>) => {
434
+ try {
435
+ const response = await makeWooCommerceRequest("DELETE", `products/${params.id}`, { force: params.force });
436
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
437
+ } catch (error: any) {
438
+ const errorMessage = error.response?.data?.message || error.message;
439
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error deleting product: ${errorMessage}` }] } };
440
+ }
441
+ },
442
+
443
+ wc_list_product_categories: async (params: z.infer<typeof wcListProductCategoriesSchema>) => {
444
+ try {
445
+ const response = await makeWooCommerceRequest("GET", "products/categories", params);
446
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
447
+ } catch (error: any) {
448
+ const errorMessage = error.response?.data?.message || error.message;
449
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing product categories: ${errorMessage}` }] } };
450
+ }
451
+ },
452
+
453
+ wc_list_product_variations: async (params: z.infer<typeof wcListProductVariationsSchema>) => {
454
+ try {
455
+ const { product_id, ...queryParams } = params;
456
+ const response = await makeWooCommerceRequest("GET", `products/${product_id}/variations`, queryParams);
457
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
458
+ } catch (error: any) {
459
+ const errorMessage = error.response?.data?.message || error.message;
460
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing product variations: ${errorMessage}` }] } };
461
+ }
462
+ },
463
+ };
464
+ ```
465
+
466
+ **Step 2: Compile check**
467
+
468
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
469
+ Expected: No errors
470
+
471
+ **Step 3: Commit**
472
+
473
+ ```bash
474
+ git add servers/wp-rest-bridge/src/tools/wc-products.ts
475
+ git commit -m "feat(wc): add wc-products.ts — 7 WooCommerce product tools
476
+
477
+ CRUD products, list categories, list variations.
478
+
479
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
480
+ ```
481
+
482
+ ---
483
+
484
+ ### Task 4: Create wc-orders.ts (6 tools)
485
+
486
+ **Files:**
487
+ - Create: `servers/wp-rest-bridge/src/tools/wc-orders.ts`
488
+
489
+ **Step 1: Write the complete file**
490
+
491
+ ```typescript
492
+ // src/tools/wc-orders.ts
493
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
494
+ import { makeWooCommerceRequest } from '../wordpress.js';
495
+ import { z } from 'zod';
496
+
497
+ const wcListOrdersSchema = z.object({
498
+ per_page: z.number().optional().default(10).describe("Results per page (1-100)"),
499
+ page: z.number().optional().default(1).describe("Page number"),
500
+ status: z.enum(['pending', 'processing', 'on-hold', 'completed', 'cancelled', 'refunded', 'failed', 'trash', 'any']).optional().describe("Order status filter"),
501
+ customer: z.number().optional().describe("Filter by customer ID"),
502
+ after: z.string().optional().describe("Orders after date (ISO 8601)"),
503
+ before: z.string().optional().describe("Orders before date (ISO 8601)"),
504
+ orderby: z.enum(['date', 'id', 'title', 'slug']).optional().describe("Sort by field"),
505
+ order: z.enum(['asc', 'desc']).optional().default('desc').describe("Sort order"),
506
+ }).strict();
507
+
508
+ const wcGetOrderSchema = z.object({
509
+ id: z.number().describe("Order ID"),
510
+ }).strict();
511
+
512
+ const wcUpdateOrderStatusSchema = z.object({
513
+ id: z.number().describe("Order ID"),
514
+ status: z.enum(['pending', 'processing', 'on-hold', 'completed', 'cancelled', 'refunded', 'failed']).describe("New order status"),
515
+ }).strict();
516
+
517
+ const wcListOrderNotesSchema = z.object({
518
+ order_id: z.number().describe("Order ID"),
519
+ }).strict();
520
+
521
+ const wcCreateOrderNoteSchema = z.object({
522
+ order_id: z.number().describe("Order ID"),
523
+ note: z.string().describe("Note content"),
524
+ customer_note: z.boolean().optional().default(false).describe("If true, note is visible to customer"),
525
+ }).strict();
526
+
527
+ const wcCreateRefundSchema = z.object({
528
+ order_id: z.number().describe("Order ID"),
529
+ amount: z.string().describe("Refund amount (e.g. '9.99')"),
530
+ reason: z.string().optional().describe("Reason for refund"),
531
+ }).strict();
532
+
533
+ export const wcOrderTools: Tool[] = [
534
+ {
535
+ name: "wc_list_orders",
536
+ description: "Lists WooCommerce orders with filtering by status, customer, and date range",
537
+ inputSchema: { type: "object", properties: wcListOrdersSchema.shape },
538
+ },
539
+ {
540
+ name: "wc_get_order",
541
+ description: "Retrieves a single WooCommerce order with full details including line items",
542
+ inputSchema: { type: "object", properties: wcGetOrderSchema.shape },
543
+ },
544
+ {
545
+ name: "wc_update_order_status",
546
+ description: "Updates the status of a WooCommerce order (e.g. processing to completed)",
547
+ inputSchema: { type: "object", properties: wcUpdateOrderStatusSchema.shape },
548
+ },
549
+ {
550
+ name: "wc_list_order_notes",
551
+ description: "Lists all notes for a WooCommerce order",
552
+ inputSchema: { type: "object", properties: wcListOrderNotesSchema.shape },
553
+ },
554
+ {
555
+ name: "wc_create_order_note",
556
+ description: "Adds a note to a WooCommerce order (internal or customer-visible)",
557
+ inputSchema: { type: "object", properties: wcCreateOrderNoteSchema.shape },
558
+ },
559
+ {
560
+ name: "wc_create_refund",
561
+ description: "Creates a refund for a WooCommerce order",
562
+ inputSchema: { type: "object", properties: wcCreateRefundSchema.shape },
563
+ },
564
+ ];
565
+
566
+ export const wcOrderHandlers = {
567
+ wc_list_orders: async (params: z.infer<typeof wcListOrdersSchema>) => {
568
+ try {
569
+ const response = await makeWooCommerceRequest("GET", "orders", params);
570
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
571
+ } catch (error: any) {
572
+ const errorMessage = error.response?.data?.message || error.message;
573
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing orders: ${errorMessage}` }] } };
574
+ }
575
+ },
576
+
577
+ wc_get_order: async (params: z.infer<typeof wcGetOrderSchema>) => {
578
+ try {
579
+ const response = await makeWooCommerceRequest("GET", `orders/${params.id}`);
580
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
581
+ } catch (error: any) {
582
+ const errorMessage = error.response?.data?.message || error.message;
583
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error retrieving order: ${errorMessage}` }] } };
584
+ }
585
+ },
586
+
587
+ wc_update_order_status: async (params: z.infer<typeof wcUpdateOrderStatusSchema>) => {
588
+ try {
589
+ const response = await makeWooCommerceRequest("PUT", `orders/${params.id}`, { status: params.status });
590
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
591
+ } catch (error: any) {
592
+ const errorMessage = error.response?.data?.message || error.message;
593
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error updating order status: ${errorMessage}` }] } };
594
+ }
595
+ },
596
+
597
+ wc_list_order_notes: async (params: z.infer<typeof wcListOrderNotesSchema>) => {
598
+ try {
599
+ const response = await makeWooCommerceRequest("GET", `orders/${params.order_id}/notes`);
600
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
601
+ } catch (error: any) {
602
+ const errorMessage = error.response?.data?.message || error.message;
603
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing order notes: ${errorMessage}` }] } };
604
+ }
605
+ },
606
+
607
+ wc_create_order_note: async (params: z.infer<typeof wcCreateOrderNoteSchema>) => {
608
+ try {
609
+ const { order_id, ...data } = params;
610
+ const response = await makeWooCommerceRequest("POST", `orders/${order_id}/notes`, data);
611
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
612
+ } catch (error: any) {
613
+ const errorMessage = error.response?.data?.message || error.message;
614
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error creating order note: ${errorMessage}` }] } };
615
+ }
616
+ },
617
+
618
+ wc_create_refund: async (params: z.infer<typeof wcCreateRefundSchema>) => {
619
+ try {
620
+ const { order_id, ...data } = params;
621
+ const response = await makeWooCommerceRequest("POST", `orders/${order_id}/refunds`, data);
622
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
623
+ } catch (error: any) {
624
+ const errorMessage = error.response?.data?.message || error.message;
625
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error creating refund: ${errorMessage}` }] } };
626
+ }
627
+ },
628
+ };
629
+ ```
630
+
631
+ **Step 2: Compile check**
632
+
633
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
634
+ Expected: No errors
635
+
636
+ **Step 3: Commit**
637
+
638
+ ```bash
639
+ git add servers/wp-rest-bridge/src/tools/wc-orders.ts
640
+ git commit -m "feat(wc): add wc-orders.ts — 6 WooCommerce order tools
641
+
642
+ List, get, update status, notes, refunds.
643
+
644
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
645
+ ```
646
+
647
+ ---
648
+
649
+ ### Task 5: Create wc-customers.ts (4 tools)
650
+
651
+ **Files:**
652
+ - Create: `servers/wp-rest-bridge/src/tools/wc-customers.ts`
653
+
654
+ **Step 1: Write the complete file**
655
+
656
+ ```typescript
657
+ // src/tools/wc-customers.ts
658
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
659
+ import { makeWooCommerceRequest } from '../wordpress.js';
660
+ import { z } from 'zod';
661
+
662
+ const wcListCustomersSchema = z.object({
663
+ per_page: z.number().optional().default(10).describe("Results per page (1-100)"),
664
+ page: z.number().optional().default(1).describe("Page number"),
665
+ search: z.string().optional().describe("Search customers by keyword"),
666
+ email: z.string().optional().describe("Filter by exact email"),
667
+ role: z.enum(['all', 'administrator', 'editor', 'author', 'contributor', 'subscriber', 'customer']).optional().default('all').describe("Filter by role"),
668
+ orderby: z.enum(['id', 'name', 'registered_date']).optional().describe("Sort by field"),
669
+ order: z.enum(['asc', 'desc']).optional().default('desc').describe("Sort order"),
670
+ }).strict();
671
+
672
+ const wcGetCustomerSchema = z.object({
673
+ id: z.number().describe("Customer ID"),
674
+ }).strict();
675
+
676
+ const wcCreateCustomerSchema = z.object({
677
+ email: z.string().describe("Customer email address"),
678
+ first_name: z.string().optional().describe("First name"),
679
+ last_name: z.string().optional().describe("Last name"),
680
+ username: z.string().optional().describe("Username (auto-generated if omitted)"),
681
+ password: z.string().optional().describe("Password (auto-generated if omitted)"),
682
+ }).strict();
683
+
684
+ const wcUpdateCustomerSchema = z.object({
685
+ id: z.number().describe("Customer ID"),
686
+ email: z.string().optional().describe("Email address"),
687
+ first_name: z.string().optional().describe("First name"),
688
+ last_name: z.string().optional().describe("Last name"),
689
+ }).strict();
690
+
691
+ export const wcCustomerTools: Tool[] = [
692
+ {
693
+ name: "wc_list_customers",
694
+ description: "Lists WooCommerce customers with filtering and search",
695
+ inputSchema: { type: "object", properties: wcListCustomersSchema.shape },
696
+ },
697
+ {
698
+ name: "wc_get_customer",
699
+ description: "Retrieves a WooCommerce customer with order count and total spent",
700
+ inputSchema: { type: "object", properties: wcGetCustomerSchema.shape },
701
+ },
702
+ {
703
+ name: "wc_create_customer",
704
+ description: "Creates a new WooCommerce customer account",
705
+ inputSchema: { type: "object", properties: wcCreateCustomerSchema.shape },
706
+ },
707
+ {
708
+ name: "wc_update_customer",
709
+ description: "Updates a WooCommerce customer's details",
710
+ inputSchema: { type: "object", properties: wcUpdateCustomerSchema.shape },
711
+ },
712
+ ];
713
+
714
+ export const wcCustomerHandlers = {
715
+ wc_list_customers: async (params: z.infer<typeof wcListCustomersSchema>) => {
716
+ try {
717
+ const response = await makeWooCommerceRequest("GET", "customers", params);
718
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
719
+ } catch (error: any) {
720
+ const errorMessage = error.response?.data?.message || error.message;
721
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing customers: ${errorMessage}` }] } };
722
+ }
723
+ },
724
+
725
+ wc_get_customer: async (params: z.infer<typeof wcGetCustomerSchema>) => {
726
+ try {
727
+ const response = await makeWooCommerceRequest("GET", `customers/${params.id}`);
728
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
729
+ } catch (error: any) {
730
+ const errorMessage = error.response?.data?.message || error.message;
731
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error retrieving customer: ${errorMessage}` }] } };
732
+ }
733
+ },
734
+
735
+ wc_create_customer: async (params: z.infer<typeof wcCreateCustomerSchema>) => {
736
+ try {
737
+ const response = await makeWooCommerceRequest("POST", "customers", params);
738
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
739
+ } catch (error: any) {
740
+ const errorMessage = error.response?.data?.message || error.message;
741
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error creating customer: ${errorMessage}` }] } };
742
+ }
743
+ },
744
+
745
+ wc_update_customer: async (params: z.infer<typeof wcUpdateCustomerSchema>) => {
746
+ try {
747
+ const { id, ...data } = params;
748
+ const response = await makeWooCommerceRequest("PUT", `customers/${id}`, data);
749
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
750
+ } catch (error: any) {
751
+ const errorMessage = error.response?.data?.message || error.message;
752
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error updating customer: ${errorMessage}` }] } };
753
+ }
754
+ },
755
+ };
756
+ ```
757
+
758
+ **Step 2: Compile check**
759
+
760
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
761
+ Expected: No errors
762
+
763
+ **Step 3: Commit**
764
+
765
+ ```bash
766
+ git add servers/wp-rest-bridge/src/tools/wc-customers.ts
767
+ git commit -m "feat(wc): add wc-customers.ts — 4 WooCommerce customer tools
768
+
769
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
770
+ ```
771
+
772
+ ---
773
+
774
+ ### Task 6: Create wc-coupons.ts (4 tools)
775
+
776
+ **Files:**
777
+ - Create: `servers/wp-rest-bridge/src/tools/wc-coupons.ts`
778
+
779
+ **Step 1: Write the complete file**
780
+
781
+ ```typescript
782
+ // src/tools/wc-coupons.ts
783
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
784
+ import { makeWooCommerceRequest } from '../wordpress.js';
785
+ import { z } from 'zod';
786
+
787
+ const wcListCouponsSchema = z.object({
788
+ per_page: z.number().optional().default(10).describe("Results per page (1-100)"),
789
+ page: z.number().optional().default(1).describe("Page number"),
790
+ search: z.string().optional().describe("Search coupons by code"),
791
+ }).strict();
792
+
793
+ const wcGetCouponSchema = z.object({
794
+ id: z.number().describe("Coupon ID"),
795
+ }).strict();
796
+
797
+ const wcCreateCouponSchema = z.object({
798
+ code: z.string().describe("Coupon code (unique)"),
799
+ discount_type: z.enum(['percent', 'fixed_cart', 'fixed_product']).optional().default('fixed_cart').describe("Discount type"),
800
+ amount: z.string().describe("Discount amount (e.g. '10' for 10% or $10)"),
801
+ description: z.string().optional().describe("Coupon description"),
802
+ date_expires: z.string().optional().describe("Expiration date (ISO 8601)"),
803
+ individual_use: z.boolean().optional().default(false).describe("Cannot combine with other coupons"),
804
+ product_ids: z.array(z.number()).optional().describe("Products this coupon applies to"),
805
+ usage_limit: z.number().optional().describe("Total usage limit"),
806
+ usage_limit_per_user: z.number().optional().describe("Per-user usage limit"),
807
+ minimum_amount: z.string().optional().describe("Minimum order amount required"),
808
+ maximum_amount: z.string().optional().describe("Maximum order amount allowed"),
809
+ free_shipping: z.boolean().optional().default(false).describe("Grants free shipping"),
810
+ }).strict();
811
+
812
+ const wcDeleteCouponSchema = z.object({
813
+ id: z.number().describe("Coupon ID to delete"),
814
+ force: z.boolean().optional().default(false).describe("True to permanently delete"),
815
+ }).strict();
816
+
817
+ export const wcCouponTools: Tool[] = [
818
+ {
819
+ name: "wc_list_coupons",
820
+ description: "Lists WooCommerce coupons with search and pagination",
821
+ inputSchema: { type: "object", properties: wcListCouponsSchema.shape },
822
+ },
823
+ {
824
+ name: "wc_get_coupon",
825
+ description: "Retrieves a WooCommerce coupon by ID with usage stats",
826
+ inputSchema: { type: "object", properties: wcGetCouponSchema.shape },
827
+ },
828
+ {
829
+ name: "wc_create_coupon",
830
+ description: "Creates a new WooCommerce coupon with discount rules",
831
+ inputSchema: { type: "object", properties: wcCreateCouponSchema.shape },
832
+ },
833
+ {
834
+ name: "wc_delete_coupon",
835
+ description: "Deletes a WooCommerce coupon",
836
+ inputSchema: { type: "object", properties: wcDeleteCouponSchema.shape },
837
+ },
838
+ ];
839
+
840
+ export const wcCouponHandlers = {
841
+ wc_list_coupons: async (params: z.infer<typeof wcListCouponsSchema>) => {
842
+ try {
843
+ const response = await makeWooCommerceRequest("GET", "coupons", params);
844
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
845
+ } catch (error: any) {
846
+ const errorMessage = error.response?.data?.message || error.message;
847
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing coupons: ${errorMessage}` }] } };
848
+ }
849
+ },
850
+
851
+ wc_get_coupon: async (params: z.infer<typeof wcGetCouponSchema>) => {
852
+ try {
853
+ const response = await makeWooCommerceRequest("GET", `coupons/${params.id}`);
854
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
855
+ } catch (error: any) {
856
+ const errorMessage = error.response?.data?.message || error.message;
857
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error retrieving coupon: ${errorMessage}` }] } };
858
+ }
859
+ },
860
+
861
+ wc_create_coupon: async (params: z.infer<typeof wcCreateCouponSchema>) => {
862
+ try {
863
+ const response = await makeWooCommerceRequest("POST", "coupons", params);
864
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
865
+ } catch (error: any) {
866
+ const errorMessage = error.response?.data?.message || error.message;
867
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error creating coupon: ${errorMessage}` }] } };
868
+ }
869
+ },
870
+
871
+ wc_delete_coupon: async (params: z.infer<typeof wcDeleteCouponSchema>) => {
872
+ try {
873
+ const response = await makeWooCommerceRequest("DELETE", `coupons/${params.id}`, { force: params.force });
874
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
875
+ } catch (error: any) {
876
+ const errorMessage = error.response?.data?.message || error.message;
877
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error deleting coupon: ${errorMessage}` }] } };
878
+ }
879
+ },
880
+ };
881
+ ```
882
+
883
+ **Step 2: Compile check**
884
+
885
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
886
+ Expected: No errors
887
+
888
+ **Step 3: Commit**
889
+
890
+ ```bash
891
+ git add servers/wp-rest-bridge/src/tools/wc-coupons.ts
892
+ git commit -m "feat(wc): add wc-coupons.ts — 4 WooCommerce coupon tools
893
+
894
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
895
+ ```
896
+
897
+ ---
898
+
899
+ ### Task 7: Create wc-reports.ts (5 tools)
900
+
901
+ **Files:**
902
+ - Create: `servers/wp-rest-bridge/src/tools/wc-reports.ts`
903
+
904
+ **Step 1: Write the complete file**
905
+
906
+ ```typescript
907
+ // src/tools/wc-reports.ts
908
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
909
+ import { makeWooCommerceRequest } from '../wordpress.js';
910
+ import { z } from 'zod';
911
+
912
+ const wcGetSalesReportSchema = z.object({
913
+ period: z.enum(['week', 'month', 'last_month', 'year']).optional().default('week').describe("Report period"),
914
+ date_min: z.string().optional().describe("Start date (YYYY-MM-DD)"),
915
+ date_max: z.string().optional().describe("End date (YYYY-MM-DD)"),
916
+ }).strict();
917
+
918
+ const wcGetTopSellersSchema = z.object({
919
+ period: z.enum(['week', 'month', 'last_month', 'year']).optional().default('week').describe("Report period"),
920
+ date_min: z.string().optional().describe("Start date (YYYY-MM-DD)"),
921
+ date_max: z.string().optional().describe("End date (YYYY-MM-DD)"),
922
+ }).strict();
923
+
924
+ const wcGetOrdersTotalsSchema = z.object({}).strict();
925
+ const wcGetProductsTotalsSchema = z.object({}).strict();
926
+ const wcGetCustomersTotalsSchema = z.object({}).strict();
927
+
928
+ export const wcReportTools: Tool[] = [
929
+ {
930
+ name: "wc_get_sales_report",
931
+ description: "Gets WooCommerce sales report (total sales, orders, items, revenue) for a period",
932
+ inputSchema: { type: "object", properties: wcGetSalesReportSchema.shape },
933
+ },
934
+ {
935
+ name: "wc_get_top_sellers",
936
+ description: "Gets top-selling WooCommerce products for a period",
937
+ inputSchema: { type: "object", properties: wcGetTopSellersSchema.shape },
938
+ },
939
+ {
940
+ name: "wc_get_orders_totals",
941
+ description: "Gets WooCommerce order totals grouped by status",
942
+ inputSchema: { type: "object", properties: wcGetOrdersTotalsSchema.shape },
943
+ },
944
+ {
945
+ name: "wc_get_products_totals",
946
+ description: "Gets WooCommerce product totals grouped by type",
947
+ inputSchema: { type: "object", properties: wcGetProductsTotalsSchema.shape },
948
+ },
949
+ {
950
+ name: "wc_get_customers_totals",
951
+ description: "Gets WooCommerce customer totals (paying vs non-paying)",
952
+ inputSchema: { type: "object", properties: wcGetCustomersTotalsSchema.shape },
953
+ },
954
+ ];
955
+
956
+ export const wcReportHandlers = {
957
+ wc_get_sales_report: async (params: z.infer<typeof wcGetSalesReportSchema>) => {
958
+ try {
959
+ const response = await makeWooCommerceRequest("GET", "reports/sales", params);
960
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
961
+ } catch (error: any) {
962
+ const errorMessage = error.response?.data?.message || error.message;
963
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting sales report: ${errorMessage}` }] } };
964
+ }
965
+ },
966
+
967
+ wc_get_top_sellers: async (params: z.infer<typeof wcGetTopSellersSchema>) => {
968
+ try {
969
+ const response = await makeWooCommerceRequest("GET", "reports/top_sellers", params);
970
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
971
+ } catch (error: any) {
972
+ const errorMessage = error.response?.data?.message || error.message;
973
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting top sellers: ${errorMessage}` }] } };
974
+ }
975
+ },
976
+
977
+ wc_get_orders_totals: async () => {
978
+ try {
979
+ const response = await makeWooCommerceRequest("GET", "reports/orders/totals");
980
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
981
+ } catch (error: any) {
982
+ const errorMessage = error.response?.data?.message || error.message;
983
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting orders totals: ${errorMessage}` }] } };
984
+ }
985
+ },
986
+
987
+ wc_get_products_totals: async () => {
988
+ try {
989
+ const response = await makeWooCommerceRequest("GET", "reports/products/totals");
990
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
991
+ } catch (error: any) {
992
+ const errorMessage = error.response?.data?.message || error.message;
993
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting products totals: ${errorMessage}` }] } };
994
+ }
995
+ },
996
+
997
+ wc_get_customers_totals: async () => {
998
+ try {
999
+ const response = await makeWooCommerceRequest("GET", "reports/customers/totals");
1000
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
1001
+ } catch (error: any) {
1002
+ const errorMessage = error.response?.data?.message || error.message;
1003
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting customers totals: ${errorMessage}` }] } };
1004
+ }
1005
+ },
1006
+ };
1007
+ ```
1008
+
1009
+ **Step 2: Compile check**
1010
+
1011
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
1012
+ Expected: No errors
1013
+
1014
+ **Step 3: Commit**
1015
+
1016
+ ```bash
1017
+ git add servers/wp-rest-bridge/src/tools/wc-reports.ts
1018
+ git commit -m "feat(wc): add wc-reports.ts — 5 WooCommerce report tools
1019
+
1020
+ Sales, top sellers, orders/products/customers totals.
1021
+
1022
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1023
+ ```
1024
+
1025
+ ---
1026
+
1027
+ ### Task 8: Create wc-settings.ts (4 tools)
1028
+
1029
+ **Files:**
1030
+ - Create: `servers/wp-rest-bridge/src/tools/wc-settings.ts`
1031
+
1032
+ **Step 1: Write the complete file**
1033
+
1034
+ ```typescript
1035
+ // src/tools/wc-settings.ts
1036
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
1037
+ import { makeWooCommerceRequest } from '../wordpress.js';
1038
+ import { z } from 'zod';
1039
+
1040
+ const wcListPaymentGatewaysSchema = z.object({}).strict();
1041
+ const wcListShippingZonesSchema = z.object({}).strict();
1042
+ const wcGetTaxClassesSchema = z.object({}).strict();
1043
+ const wcGetSystemStatusSchema = z.object({}).strict();
1044
+
1045
+ export const wcSettingTools: Tool[] = [
1046
+ {
1047
+ name: "wc_list_payment_gateways",
1048
+ description: "Lists all configured WooCommerce payment gateways with status and settings",
1049
+ inputSchema: { type: "object", properties: wcListPaymentGatewaysSchema.shape },
1050
+ },
1051
+ {
1052
+ name: "wc_list_shipping_zones",
1053
+ description: "Lists WooCommerce shipping zones with methods and regions",
1054
+ inputSchema: { type: "object", properties: wcListShippingZonesSchema.shape },
1055
+ },
1056
+ {
1057
+ name: "wc_get_tax_classes",
1058
+ description: "Gets WooCommerce tax classes configuration",
1059
+ inputSchema: { type: "object", properties: wcGetTaxClassesSchema.shape },
1060
+ },
1061
+ {
1062
+ name: "wc_get_system_status",
1063
+ description: "Gets WooCommerce system status (version, environment, database, theme, plugins)",
1064
+ inputSchema: { type: "object", properties: wcGetSystemStatusSchema.shape },
1065
+ },
1066
+ ];
1067
+
1068
+ export const wcSettingHandlers = {
1069
+ wc_list_payment_gateways: async () => {
1070
+ try {
1071
+ const response = await makeWooCommerceRequest("GET", "payment_gateways");
1072
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
1073
+ } catch (error: any) {
1074
+ const errorMessage = error.response?.data?.message || error.message;
1075
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing payment gateways: ${errorMessage}` }] } };
1076
+ }
1077
+ },
1078
+
1079
+ wc_list_shipping_zones: async () => {
1080
+ try {
1081
+ const response = await makeWooCommerceRequest("GET", "shipping/zones");
1082
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
1083
+ } catch (error: any) {
1084
+ const errorMessage = error.response?.data?.message || error.message;
1085
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error listing shipping zones: ${errorMessage}` }] } };
1086
+ }
1087
+ },
1088
+
1089
+ wc_get_tax_classes: async () => {
1090
+ try {
1091
+ const response = await makeWooCommerceRequest("GET", "taxes/classes");
1092
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
1093
+ } catch (error: any) {
1094
+ const errorMessage = error.response?.data?.message || error.message;
1095
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting tax classes: ${errorMessage}` }] } };
1096
+ }
1097
+ },
1098
+
1099
+ wc_get_system_status: async () => {
1100
+ try {
1101
+ const response = await makeWooCommerceRequest("GET", "system_status");
1102
+ return { toolResult: { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] } };
1103
+ } catch (error: any) {
1104
+ const errorMessage = error.response?.data?.message || error.message;
1105
+ return { toolResult: { isError: true, content: [{ type: "text", text: `Error getting system status: ${errorMessage}` }] } };
1106
+ }
1107
+ },
1108
+ };
1109
+ ```
1110
+
1111
+ **Step 2: Compile check**
1112
+
1113
+ Run: `cd servers/wp-rest-bridge && npx tsc --noEmit`
1114
+ Expected: No errors
1115
+
1116
+ **Step 3: Commit**
1117
+
1118
+ ```bash
1119
+ git add servers/wp-rest-bridge/src/tools/wc-settings.ts
1120
+ git commit -m "feat(wc): add wc-settings.ts — 4 WooCommerce settings tools
1121
+
1122
+ Payment gateways, shipping zones, tax classes, system status.
1123
+
1124
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1125
+ ```
1126
+
1127
+ ---
1128
+
1129
+ ### Task 9: Register WC tools in index.ts and build
1130
+
1131
+ **Files:**
1132
+ - Modify: `servers/wp-rest-bridge/src/tools/index.ts`
1133
+
1134
+ **Step 1: Add imports and registrations**
1135
+
1136
+ Replace entire file with:
1137
+
1138
+ ```typescript
1139
+ // src/tools/index.ts
1140
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
1141
+ import { unifiedContentTools, unifiedContentHandlers } from './unified-content.js';
1142
+ import { unifiedTaxonomyTools, unifiedTaxonomyHandlers } from './unified-taxonomies.js';
1143
+ import { pluginTools, pluginHandlers } from './plugins.js';
1144
+ import { mediaTools, mediaHandlers } from './media.js';
1145
+ import { userTools, userHandlers } from './users.js';
1146
+ import { pluginRepositoryTools, pluginRepositoryHandlers } from './plugin-repository.js';
1147
+ import { commentTools, commentHandlers } from './comments.js';
1148
+ import { searchTools, searchHandlers } from './search.js';
1149
+ import { wcProductTools, wcProductHandlers } from './wc-products.js';
1150
+ import { wcOrderTools, wcOrderHandlers } from './wc-orders.js';
1151
+ import { wcCustomerTools, wcCustomerHandlers } from './wc-customers.js';
1152
+ import { wcCouponTools, wcCouponHandlers } from './wc-coupons.js';
1153
+ import { wcReportTools, wcReportHandlers } from './wc-reports.js';
1154
+ import { wcSettingTools, wcSettingHandlers } from './wc-settings.js';
1155
+
1156
+ // Combine all tools
1157
+ export const allTools: Tool[] = [
1158
+ ...unifiedContentTools, // 8 tools
1159
+ ...unifiedTaxonomyTools, // 8 tools
1160
+ ...pluginTools, // 6 tools
1161
+ ...mediaTools, // 5 tools
1162
+ ...userTools, // 6 tools
1163
+ ...pluginRepositoryTools, // 2 tools
1164
+ ...commentTools, // 5 tools
1165
+ ...searchTools, // 1 tool
1166
+ ...wcProductTools, // 7 tools
1167
+ ...wcOrderTools, // 6 tools
1168
+ ...wcCustomerTools, // 4 tools
1169
+ ...wcCouponTools, // 4 tools
1170
+ ...wcReportTools, // 5 tools
1171
+ ...wcSettingTools, // 4 tools
1172
+ ];
1173
+
1174
+ // Combine all handlers
1175
+ export const toolHandlers = {
1176
+ ...unifiedContentHandlers,
1177
+ ...unifiedTaxonomyHandlers,
1178
+ ...pluginHandlers,
1179
+ ...mediaHandlers,
1180
+ ...userHandlers,
1181
+ ...pluginRepositoryHandlers,
1182
+ ...commentHandlers,
1183
+ ...searchHandlers,
1184
+ ...wcProductHandlers,
1185
+ ...wcOrderHandlers,
1186
+ ...wcCustomerHandlers,
1187
+ ...wcCouponHandlers,
1188
+ ...wcReportHandlers,
1189
+ ...wcSettingHandlers,
1190
+ };
1191
+ ```
1192
+
1193
+ **Step 2: Full build**
1194
+
1195
+ Run: `cd servers/wp-rest-bridge && npx tsc`
1196
+ Expected: Clean build, `.js` files in `build/` directory
1197
+
1198
+ **Step 3: Commit**
1199
+
1200
+ ```bash
1201
+ git add servers/wp-rest-bridge/src/tools/index.ts servers/wp-rest-bridge/build/
1202
+ git commit -m "feat(wc): register 30 WooCommerce tools in index.ts + build
1203
+
1204
+ WP REST Bridge now has 71 total tools (41 WP + 30 WC).
1205
+
1206
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1207
+ ```
1208
+
1209
+ ---
1210
+
1211
+ ### Task 10: Create detection script woocommerce_inspect.mjs
1212
+
1213
+ **Files:**
1214
+ - Create: `skills/wp-woocommerce/scripts/woocommerce_inspect.mjs`
1215
+
1216
+ **Step 1: Create directory**
1217
+
1218
+ Run: `mkdir -p skills/wp-woocommerce/scripts`
1219
+
1220
+ **Step 2: Write the detection script**
1221
+
1222
+ Follow the pattern from `detect_local_env.mjs`: Node.js ESM, no third-party deps, JSON output to stdout, exit code 0/1.
1223
+
1224
+ The script should detect:
1225
+ - WooCommerce plugin in the project (for development context)
1226
+ - WC hooks usage in PHP files (`woocommerce_`, `wc_`)
1227
+ - composer.json WooCommerce dependencies
1228
+ - WC config in `WP_SITES_CONFIG` env var
1229
+ - WooCommerce template overrides (`woocommerce/` dir in theme)
1230
+
1231
+ ```javascript
1232
+ /**
1233
+ * woocommerce_inspect.mjs — Detect WooCommerce presence and configuration.
1234
+ *
1235
+ * Scans project files for WooCommerce indicators (plugin files, hooks, composer deps)
1236
+ * and checks WP_SITES_CONFIG for WC credentials.
1237
+ *
1238
+ * Usage:
1239
+ * node woocommerce_inspect.mjs [--cwd=/path/to/check]
1240
+ *
1241
+ * Exit codes:
1242
+ * 0 — WooCommerce indicators found
1243
+ * 1 — no WooCommerce indicators found
1244
+ */
1245
+
1246
+ import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
1247
+ import { join, resolve } from 'node:path';
1248
+ import { argv, env, stdout, exit } from 'node:process';
1249
+
1250
+ // ---------------------------------------------------------------------------
1251
+ // Helpers
1252
+ // ---------------------------------------------------------------------------
1253
+
1254
+ function readFileSafe(filePath) {
1255
+ try { return readFileSync(filePath, 'utf-8'); } catch { return null; }
1256
+ }
1257
+
1258
+ function readJsonSafe(filePath) {
1259
+ const raw = readFileSafe(filePath);
1260
+ if (!raw) return null;
1261
+ try { return JSON.parse(raw); } catch { return null; }
1262
+ }
1263
+
1264
+ function existsSafe(filePath) {
1265
+ try { return existsSync(filePath); } catch { return false; }
1266
+ }
1267
+
1268
+ function findFiles(dir, pattern, maxDepth = 3, depth = 0) {
1269
+ const results = [];
1270
+ if (depth > maxDepth) return results;
1271
+ try {
1272
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
1273
+ const full = join(dir, entry.name);
1274
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules' && entry.name !== 'vendor') {
1275
+ results.push(...findFiles(full, pattern, maxDepth, depth + 1));
1276
+ } else if (entry.isFile() && pattern.test(entry.name)) {
1277
+ results.push(full);
1278
+ }
1279
+ }
1280
+ } catch { /* permission denied, etc. */ }
1281
+ return results;
1282
+ }
1283
+
1284
+ // ---------------------------------------------------------------------------
1285
+ // Detectors
1286
+ // ---------------------------------------------------------------------------
1287
+
1288
+ function detectWcPlugin(cwd) {
1289
+ // Check for WooCommerce plugin directory
1290
+ const wcPaths = [
1291
+ join(cwd, 'wp-content/plugins/woocommerce/woocommerce.php'),
1292
+ join(cwd, 'plugins/woocommerce/woocommerce.php'),
1293
+ join(cwd, 'woocommerce.php'),
1294
+ ];
1295
+ for (const p of wcPaths) {
1296
+ if (existsSafe(p)) {
1297
+ const content = readFileSafe(p);
1298
+ const versionMatch = content?.match(/\*\s*Version:\s*(.+)/i);
1299
+ return { found: true, path: p, version: versionMatch?.[1]?.trim() || 'unknown' };
1300
+ }
1301
+ }
1302
+ return null;
1303
+ }
1304
+
1305
+ function detectComposerDeps(cwd) {
1306
+ const composer = readJsonSafe(join(cwd, 'composer.json'));
1307
+ if (!composer) return null;
1308
+ const allDeps = { ...composer.require, ...composer['require-dev'] };
1309
+ const wcDeps = Object.keys(allDeps).filter(k => k.includes('woocommerce'));
1310
+ return wcDeps.length > 0 ? { deps: wcDeps } : null;
1311
+ }
1312
+
1313
+ function detectWcHooks(cwd) {
1314
+ const phpFiles = findFiles(cwd, /\.php$/, 3);
1315
+ const hooks = { actions: new Set(), filters: new Set() };
1316
+ for (const f of phpFiles.slice(0, 100)) {
1317
+ const content = readFileSafe(f);
1318
+ if (!content) continue;
1319
+ const actionMatches = content.matchAll(/add_action\(\s*['"]([^'"]*woocommerce[^'"]*)['"]/gi);
1320
+ for (const m of actionMatches) hooks.actions.add(m[1]);
1321
+ const filterMatches = content.matchAll(/add_filter\(\s*['"]([^'"]*woocommerce[^'"]*)['"]/gi);
1322
+ for (const m of filterMatches) hooks.filters.add(m[1]);
1323
+ const wcFuncMatches = content.matchAll(/\b(wc_get_[a-z_]+|WC\(\))/g);
1324
+ for (const m of wcFuncMatches) hooks.actions.add(m[1]);
1325
+ }
1326
+ return (hooks.actions.size + hooks.filters.size) > 0
1327
+ ? { actions: [...hooks.actions].slice(0, 20), filters: [...hooks.filters].slice(0, 20) }
1328
+ : null;
1329
+ }
1330
+
1331
+ function detectTemplateOverrides(cwd) {
1332
+ const themePaths = [
1333
+ join(cwd, 'woocommerce'),
1334
+ join(cwd, 'templates/woocommerce'),
1335
+ join(cwd, 'theme/woocommerce'),
1336
+ ];
1337
+ for (const p of themePaths) {
1338
+ if (existsSafe(p)) {
1339
+ try {
1340
+ const files = findFiles(p, /\.php$/, 2);
1341
+ return { path: p, templateCount: files.length };
1342
+ } catch { /* skip */ }
1343
+ }
1344
+ }
1345
+ return null;
1346
+ }
1347
+
1348
+ function detectWcConfig() {
1349
+ const sitesJson = env.WP_SITES_CONFIG;
1350
+ if (!sitesJson) return null;
1351
+ try {
1352
+ const sites = JSON.parse(sitesJson);
1353
+ const wcSites = sites.filter(s => s.wc_consumer_key && s.wc_consumer_secret);
1354
+ return wcSites.length > 0
1355
+ ? { configured_sites: wcSites.map(s => s.id), count: wcSites.length }
1356
+ : null;
1357
+ } catch { return null; }
1358
+ }
1359
+
1360
+ // ---------------------------------------------------------------------------
1361
+ // Main
1362
+ // ---------------------------------------------------------------------------
1363
+
1364
+ function main() {
1365
+ const cwdArg = argv.find(a => a.startsWith('--cwd='));
1366
+ const cwd = cwdArg ? resolve(cwdArg.split('=')[1]) : process.cwd();
1367
+
1368
+ const plugin = detectWcPlugin(cwd);
1369
+ const composer = detectComposerDeps(cwd);
1370
+ const hooks = detectWcHooks(cwd);
1371
+ const templates = detectTemplateOverrides(cwd);
1372
+ const config = detectWcConfig();
1373
+
1374
+ const signals = [];
1375
+ if (plugin) signals.push('woocommerce_plugin');
1376
+ if (composer) signals.push('composer_dependency');
1377
+ if (hooks) signals.push('wc_hooks_usage');
1378
+ if (templates) signals.push('template_overrides');
1379
+ if (config) signals.push('wc_api_configured');
1380
+
1381
+ const report = {
1382
+ tool: 'woocommerce_inspect',
1383
+ version: '1.0.0',
1384
+ timestamp: new Date().toISOString(),
1385
+ cwd,
1386
+ found: signals.length > 0,
1387
+ signals,
1388
+ details: {
1389
+ plugin: plugin || undefined,
1390
+ composer: composer || undefined,
1391
+ hooks: hooks || undefined,
1392
+ templates: templates || undefined,
1393
+ api_config: config || undefined,
1394
+ },
1395
+ recommendations: [],
1396
+ };
1397
+
1398
+ if (!config && signals.length > 0) {
1399
+ report.recommendations.push('Add wc_consumer_key and wc_consumer_secret to WP_SITES_CONFIG for API access');
1400
+ }
1401
+ if (plugin) {
1402
+ report.recommendations.push(`WooCommerce ${plugin.version} detected — all 30 WC tools available`);
1403
+ }
1404
+ if (hooks && !plugin) {
1405
+ report.recommendations.push('WooCommerce hooks detected but plugin not found locally — this may be a WC extension');
1406
+ }
1407
+
1408
+ stdout.write(JSON.stringify(report, null, 2) + '\n');
1409
+ exit(signals.length > 0 ? 0 : 1);
1410
+ }
1411
+
1412
+ main();
1413
+ ```
1414
+
1415
+ **Step 3: Test the script**
1416
+
1417
+ Run: `node skills/wp-woocommerce/scripts/woocommerce_inspect.mjs`
1418
+ Expected: JSON output with `"found": false` (no WC in plugin project itself), exit code 1
1419
+
1420
+ **Step 4: Commit**
1421
+
1422
+ ```bash
1423
+ git add skills/wp-woocommerce/scripts/woocommerce_inspect.mjs
1424
+ git commit -m "feat(wc): add woocommerce_inspect.mjs detection script
1425
+
1426
+ Detects WC plugin, composer deps, hooks, template overrides, API config.
1427
+
1428
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1429
+ ```
1430
+
1431
+ ---
1432
+
1433
+ ### Task 11: Create skill wp-woocommerce SKILL.md
1434
+
1435
+ **Files:**
1436
+ - Create: `skills/wp-woocommerce/SKILL.md`
1437
+
1438
+ **Step 1: Write SKILL.md**
1439
+
1440
+ ```markdown
1441
+ ---
1442
+ name: wp-woocommerce
1443
+ description: |
1444
+ This skill should be used when the user asks to "manage products", "check orders",
1445
+ "create a coupon", "view sales report", "WooCommerce setup", "configure shipping",
1446
+ "manage WooCommerce store", "product catalog", "inventory management",
1447
+ "order fulfillment", or any WooCommerce e-commerce operations.
1448
+ version: 1.0.0
1449
+ ---
1450
+
1451
+ ## Overview
1452
+
1453
+ Comprehensive WooCommerce store management via the WP REST Bridge WC tools (30 MCP tools using the `wc/v3` namespace). Covers product catalog CRUD, order lifecycle, customer management, coupon marketing, sales analytics, and store configuration (payments, shipping, taxes).
1454
+
1455
+ ## When to Use
1456
+
1457
+ - User mentions WooCommerce, products, orders, coupons, or store management
1458
+ - User needs sales reports, revenue analytics, or top-selling products
1459
+ - User wants to configure payment gateways, shipping zones, or tax classes
1460
+ - User needs to manage WooCommerce customers or process refunds
1461
+ - User asks about WooCommerce extensions or system status
1462
+
1463
+ ## Prerequisites
1464
+
1465
+ WooCommerce credentials must be configured in `WP_SITES_CONFIG`:
1466
+
1467
+ ```json
1468
+ {
1469
+ "id": "myshop",
1470
+ "url": "https://myshop.com",
1471
+ "username": "admin",
1472
+ "password": "xxxx xxxx xxxx xxxx",
1473
+ "wc_consumer_key": "ck_xxxx",
1474
+ "wc_consumer_secret": "cs_xxxx"
1475
+ }
1476
+ ```
1477
+
1478
+ Generate Consumer Key/Secret in WooCommerce > Settings > Advanced > REST API.
1479
+
1480
+ ## Detection
1481
+
1482
+ Run the detection script to check WooCommerce presence:
1483
+
1484
+ ```bash
1485
+ node skills/wp-woocommerce/scripts/woocommerce_inspect.mjs
1486
+ ```
1487
+
1488
+ ## WooCommerce Operations Decision Tree
1489
+
1490
+ 1. **Product management?**
1491
+ - List/search products → `wc_list_products`
1492
+ - Create product → `wc_create_product`
1493
+ - Update product → `wc_update_product`
1494
+ - Delete product → `wc_delete_product`
1495
+ - Categories → `wc_list_product_categories`
1496
+ - Variations → `wc_list_product_variations`
1497
+
1498
+ 2. **Order management?**
1499
+ - List/filter orders → `wc_list_orders`
1500
+ - Order details → `wc_get_order`
1501
+ - Update status → `wc_update_order_status`
1502
+ - Add note → `wc_create_order_note`
1503
+ - Process refund → `wc_create_refund`
1504
+
1505
+ 3. **Customer management?**
1506
+ - List/search customers → `wc_list_customers`
1507
+ - Customer details → `wc_get_customer`
1508
+ - Create customer → `wc_create_customer`
1509
+ - Update customer → `wc_update_customer`
1510
+
1511
+ 4. **Marketing/Coupons?**
1512
+ - List coupons → `wc_list_coupons`
1513
+ - Create coupon → `wc_create_coupon`
1514
+ - Delete coupon → `wc_delete_coupon`
1515
+
1516
+ 5. **Analytics/Reports?**
1517
+ - Sales summary → `wc_get_sales_report`
1518
+ - Top products → `wc_get_top_sellers`
1519
+ - Order totals → `wc_get_orders_totals`
1520
+ - Product totals → `wc_get_products_totals`
1521
+ - Customer totals → `wc_get_customers_totals`
1522
+
1523
+ 6. **Store configuration?**
1524
+ - Payment gateways → `wc_list_payment_gateways`
1525
+ - Shipping zones → `wc_list_shipping_zones`
1526
+ - Tax classes → `wc_get_tax_classes`
1527
+ - System status → `wc_get_system_status`
1528
+
1529
+ ## Recommended Agent
1530
+
1531
+ For complex multi-step WooCommerce operations, use the `wp-ecommerce-manager` agent.
1532
+
1533
+ ## Additional Resources
1534
+
1535
+ ### Reference Files
1536
+
1537
+ - **`references/product-management.md`** — CRUD products, variations, bulk operations, image management
1538
+ - **`references/order-workflow.md`** — Order lifecycle, status transitions, notes, refunds
1539
+ - **`references/analytics-reports.md`** — Sales reports, KPIs, date ranges, export strategies
1540
+ - **`references/coupon-marketing.md`** — Coupon strategies, discount types, usage limits
1541
+ - **`references/shipping-setup.md`** — Shipping zones, methods, classes, flat rate/free shipping
1542
+ - **`references/payment-gateways.md`** — Gateway configuration, test mode, supported providers
1543
+ - **`references/tax-configuration.md`** — Tax classes, rates by country, automated tax services
1544
+ - **`references/wc-extensions.md`** — Popular extensions, compatibility, WC Marketplace
1545
+
1546
+ ### Related Skills
1547
+
1548
+ - `wp-deploy` — Deploy WooCommerce store changes to production
1549
+ - `wp-audit` — Audit WooCommerce store security and performance
1550
+ - `wp-backup` — Backup WooCommerce database and uploads
1551
+ ```
1552
+
1553
+ **Step 2: Commit**
1554
+
1555
+ ```bash
1556
+ git add skills/wp-woocommerce/SKILL.md
1557
+ git commit -m "feat(wc): add wp-woocommerce skill SKILL.md
1558
+
1559
+ Decision tree for 30 WC tools, prerequisites, detection, references.
1560
+
1561
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1562
+ ```
1563
+
1564
+ ---
1565
+
1566
+ ### Task 12: Create 8 reference files
1567
+
1568
+ **Files:**
1569
+ - Create: `skills/wp-woocommerce/references/product-management.md`
1570
+ - Create: `skills/wp-woocommerce/references/order-workflow.md`
1571
+ - Create: `skills/wp-woocommerce/references/analytics-reports.md`
1572
+ - Create: `skills/wp-woocommerce/references/coupon-marketing.md`
1573
+ - Create: `skills/wp-woocommerce/references/shipping-setup.md`
1574
+ - Create: `skills/wp-woocommerce/references/payment-gateways.md`
1575
+ - Create: `skills/wp-woocommerce/references/tax-configuration.md`
1576
+ - Create: `skills/wp-woocommerce/references/wc-extensions.md`
1577
+
1578
+ **Step 1: Create directory**
1579
+
1580
+ Run: `mkdir -p skills/wp-woocommerce/references`
1581
+
1582
+ **Step 2: Write each reference file**
1583
+
1584
+ Each file should follow this structure:
1585
+ - H1 title
1586
+ - Overview paragraph
1587
+ - Relevant MCP tools listed with brief usage
1588
+ - Step-by-step procedures for common operations
1589
+ - Tips and gotchas section
1590
+
1591
+ Content outline per file:
1592
+
1593
+ **product-management.md** (~60 lines):
1594
+ - Product types: simple, variable, grouped, external
1595
+ - CRUD workflow: create → set pricing → add images → categorize → publish
1596
+ - Variable products: create parent → add attributes → create variations
1597
+ - Bulk operations: list with filters, update stock in batches
1598
+ - Tools: `wc_create_product`, `wc_update_product`, `wc_list_product_variations`, `wc_list_product_categories`
1599
+
1600
+ **order-workflow.md** (~60 lines):
1601
+ - Order statuses: pending → processing → completed (or cancelled/refunded/failed)
1602
+ - Status transition rules (which transitions are valid)
1603
+ - Order notes: internal vs customer-visible
1604
+ - Refund process: partial vs full, restocking
1605
+ - Tools: `wc_list_orders`, `wc_update_order_status`, `wc_create_order_note`, `wc_create_refund`
1606
+
1607
+ **analytics-reports.md** (~50 lines):
1608
+ - Sales report: total_sales, net_sales, orders, items, tax, shipping, discount
1609
+ - Period options: week, month, last_month, year, custom date range
1610
+ - Top sellers: product ranking by quantity sold
1611
+ - KPI formulas: AOV, conversion rate, revenue per customer
1612
+ - Tools: `wc_get_sales_report`, `wc_get_top_sellers`, `wc_get_orders_totals`
1613
+
1614
+ **coupon-marketing.md** (~50 lines):
1615
+ - Discount types: percent, fixed_cart, fixed_product
1616
+ - Usage limits: total, per-user, minimum/maximum amount
1617
+ - Strategies: welcome discount, cart abandonment, seasonal, loyalty
1618
+ - Validation: individual_use, product_ids, excluded categories
1619
+ - Tools: `wc_create_coupon`, `wc_list_coupons`, `wc_delete_coupon`
1620
+
1621
+ **shipping-setup.md** (~50 lines):
1622
+ - Shipping zones: geographical regions → methods
1623
+ - Methods: flat rate, free shipping, local pickup
1624
+ - Shipping classes: different rates for product categories
1625
+ - Free shipping thresholds and coupon requirements
1626
+ - Tools: `wc_list_shipping_zones`
1627
+
1628
+ **payment-gateways.md** (~50 lines):
1629
+ - Built-in: PayPal, Stripe, Direct bank transfer, COD, Check
1630
+ - Configuration: enable/disable, test mode, API keys
1631
+ - Test mode workflow: enable → test with sandbox credentials → verify → go live
1632
+ - Tools: `wc_list_payment_gateways`
1633
+
1634
+ **tax-configuration.md** (~50 lines):
1635
+ - Tax classes: Standard, Reduced rate, Zero rate
1636
+ - Tax rates: by country, state, postcode, city
1637
+ - Tax display: inclusive vs exclusive pricing
1638
+ - Automated tax services: WooCommerce Tax, TaxJar, Avalara
1639
+ - Tools: `wc_get_tax_classes`
1640
+
1641
+ **wc-extensions.md** (~50 lines):
1642
+ - Extension categories: payments, shipping, marketing, analytics, subscriptions
1643
+ - Popular extensions: WC Subscriptions, WC Memberships, WC Bookings
1644
+ - Compatibility: version compatibility matrix
1645
+ - WC Marketplace: official vs third-party
1646
+ - Tools: `wc_get_system_status` (lists active extensions)
1647
+
1648
+ **Step 3: Commit**
1649
+
1650
+ ```bash
1651
+ git add skills/wp-woocommerce/references/
1652
+ git commit -m "feat(wc): add 8 WooCommerce reference files
1653
+
1654
+ product-management, order-workflow, analytics-reports, coupon-marketing,
1655
+ shipping-setup, payment-gateways, tax-configuration, wc-extensions.
1656
+
1657
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1658
+ ```
1659
+
1660
+ ---
1661
+
1662
+ ### Task 13: Create agent wp-ecommerce-manager.md
1663
+
1664
+ **Files:**
1665
+ - Create: `agents/wp-ecommerce-manager.md`
1666
+
1667
+ **Step 1: Write the agent file**
1668
+
1669
+ ```markdown
1670
+ ---
1671
+ name: wp-ecommerce-manager
1672
+ color: orange
1673
+ description: |
1674
+ Use this agent when the user needs to manage a WooCommerce store: products, orders,
1675
+ customers, coupons, analytics, or store configuration.
1676
+
1677
+ <example>
1678
+ Context: User wants to check recent orders and update their status.
1679
+ user: "Mostrami gli ordini degli ultimi 7 giorni e segna come completati quelli spediti"
1680
+ assistant: "I'll use the wp-ecommerce-manager agent to list recent orders and update their status."
1681
+ <commentary>Order management with status updates requires the WooCommerce agent for safe multi-step operations.</commentary>
1682
+ </example>
1683
+
1684
+ <example>
1685
+ Context: User needs to set up a product catalog.
1686
+ user: "Crea 5 prodotti nel catalogo WooCommerce con variazioni di taglia"
1687
+ assistant: "I'll use the wp-ecommerce-manager agent to create variable products with size variations."
1688
+ <commentary>Bulk product creation with variations is a multi-step WooCommerce operation.</commentary>
1689
+ </example>
1690
+
1691
+ <example>
1692
+ Context: User wants a sales performance overview.
1693
+ user: "Fammi un report delle vendite di questo mese con i prodotti piu venduti"
1694
+ assistant: "I'll use the wp-ecommerce-manager agent to generate a monthly sales report with top sellers."
1695
+ <commentary>Sales analytics combining multiple report endpoints requires the WooCommerce agent.</commentary>
1696
+ </example>
1697
+
1698
+ model: inherit
1699
+ tools: Read, Grep, Glob, Bash, WebFetch, WebSearch
1700
+ ---
1701
+
1702
+ # WooCommerce E-Commerce Manager
1703
+
1704
+ Specialized agent for WooCommerce store management. Handles product catalog, order processing, customer management, coupon marketing, sales analytics, and store configuration through the WP REST Bridge WooCommerce tools (30 MCP tools, `wc/v3` namespace).
1705
+
1706
+ ## Available MCP Tool Sets
1707
+
1708
+ ### 1. WP REST Bridge — WooCommerce (wc_ prefix)
1709
+
1710
+ All tools require WooCommerce credentials in `WP_SITES_CONFIG` (`wc_consumer_key` + `wc_consumer_secret`).
1711
+
1712
+ - **Products (7)**: `wc_list_products`, `wc_get_product`, `wc_create_product`, `wc_update_product`, `wc_delete_product`, `wc_list_product_categories`, `wc_list_product_variations`
1713
+ - **Orders (6)**: `wc_list_orders`, `wc_get_order`, `wc_update_order_status`, `wc_list_order_notes`, `wc_create_order_note`, `wc_create_refund`
1714
+ - **Customers (4)**: `wc_list_customers`, `wc_get_customer`, `wc_create_customer`, `wc_update_customer`
1715
+ - **Coupons (4)**: `wc_list_coupons`, `wc_get_coupon`, `wc_create_coupon`, `wc_delete_coupon`
1716
+ - **Reports (5)**: `wc_get_sales_report`, `wc_get_top_sellers`, `wc_get_orders_totals`, `wc_get_products_totals`, `wc_get_customers_totals`
1717
+ - **Settings (4)**: `wc_list_payment_gateways`, `wc_list_shipping_zones`, `wc_get_tax_classes`, `wc_get_system_status`
1718
+
1719
+ ### 2. WP REST Bridge — WordPress (wp/v2)
1720
+
1721
+ For cross-referencing with WordPress content:
1722
+ - **Content**: `list_content`, `get_content`, `create_content` (pages for shop, cart, checkout)
1723
+ - **Plugins**: `list_plugins` (verify WooCommerce active)
1724
+ - **Media**: `upload_media` (product images)
1725
+
1726
+ ## Operating Procedures
1727
+
1728
+ ### Product Catalog Setup
1729
+
1730
+ 1. Verify WooCommerce active: `list_plugins` → check woocommerce status
1731
+ 2. Create categories: use WooCommerce admin or REST API
1732
+ 3. Create products: `wc_create_product` with name, price, description, categories, images
1733
+ 4. For variable products: create parent (type: 'variable') → add attributes → create variations
1734
+ 5. Verify: `wc_list_products` with status filter
1735
+
1736
+ ### Order Processing
1737
+
1738
+ 1. List pending orders: `wc_list_orders` with status='processing'
1739
+ 2. Review order details: `wc_get_order` for each order
1740
+ 3. Update status: `wc_update_order_status` (processing → completed)
1741
+ 4. Add notes: `wc_create_order_note` for tracking info
1742
+ 5. Handle refunds: `wc_create_refund` with amount and reason
1743
+
1744
+ ### Sales Analytics
1745
+
1746
+ 1. Get sales overview: `wc_get_sales_report` with period or date range
1747
+ 2. Get top products: `wc_get_top_sellers`
1748
+ 3. Get totals: `wc_get_orders_totals` + `wc_get_products_totals` + `wc_get_customers_totals`
1749
+ 4. Present as structured report with KPIs (AOV, revenue trend, top sellers)
1750
+
1751
+ ### Coupon Campaign
1752
+
1753
+ 1. Define strategy: discount type (percent/fixed), target, limits
1754
+ 2. Create coupon: `wc_create_coupon` with rules
1755
+ 3. Verify: `wc_get_coupon` to confirm settings
1756
+ 4. Monitor: `wc_list_coupons` to check usage_count
1757
+
1758
+ ### Store Health Check
1759
+
1760
+ 1. System status: `wc_get_system_status` (WC version, environment, DB)
1761
+ 2. Payment gateways: `wc_list_payment_gateways` (verify active gateways)
1762
+ 3. Shipping: `wc_list_shipping_zones` (verify zone coverage)
1763
+ 4. Tax: `wc_get_tax_classes` (verify tax configuration)
1764
+
1765
+ ## Report Format
1766
+
1767
+ ```
1768
+ ## WooCommerce Store Report — [Site Name]
1769
+
1770
+ ### Sales Summary (period)
1771
+ - Total Sales: $X,XXX
1772
+ - Net Sales: $X,XXX
1773
+ - Orders: XX
1774
+ - Average Order Value: $XX.XX
1775
+ - Items Sold: XX
1776
+
1777
+ ### Top Sellers
1778
+ 1. Product Name — XX units ($X,XXX revenue)
1779
+ 2. ...
1780
+
1781
+ ### Order Status
1782
+ - Processing: XX
1783
+ - Completed: XX
1784
+ - On Hold: XX
1785
+ - Refunded: XX
1786
+
1787
+ ### Recommendations
1788
+ - [Actionable items based on data]
1789
+ ```
1790
+
1791
+ ## Safety Rules
1792
+
1793
+ - NEVER delete products without explicit user confirmation
1794
+ - NEVER process refunds without verifying order details and getting user approval
1795
+ - ALWAYS confirm before changing order status (especially to cancelled/refunded)
1796
+ - ALWAYS verify WooCommerce credentials are configured before attempting operations
1797
+ - NEVER expose Consumer Key/Secret in output or logs
1798
+ - When creating bulk products, confirm the list with user before executing
1799
+
1800
+ ## Related Skills
1801
+
1802
+ - `wp-woocommerce` — Decision tree and reference files for all WC operations
1803
+ - `wp-deploy` — Deploy store changes to production
1804
+ - `wp-backup` — Backup store database before bulk operations
1805
+ - `wp-audit` — Security and performance audit for WC stores
1806
+ ```
1807
+
1808
+ **Step 2: Commit**
1809
+
1810
+ ```bash
1811
+ git add agents/wp-ecommerce-manager.md
1812
+ git commit -m "feat(wc): add wp-ecommerce-manager agent
1813
+
1814
+ 30 WC tool references, 5 procedures, report template, safety rules.
1815
+
1816
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1817
+ ```
1818
+
1819
+ ---
1820
+
1821
+ ### Task 14: Router update and cross-references
1822
+
1823
+ **Files:**
1824
+ - Modify: `skills/wordpress-router/references/decision-tree.md`
1825
+ - Modify: `skills/wordpress-router/SKILL.md` (if keyword list exists there)
1826
+
1827
+ **Step 1: Add WooCommerce routing to decision-tree.md**
1828
+
1829
+ In Step 0 (keywords that indicate **operations**), append WooCommerce keywords:
1830
+ ```
1831
+ , WooCommerce, prodotto, ordine, coupon, negozio, catalogo, inventario, vendite, carrello
1832
+ ```
1833
+
1834
+ In Step 2b (after the last entry, before Step 2c), add:
1835
+ ```markdown
1836
+ - **WooCommerce / woo / shop / products / orders / coupons / cart / store management / sales report / inventory**
1837
+ → `wp-woocommerce` skill + `wp-ecommerce-manager` agent
1838
+ ```
1839
+
1840
+ **Step 2: Add cross-references to existing skills**
1841
+
1842
+ In `skills/wp-audit/SKILL.md`, add to Additional Resources:
1843
+ ```markdown
1844
+ - For WooCommerce store audit, see `wp-woocommerce` skill
1845
+ ```
1846
+
1847
+ In `skills/wp-deploy/SKILL.md`, add to Additional Resources:
1848
+ ```markdown
1849
+ - For deploying WooCommerce stores, see `wp-woocommerce` skill
1850
+ ```
1851
+
1852
+ In `skills/wp-backup/SKILL.md`, add to Additional Resources:
1853
+ ```markdown
1854
+ - For WooCommerce database backup, see `wp-woocommerce` skill
1855
+ ```
1856
+
1857
+ **Step 3: Add WC delegation to wp-site-manager agent**
1858
+
1859
+ In `agents/wp-site-manager.md`, add to the Specialized Agents table:
1860
+ ```markdown
1861
+ | WooCommerce store management | `wp-ecommerce-manager` | Products, orders, customers, coupons, analytics |
1862
+ ```
1863
+
1864
+ **Step 4: Commit**
1865
+
1866
+ ```bash
1867
+ git add skills/wordpress-router/references/decision-tree.md \
1868
+ skills/wp-audit/SKILL.md skills/wp-deploy/SKILL.md skills/wp-backup/SKILL.md \
1869
+ agents/wp-site-manager.md
1870
+ git commit -m "feat(wc): add WooCommerce routing and cross-references
1871
+
1872
+ Router v5: WC keywords in Step 0 + Step 2b entry.
1873
+ Cross-refs: wp-audit, wp-deploy, wp-backup → wp-woocommerce.
1874
+ wp-site-manager: add wp-ecommerce-manager to delegation table.
1875
+
1876
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1877
+ ```
1878
+
1879
+ ---
1880
+
1881
+ ### Task 15: Version bump + CHANGELOG + docs update
1882
+
1883
+ **Files:**
1884
+ - Modify: `.claude-plugin/plugin.json` — version 1.7.2 → 1.8.0, update description
1885
+ - Modify: `package.json` — version 1.7.2 → 1.8.0, update description, add keywords
1886
+ - Modify: `CHANGELOG.md` — add v1.8.0 entry
1887
+
1888
+ **Step 1: Update plugin.json**
1889
+
1890
+ Change version to `"1.8.0"`, update description to mention WooCommerce, 9 agents, 25 skills, ~71 MCP tools.
1891
+
1892
+ **Step 2: Update package.json**
1893
+
1894
+ Change version to `"1.8.0"`, update description, add keywords: `"woocommerce"`, `"ecommerce"`, `"shop"`.
1895
+
1896
+ **Step 3: Add CHANGELOG entry**
1897
+
1898
+ Add before the `[1.7.2]` entry:
1899
+
1900
+ ```markdown
1901
+ ## [1.8.0] - 2026-XX-XX
1902
+
1903
+ ### Added
1904
+ - **WooCommerce support** — 30 new MCP tools via WP REST Bridge (`wc/v3` namespace)
1905
+ - `wc-products.ts` (7 tools): CRUD products, categories, variations
1906
+ - `wc-orders.ts` (6 tools): List, get, update status, notes, refunds
1907
+ - `wc-customers.ts` (4 tools): List, get, create, update customers
1908
+ - `wc-coupons.ts` (4 tools): CRUD coupons with discount rules
1909
+ - `wc-reports.ts` (5 tools): Sales, top sellers, order/product/customer totals
1910
+ - `wc-settings.ts` (4 tools): Payment gateways, shipping zones, tax classes, system status
1911
+ - **`wp-woocommerce` skill** — WooCommerce operations with decision tree and 8 reference files
1912
+ - Reference files: product-management, order-workflow, analytics-reports, coupon-marketing,
1913
+ shipping-setup, payment-gateways, tax-configuration, wc-extensions
1914
+ - **`wp-ecommerce-manager` agent** — WooCommerce store management (color: orange)
1915
+ - 5 procedures: product catalog, order processing, sales analytics, coupon campaigns, store health
1916
+ - Report template with KPIs and recommendations
1917
+ - **`woocommerce_inspect.mjs`** detection script — scans for WC plugin, hooks, composer deps, API config
1918
+ - WooCommerce authentication: Consumer Key/Secret via separate AxiosInstance in WP REST Bridge
1919
+ - `SiteConfig` extended with optional `wc_consumer_key`/`wc_consumer_secret`
1920
+ - `makeWooCommerceRequest()` reusing existing retry and concurrency logic
1921
+
1922
+ ### Changed
1923
+ - Router upgraded to v5 — WooCommerce keywords in Step 0 + Step 2b routing
1924
+ - `wp-site-manager` agent — added `wp-ecommerce-manager` to delegation table
1925
+ - Cross-references added to `wp-audit`, `wp-deploy`, `wp-backup` skills
1926
+ - WP REST Bridge: 41 → 71 total tools
1927
+ - Version bumps: plugin.json + package.json → 1.8.0
1928
+ ```
1929
+
1930
+ **Step 4: Update GUIDE.md**
1931
+
1932
+ Add WooCommerce section to relevant parts of GUIDE.md (architecture, skill list, agent list, scenarios).
1933
+
1934
+ **Step 5: Commit**
1935
+
1936
+ ```bash
1937
+ git add .claude-plugin/plugin.json package.json CHANGELOG.md docs/GUIDE.md
1938
+ git commit -m "feat(wc): version bump to v1.8.0 + CHANGELOG + docs
1939
+
1940
+ 25 skills, 9 agents, 71 MCP tools, 13 detection scripts, 114 reference files.
1941
+
1942
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
1943
+ ```
1944
+
1945
+ ---
1946
+
1947
+ ### Task 16: Build, final test, publish
1948
+
1949
+ **Step 1: Full TypeScript build**
1950
+
1951
+ Run: `cd servers/wp-rest-bridge && npm install && npx tsc`
1952
+ Expected: Clean build with no errors
1953
+
1954
+ **Step 2: Verify tool count**
1955
+
1956
+ Run: `cd servers/wp-rest-bridge && node -e "const {allTools} = require('./build/tools/index.js'); console.log('Total tools:', allTools.length)"`
1957
+ Expected: `Total tools: 71`
1958
+
1959
+ **Step 3: Verify plugin structure**
1960
+
1961
+ Run: `npm pack --dry-run` from plugin root
1962
+ Expected: All new files included, no missing references
1963
+
1964
+ **Step 4: Push to git**
1965
+
1966
+ ```bash
1967
+ git push origin main
1968
+ ```
1969
+
1970
+ **Step 5: Publish to npm**
1971
+
1972
+ ```bash
1973
+ npm config set //registry.npmjs.org/:_authToken=TOKEN
1974
+ npm publish --access public
1975
+ npm config delete //registry.npmjs.org/:_authToken
1976
+ ```
1977
+
1978
+ **Step 6: Create GitHub release**
1979
+
1980
+ ```bash
1981
+ gh release create v1.8.0 --title "v1.8.0 — WooCommerce" --notes "..."
1982
+ ```
1983
+
1984
+ ---
1985
+
1986
+ ## File Summary
1987
+
1988
+ | File | Action | Tools |
1989
+ |------|--------|-------|
1990
+ | `servers/wp-rest-bridge/src/types.ts` | Modify | — |
1991
+ | `servers/wp-rest-bridge/src/wordpress.ts` | Modify | — |
1992
+ | `servers/wp-rest-bridge/src/tools/wc-products.ts` | **Create** | 7 |
1993
+ | `servers/wp-rest-bridge/src/tools/wc-orders.ts` | **Create** | 6 |
1994
+ | `servers/wp-rest-bridge/src/tools/wc-customers.ts` | **Create** | 4 |
1995
+ | `servers/wp-rest-bridge/src/tools/wc-coupons.ts` | **Create** | 4 |
1996
+ | `servers/wp-rest-bridge/src/tools/wc-reports.ts` | **Create** | 5 |
1997
+ | `servers/wp-rest-bridge/src/tools/wc-settings.ts` | **Create** | 4 |
1998
+ | `servers/wp-rest-bridge/src/tools/index.ts` | Modify | — |
1999
+ | `skills/wp-woocommerce/scripts/woocommerce_inspect.mjs` | **Create** | — |
2000
+ | `skills/wp-woocommerce/SKILL.md` | **Create** | — |
2001
+ | `skills/wp-woocommerce/references/*.md` (8 files) | **Create** | — |
2002
+ | `agents/wp-ecommerce-manager.md` | **Create** | — |
2003
+ | `skills/wordpress-router/references/decision-tree.md` | Modify | — |
2004
+ | `skills/wp-audit/SKILL.md` | Modify | — |
2005
+ | `skills/wp-deploy/SKILL.md` | Modify | — |
2006
+ | `skills/wp-backup/SKILL.md` | Modify | — |
2007
+ | `agents/wp-site-manager.md` | Modify | — |
2008
+ | `.claude-plugin/plugin.json` | Modify | — |
2009
+ | `package.json` | Modify | — |
2010
+ | `CHANGELOG.md` | Modify | — |
2011
+ | `docs/GUIDE.md` | Modify | — |
2012
+ | **Total new tools** | | **30** |