mcp-wordpress 1.4.0 → 1.5.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 (63) hide show
  1. package/README.md +20 -1
  2. package/dist/cache/CacheInvalidation.d.ts.map +1 -1
  3. package/dist/client/CachedWordPressClient.d.ts.map +1 -1
  4. package/dist/client/CachedWordPressClient.js.map +1 -1
  5. package/dist/client/api.d.ts.map +1 -1
  6. package/dist/client/api.js +11 -3
  7. package/dist/client/api.js.map +1 -1
  8. package/dist/client/auth.js.map +1 -1
  9. package/dist/client/managers/AuthenticationManager.js.map +1 -1
  10. package/dist/client/managers/RequestManager.js +0 -1
  11. package/dist/client/managers/RequestManager.js.map +1 -1
  12. package/dist/config/ServerConfiguration.d.ts.map +1 -1
  13. package/dist/config/ServerConfiguration.js +18 -0
  14. package/dist/config/ServerConfiguration.js.map +1 -1
  15. package/dist/docs/MarkdownFormatter.js.map +1 -1
  16. package/dist/dxt-entry.d.ts +6 -0
  17. package/dist/dxt-entry.d.ts.map +1 -0
  18. package/dist/dxt-entry.js +38 -0
  19. package/dist/dxt-entry.js.map +1 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +34 -2
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp-wordpress-1.5.0.tgz +0 -0
  24. package/dist/performance/MetricsCollector.d.ts.map +1 -1
  25. package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
  26. package/dist/performance/PerformanceAnalytics.js.map +1 -1
  27. package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
  28. package/dist/security/InputValidator.js.map +1 -1
  29. package/dist/security/SecurityConfig.d.ts.map +1 -1
  30. package/dist/server/ToolRegistry.js.map +1 -1
  31. package/dist/tools/cache.js +1 -1
  32. package/dist/tools/cache.js.map +1 -1
  33. package/dist/tools/performance.js.map +1 -1
  34. package/docs/developer/API_REFERENCE.md +97 -57
  35. package/docs/developer/ARCHITECTURE.md +7 -7
  36. package/docs/developer/BUILD_SYSTEM.md +8 -13
  37. package/docs/developer/CONTRIBUTING.md +29 -23
  38. package/docs/developer/DXT-DEBUG-BEST-PRACTICES.md +212 -0
  39. package/docs/developer/README.md +24 -1
  40. package/docs/developer/RELEASE_PROCESS.md +33 -28
  41. package/docs/developer/TESTING.md +122 -118
  42. package/docs/user-guides/DXT_INSTALLATION.md +149 -0
  43. package/package.json +4 -3
  44. package/src/cache/CacheInvalidation.ts +1 -1
  45. package/src/client/CachedWordPressClient.ts +15 -15
  46. package/src/client/api.ts +54 -47
  47. package/src/client/auth.ts +88 -88
  48. package/src/client/managers/AuthenticationManager.ts +112 -112
  49. package/src/client/managers/RequestManager.ts +1 -1
  50. package/src/config/ServerConfiguration.ts +39 -0
  51. package/src/docs/MarkdownFormatter.ts +4 -4
  52. package/src/dxt-entry.cjs +55 -0
  53. package/src/dxt-entry.ts +55 -0
  54. package/src/index.ts +55 -2
  55. package/src/performance/MetricsCollector.ts +3 -3
  56. package/src/performance/PerformanceAnalytics.ts +16 -16
  57. package/src/performance/PerformanceMonitor.ts +1 -1
  58. package/src/security/InputValidator.ts +4 -4
  59. package/src/security/SecurityConfig.ts +1 -1
  60. package/src/server/ToolRegistry.ts +12 -12
  61. package/src/tools/cache.ts +1 -1
  62. package/src/tools/performance.ts +17 -17
  63. package/dist/mcp-wordpress-1.4.0.tgz +0 -0
@@ -250,18 +250,18 @@ export class CachedWordPressClient extends WordPressClient {
250
250
  let operationType: "create" | "update" | "delete";
251
251
 
252
252
  switch (method.toUpperCase()) {
253
- case "POST":
254
- operationType = "create";
255
- break;
256
- case "PUT":
257
- case "PATCH":
258
- operationType = "update";
259
- break;
260
- case "DELETE":
261
- operationType = "delete";
262
- break;
263
- default:
264
- return;
253
+ case "POST":
254
+ operationType = "create";
255
+ break;
256
+ case "PUT":
257
+ case "PATCH":
258
+ operationType = "update";
259
+ break;
260
+ case "DELETE":
261
+ operationType = "delete";
262
+ break;
263
+ default:
264
+ return;
265
265
  }
266
266
 
267
267
  await this.cacheInvalidation.invalidateResource(
@@ -375,7 +375,7 @@ export class CachedWordPressClient extends WordPressClient {
375
375
  efficiency: string;
376
376
  memoryUsage: number;
377
377
  totalEntries: number;
378
- } {
378
+ } {
379
379
  const stats = this.cacheManager.getStats();
380
380
  const total = stats.hits + stats.misses;
381
381
  const hitRate = total > 0 ? stats.hits / total : 0;
@@ -405,7 +405,7 @@ export class CachedWordPressClient extends WordPressClient {
405
405
  defaultTTL: number;
406
406
  currentSize: number;
407
407
  ttlPresets: any;
408
- } {
408
+ } {
409
409
  const stats = this.cacheManager.getStats();
410
410
 
411
411
  return {
@@ -438,7 +438,7 @@ export class CachedWordPressClient extends WordPressClient {
438
438
  siteId: string;
439
439
  baseUrl: string;
440
440
  };
441
- } {
441
+ } {
442
442
  return {
443
443
  statistics: this.getCacheStats(),
444
444
  efficiency: this.getCacheEfficiency(),
package/src/client/api.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Handles all REST API communication with WordPress
4
4
  */
5
5
 
6
- import fetch from "node-fetch";
6
+ // Use native fetch in Node.js 18+
7
7
  import FormData from "form-data";
8
8
  import * as fs from "fs";
9
9
  import * as path from "path";
@@ -207,40 +207,40 @@ export class WordPressClient implements IWordPressClient {
207
207
  const method = this.auth.method?.toLowerCase() as AuthMethod;
208
208
 
209
209
  switch (method) {
210
- case "app-password":
211
- if (this.auth.username && this.auth.appPassword) {
212
- const credentials = Buffer.from(
213
- `${this.auth.username}:${this.auth.appPassword}`,
214
- ).toString("base64");
215
- headers["Authorization"] = `Basic ${credentials}`;
216
- }
217
- break;
218
- case "basic":
219
- if (this.auth.username && this.auth.password) {
220
- const credentials = Buffer.from(
221
- `${this.auth.username}:${this.auth.password}`,
222
- ).toString("base64");
223
- headers["Authorization"] = `Basic ${credentials}`;
224
- }
225
- break;
210
+ case "app-password":
211
+ if (this.auth.username && this.auth.appPassword) {
212
+ const credentials = Buffer.from(
213
+ `${this.auth.username}:${this.auth.appPassword}`,
214
+ ).toString("base64");
215
+ headers["Authorization"] = `Basic ${credentials}`;
216
+ }
217
+ break;
218
+ case "basic":
219
+ if (this.auth.username && this.auth.password) {
220
+ const credentials = Buffer.from(
221
+ `${this.auth.username}:${this.auth.password}`,
222
+ ).toString("base64");
223
+ headers["Authorization"] = `Basic ${credentials}`;
224
+ }
225
+ break;
226
226
 
227
- case "jwt":
228
- if (this.jwtToken) {
229
- headers["Authorization"] = `Bearer ${this.jwtToken}`;
230
- }
231
- break;
227
+ case "jwt":
228
+ if (this.jwtToken) {
229
+ headers["Authorization"] = `Bearer ${this.jwtToken}`;
230
+ }
231
+ break;
232
232
 
233
- case "api-key":
234
- if (this.auth.apiKey) {
235
- headers["X-API-Key"] = this.auth.apiKey;
236
- }
237
- break;
233
+ case "api-key":
234
+ if (this.auth.apiKey) {
235
+ headers["X-API-Key"] = this.auth.apiKey;
236
+ }
237
+ break;
238
238
 
239
- case "cookie":
240
- if (this.auth.nonce) {
241
- headers["X-WP-Nonce"] = this.auth.nonce;
242
- }
243
- break;
239
+ case "cookie":
240
+ if (this.auth.nonce) {
241
+ headers["X-WP-Nonce"] = this.auth.nonce;
242
+ }
243
+ break;
244
244
  }
245
245
  }
246
246
 
@@ -271,19 +271,19 @@ export class WordPressClient implements IWordPressClient {
271
271
 
272
272
  try {
273
273
  switch (method) {
274
- case "app-password":
275
- case "basic":
276
- return await this.authenticateWithBasic();
277
- case "jwt":
278
- return await this.authenticateWithJWT();
279
- case "cookie":
280
- return await this.authenticateWithCookie();
281
- case "api-key":
282
- // API key auth doesn't require separate authentication step
283
- this.authenticated = true;
284
- return true;
285
- default:
286
- throw new Error(`Unsupported authentication method: ${method}`);
274
+ case "app-password":
275
+ case "basic":
276
+ return await this.authenticateWithBasic();
277
+ case "jwt":
278
+ return await this.authenticateWithJWT();
279
+ case "cookie":
280
+ return await this.authenticateWithCookie();
281
+ case "api-key":
282
+ // API key auth doesn't require separate authentication step
283
+ this.authenticated = true;
284
+ return true;
285
+ default:
286
+ throw new Error(`Unsupported authentication method: ${method}`);
287
287
  }
288
288
  } catch (error) {
289
289
  this._stats.authFailures++;
@@ -430,8 +430,15 @@ export class WordPressClient implements IWordPressClient {
430
430
  data instanceof FormData ||
431
431
  (data && typeof data.append === "function")
432
432
  ) {
433
- // For FormData, don't set Content-Type (let fetch set it with boundary)
434
- delete headers["Content-Type"];
433
+ // For FormData, check if it has getHeaders method (form-data package)
434
+ if (data && typeof data.getHeaders === "function") {
435
+ // Use headers from form-data package
436
+ const formHeaders = data.getHeaders();
437
+ Object.assign(headers, formHeaders);
438
+ } else {
439
+ // For native FormData, don't set Content-Type (let fetch set it with boundary)
440
+ delete headers["Content-Type"];
441
+ }
435
442
  fetchOptions.body = data;
436
443
  } else if (Buffer.isBuffer(data)) {
437
444
  // For Buffer data (manual multipart), keep Content-Type from headers
@@ -29,18 +29,18 @@ export class WordPressAuth {
29
29
  async authenticate(): Promise<boolean> {
30
30
  try {
31
31
  switch (this.authType) {
32
- case "app-password":
33
- return await this.handleAppPasswordAuth();
34
- case "jwt":
35
- return await this.handleJWTAuth();
36
- case "basic":
37
- return await this.handleBasicAuth();
38
- case "api-key":
39
- return await this.handleAPIKeyAuth();
40
- case "cookie":
41
- return await this.handleCookieAuth();
42
- default:
43
- throw new Error(`Unsupported authentication type: ${this.authType}`);
32
+ case "app-password":
33
+ return await this.handleAppPasswordAuth();
34
+ case "jwt":
35
+ return await this.handleJWTAuth();
36
+ case "basic":
37
+ return await this.handleBasicAuth();
38
+ case "api-key":
39
+ return await this.handleAPIKeyAuth();
40
+ case "cookie":
41
+ return await this.handleCookieAuth();
42
+ default:
43
+ throw new Error(`Unsupported authentication type: ${this.authType}`);
44
44
  }
45
45
  } catch (error) {
46
46
  logger.error("Authentication failed:", error);
@@ -185,11 +185,11 @@ export class WordPressAuth {
185
185
  */
186
186
  async refreshAuth(): Promise<boolean> {
187
187
  switch (this.authType) {
188
- case "jwt":
189
- return await this.refreshJWTToken();
190
- default:
191
- logger.log(`Authentication refresh not supported for ${this.authType}`);
192
- return true;
188
+ case "jwt":
189
+ return await this.refreshJWTToken();
190
+ default:
191
+ logger.log(`Authentication refresh not supported for ${this.authType}`);
192
+ return true;
193
193
  }
194
194
  }
195
195
 
@@ -312,40 +312,40 @@ export class WordPressAuth {
312
312
  const auth = this.client.config.auth;
313
313
 
314
314
  switch (this.authType) {
315
- case "app-password":
316
- if (auth.username && auth.appPassword) {
317
- const credentials = Buffer.from(
318
- `${auth.username}:${auth.appPassword}`,
319
- ).toString("base64");
320
- headers["Authorization"] = `Basic ${credentials}`;
321
- }
322
- break;
323
- case "basic":
324
- if (auth.username && auth.password) {
325
- const credentials = Buffer.from(
326
- `${auth.username}:${auth.password}`,
327
- ).toString("base64");
328
- headers["Authorization"] = `Basic ${credentials}`;
329
- }
330
- break;
315
+ case "app-password":
316
+ if (auth.username && auth.appPassword) {
317
+ const credentials = Buffer.from(
318
+ `${auth.username}:${auth.appPassword}`,
319
+ ).toString("base64");
320
+ headers["Authorization"] = `Basic ${credentials}`;
321
+ }
322
+ break;
323
+ case "basic":
324
+ if (auth.username && auth.password) {
325
+ const credentials = Buffer.from(
326
+ `${auth.username}:${auth.password}`,
327
+ ).toString("base64");
328
+ headers["Authorization"] = `Basic ${credentials}`;
329
+ }
330
+ break;
331
331
 
332
- case "jwt":
333
- if (auth.token) {
334
- headers["Authorization"] = `Bearer ${auth.token}`;
335
- }
336
- break;
332
+ case "jwt":
333
+ if (auth.token) {
334
+ headers["Authorization"] = `Bearer ${auth.token}`;
335
+ }
336
+ break;
337
337
 
338
- case "api-key":
339
- if (auth.apiKey) {
340
- headers["X-API-Key"] = auth.apiKey;
341
- }
342
- break;
338
+ case "api-key":
339
+ if (auth.apiKey) {
340
+ headers["X-API-Key"] = auth.apiKey;
341
+ }
342
+ break;
343
343
 
344
- case "cookie":
345
- if (auth.nonce) {
346
- headers["X-WP-Nonce"] = auth.nonce;
347
- }
348
- break;
344
+ case "cookie":
345
+ if (auth.nonce) {
346
+ headers["X-WP-Nonce"] = auth.nonce;
347
+ }
348
+ break;
349
349
  }
350
350
 
351
351
  return headers;
@@ -356,23 +356,23 @@ export class WordPressAuth {
356
356
  */
357
357
  requiresSetup(): boolean {
358
358
  switch (this.authType) {
359
- case "jwt":
360
- return !this.client.config.auth.secret;
361
- case "api-key":
362
- return !this.client.config.auth.apiKey;
363
- case "app-password":
364
- return (
365
- !this.client.config.auth.username ||
359
+ case "jwt":
360
+ return !this.client.config.auth.secret;
361
+ case "api-key":
362
+ return !this.client.config.auth.apiKey;
363
+ case "app-password":
364
+ return (
365
+ !this.client.config.auth.username ||
366
366
  !this.client.config.auth.appPassword
367
- );
368
- case "basic":
369
- return (
370
- !this.client.config.auth.username || !this.client.config.auth.password
371
- );
372
- case "cookie":
373
- return false; // Cookie auth can work without additional setup
374
- default:
375
- return true;
367
+ );
368
+ case "basic":
369
+ return (
370
+ !this.client.config.auth.username || !this.client.config.auth.password
371
+ );
372
+ case "cookie":
373
+ return false; // Cookie auth can work without additional setup
374
+ default:
375
+ return true;
376
376
  }
377
377
  }
378
378
 
@@ -381,8 +381,8 @@ export class WordPressAuth {
381
381
  */
382
382
  getSetupInstructions(): string {
383
383
  switch (this.authType) {
384
- case "app-password":
385
- return `
384
+ case "app-password":
385
+ return `
386
386
  To set up Application Password authentication:
387
387
  1. Log into your WordPress admin dashboard
388
388
  2. Go to Users → Profile (or Users → All Users → Edit your user)
@@ -393,8 +393,8 @@ To set up Application Password authentication:
393
393
  7. Set WORDPRESS_USERNAME to your WordPress username
394
394
  `;
395
395
 
396
- case "jwt":
397
- return `
396
+ case "jwt":
397
+ return `
398
398
  To set up JWT authentication:
399
399
  1. Install the "JWT Authentication for WP REST API" plugin
400
400
  2. Add JWT_AUTH_SECRET_KEY to your wp-config.php file
@@ -403,30 +403,30 @@ To set up JWT authentication:
403
403
  5. Set WORDPRESS_USERNAME and WORDPRESS_PASSWORD
404
404
  `;
405
405
 
406
- case "api-key":
407
- return `
406
+ case "api-key":
407
+ return `
408
408
  To set up API Key authentication:
409
409
  1. Install an API Key plugin (varies by plugin)
410
410
  2. Generate an API key in the plugin settings
411
411
  3. Set WORDPRESS_API_KEY environment variable
412
412
  `;
413
413
 
414
- case "basic":
415
- return `
414
+ case "basic":
415
+ return `
416
416
  To set up Basic authentication:
417
417
  1. Set WORDPRESS_USERNAME to your WordPress username
418
418
  2. Set WORDPRESS_PASSWORD to your WordPress password
419
419
  Note: This method is less secure than Application Passwords
420
420
  `;
421
421
 
422
- case "cookie":
423
- return `
422
+ case "cookie":
423
+ return `
424
424
  Cookie authentication is automatically configured when you're logged into WordPress.
425
425
  For write operations, you may need to set WORDPRESS_COOKIE_NONCE.
426
426
  `;
427
427
 
428
- default:
429
- return "No setup instructions available for this authentication method.";
428
+ default:
429
+ return "No setup instructions available for this authentication method.";
430
430
  }
431
431
  }
432
432
  }
@@ -510,17 +510,17 @@ export class CookieAuthProvider implements IAuthProvider {
510
510
  */
511
511
  export function createAuthProvider(method: AuthMethod): IAuthProvider {
512
512
  switch (method) {
513
- case "app-password":
514
- return new AppPasswordAuthProvider();
515
- case "jwt":
516
- return new JWTAuthProvider();
517
- case "basic":
518
- return new BasicAuthProvider();
519
- case "api-key":
520
- return new APIKeyAuthProvider();
521
- case "cookie":
522
- return new CookieAuthProvider();
523
- default:
524
- throw new Error(`Unsupported authentication method: ${method}`);
513
+ case "app-password":
514
+ return new AppPasswordAuthProvider();
515
+ case "jwt":
516
+ return new JWTAuthProvider();
517
+ case "basic":
518
+ return new BasicAuthProvider();
519
+ case "api-key":
520
+ return new APIKeyAuthProvider();
521
+ case "cookie":
522
+ return new CookieAuthProvider();
523
+ default:
524
+ throw new Error(`Unsupported authentication method: ${method}`);
525
525
  }
526
526
  }