mcp-wordpress 2.10.0 → 2.10.2

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 (198) hide show
  1. package/README.md +17 -19
  2. package/bin/mcp-wordpress.js +3 -3
  3. package/bin/setup.js +140 -141
  4. package/bin/status.js +112 -114
  5. package/dist/client/MockWordPressClient.d.ts.map +1 -1
  6. package/dist/client/MockWordPressClient.js.map +1 -1
  7. package/dist/client/SEOWordPressClient.d.ts.map +1 -1
  8. package/dist/client/SEOWordPressClient.js +16 -14
  9. package/dist/client/SEOWordPressClient.js.map +1 -1
  10. package/dist/client/index.d.ts +6 -6
  11. package/dist/client/index.js +6 -6
  12. package/dist/client/managers/AuthManager.d.ts.map +1 -1
  13. package/dist/client/managers/AuthManager.js +2 -2
  14. package/dist/client/managers/AuthManager.js.map +1 -1
  15. package/dist/client/managers/AuthenticationManager.js +1 -1
  16. package/dist/client/managers/JWTAuthImplementation.d.ts.map +1 -1
  17. package/dist/client/managers/JWTAuthImplementation.js +7 -7
  18. package/dist/client/managers/JWTAuthImplementation.js.map +1 -1
  19. package/dist/client/managers/composed/MigrationAdapter.js +1 -1
  20. package/dist/client/managers/composed/index.d.ts +2 -2
  21. package/dist/client/managers/composed/index.d.ts.map +1 -1
  22. package/dist/client/managers/composed/index.js +1 -1
  23. package/dist/client/managers/composed/index.js.map +1 -1
  24. package/dist/client/managers/implementations/ErrorHandlerImpl.d.ts.map +1 -1
  25. package/dist/client/managers/implementations/ErrorHandlerImpl.js +2 -4
  26. package/dist/client/managers/implementations/ErrorHandlerImpl.js.map +1 -1
  27. package/dist/client/managers/implementations/ParameterValidatorImpl.d.ts.map +1 -1
  28. package/dist/client/managers/implementations/ParameterValidatorImpl.js +1 -1
  29. package/dist/client/managers/implementations/ParameterValidatorImpl.js.map +1 -1
  30. package/dist/client/managers/interfaces/ManagerInterfaces.d.ts.map +1 -1
  31. package/dist/config/index.d.ts +3 -3
  32. package/dist/config/index.js +3 -3
  33. package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
  34. package/dist/docs/MarkdownFormatter.js +7 -7
  35. package/dist/docs/MarkdownFormatter.js.map +1 -1
  36. package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
  37. package/dist/performance/PerformanceAnalytics.js +3 -1
  38. package/dist/performance/PerformanceAnalytics.js.map +1 -1
  39. package/dist/security/InputValidator.js +1 -1
  40. package/dist/security/SecurityCIPipeline.js +1 -1
  41. package/dist/security/SecurityCIPipeline.js.map +1 -1
  42. package/dist/security/SecurityConfig.d.ts.map +1 -1
  43. package/dist/security/SecurityConfig.js +6 -2
  44. package/dist/security/SecurityConfig.js.map +1 -1
  45. package/dist/server/index.d.ts +2 -2
  46. package/dist/server/index.js +2 -2
  47. package/dist/tools/cache.d.ts.map +1 -1
  48. package/dist/tools/cache.js.map +1 -1
  49. package/dist/tools/comments.d.ts.map +1 -1
  50. package/dist/tools/comments.js.map +1 -1
  51. package/dist/tools/performance.d.ts.map +1 -1
  52. package/dist/tools/performance.js.map +1 -1
  53. package/dist/tools/posts/PostHandlers.d.ts.map +1 -1
  54. package/dist/tools/posts/PostHandlers.js.map +1 -1
  55. package/dist/tools/seo/SEOTools.d.ts.map +1 -1
  56. package/dist/tools/seo/SEOTools.js.map +1 -1
  57. package/dist/tools/seo/analyzers/ContentAnalyzer.d.ts.map +1 -1
  58. package/dist/tools/seo/analyzers/ContentAnalyzer.js.map +1 -1
  59. package/dist/types/enhanced.d.ts +17 -17
  60. package/dist/types/enhanced.d.ts.map +1 -1
  61. package/dist/types/enhanced.js +2 -2
  62. package/dist/types/index.d.ts +2 -2
  63. package/dist/types/index.d.ts.map +1 -1
  64. package/dist/types/requests.d.ts +16 -16
  65. package/dist/types/tools.d.ts +46 -46
  66. package/dist/types/tools.d.ts.map +1 -1
  67. package/dist/utils/index.d.ts +7 -7
  68. package/dist/utils/index.js +7 -7
  69. package/docs/ARCHITECTURE.md +17 -17
  70. package/docs/BADGE_UPDATES.md +11 -11
  71. package/docs/CACHING.md +2 -0
  72. package/docs/CI_CD_IMPROVEMENTS.md +8 -5
  73. package/docs/CONFIGURATION.md +76 -46
  74. package/docs/DOCKER_PUBLISHING_TROUBLESHOOTING.md +11 -2
  75. package/docs/EVALUATION.md +16 -21
  76. package/docs/INCREMENTAL_COVERAGE.md +7 -3
  77. package/docs/INSTALLATION.md +33 -19
  78. package/docs/PUBLISHING-TROUBLESHOOTING.md +3 -2
  79. package/docs/SECURITY.md +17 -15
  80. package/docs/SECURITY_TESTING.md +3 -0
  81. package/docs/TROUBLESHOOTING.md +85 -36
  82. package/docs/api/README.md +118 -125
  83. package/docs/api/categories/auth.md +3 -1
  84. package/docs/api/categories/cache.md +3 -1
  85. package/docs/api/categories/comment.md +3 -1
  86. package/docs/api/categories/media.md +3 -1
  87. package/docs/api/categories/page.md +3 -1
  88. package/docs/api/categories/performance.md +3 -1
  89. package/docs/api/categories/post.md +3 -1
  90. package/docs/api/categories/site.md +3 -1
  91. package/docs/api/categories/taxonomy.md +3 -1
  92. package/docs/api/categories/user.md +3 -1
  93. package/docs/api/openapi.json +114 -410
  94. package/docs/api/summary.json +1 -1
  95. package/docs/api/tools/wp_approve_comment.md +13 -25
  96. package/docs/api/tools/wp_cache_clear.md +17 -30
  97. package/docs/api/tools/wp_cache_info.md +16 -29
  98. package/docs/api/tools/wp_cache_stats.md +16 -29
  99. package/docs/api/tools/wp_cache_warm.md +16 -29
  100. package/docs/api/tools/wp_create_application_password.md +14 -26
  101. package/docs/api/tools/wp_create_category.md +14 -26
  102. package/docs/api/tools/wp_create_comment.md +18 -31
  103. package/docs/api/tools/wp_create_page.md +17 -29
  104. package/docs/api/tools/wp_create_post.md +25 -30
  105. package/docs/api/tools/wp_create_tag.md +13 -25
  106. package/docs/api/tools/wp_create_user.md +18 -30
  107. package/docs/api/tools/wp_delete_application_password.md +14 -26
  108. package/docs/api/tools/wp_delete_category.md +13 -25
  109. package/docs/api/tools/wp_delete_comment.md +14 -26
  110. package/docs/api/tools/wp_delete_media.md +14 -25
  111. package/docs/api/tools/wp_delete_page.md +14 -25
  112. package/docs/api/tools/wp_delete_post.md +17 -25
  113. package/docs/api/tools/wp_delete_tag.md +13 -25
  114. package/docs/api/tools/wp_delete_user.md +14 -25
  115. package/docs/api/tools/wp_get_application_passwords.md +13 -25
  116. package/docs/api/tools/wp_get_auth_status.md +12 -24
  117. package/docs/api/tools/wp_get_category.md +13 -25
  118. package/docs/api/tools/wp_get_comment.md +13 -25
  119. package/docs/api/tools/wp_get_current_user.md +17 -30
  120. package/docs/api/tools/wp_get_media.md +13 -25
  121. package/docs/api/tools/wp_get_page.md +13 -25
  122. package/docs/api/tools/wp_get_page_revisions.md +13 -25
  123. package/docs/api/tools/wp_get_post.md +16 -25
  124. package/docs/api/tools/wp_get_post_revisions.md +13 -25
  125. package/docs/api/tools/wp_get_site_settings.md +12 -23
  126. package/docs/api/tools/wp_get_tag.md +13 -25
  127. package/docs/api/tools/wp_get_user.md +13 -25
  128. package/docs/api/tools/wp_list_categories.md +15 -27
  129. package/docs/api/tools/wp_list_comments.md +15 -27
  130. package/docs/api/tools/wp_list_media.md +18 -31
  131. package/docs/api/tools/wp_list_pages.md +18 -31
  132. package/docs/api/tools/wp_list_posts.md +29 -41
  133. package/docs/api/tools/wp_list_tags.md +14 -26
  134. package/docs/api/tools/wp_list_users.md +20 -34
  135. package/docs/api/tools/wp_performance_alerts.md +22 -36
  136. package/docs/api/tools/wp_performance_benchmark.md +20 -34
  137. package/docs/api/tools/wp_performance_export.md +22 -36
  138. package/docs/api/tools/wp_performance_history.md +21 -35
  139. package/docs/api/tools/wp_performance_optimize.md +22 -36
  140. package/docs/api/tools/wp_performance_stats.md +20 -34
  141. package/docs/api/tools/wp_search_site.md +18 -32
  142. package/docs/api/tools/wp_spam_comment.md +13 -25
  143. package/docs/api/tools/wp_switch_auth_method.md +18 -31
  144. package/docs/api/tools/wp_test_auth.md +15 -30
  145. package/docs/api/tools/wp_update_category.md +14 -26
  146. package/docs/api/tools/wp_update_comment.md +17 -30
  147. package/docs/api/tools/wp_update_media.md +19 -32
  148. package/docs/api/tools/wp_update_page.md +18 -30
  149. package/docs/api/tools/wp_update_post.md +21 -30
  150. package/docs/api/tools/wp_update_site_settings.md +18 -31
  151. package/docs/api/tools/wp_update_tag.md +14 -26
  152. package/docs/api/tools/wp_update_user.md +17 -29
  153. package/docs/api/tools/wp_upload_media.md +20 -32
  154. package/docs/api/types/WordPressPost.md +8 -15
  155. package/docs/code-improvements.md +1 -0
  156. package/docs/developer/GITHUB_ACTIONS_SETUP.md +2 -2
  157. package/docs/developer/MAINTENANCE.md +4 -0
  158. package/docs/developer/NPM_AUTH_SETUP.md +3 -0
  159. package/docs/developer/RELEASE_PROCESS.md +1 -0
  160. package/docs/examples/multi-site-setup.md +2 -0
  161. package/docs/integrations/claude-desktop.md +14 -5
  162. package/docs/integrations/cline.md +1 -0
  163. package/docs/user-guides/DTX_SETUP.md +9 -8
  164. package/docs/user-guides/NPX_SETUP.md +5 -9
  165. package/docs/user-guides/SMITHERY_SETUP.md +5 -0
  166. package/docs/v2.2.0-resolution-demo.md +17 -2
  167. package/package.json +2 -1
  168. package/src/cache/__tests__/CacheManager.test.ts +4 -8
  169. package/src/client/MockWordPressClient.ts +5 -1
  170. package/src/client/SEOWordPressClient.ts +30 -26
  171. package/src/client/index.ts +6 -6
  172. package/src/client/managers/AuthManager.ts +16 -8
  173. package/src/client/managers/AuthenticationManager.ts +2 -2
  174. package/src/client/managers/JWTAuthImplementation.ts +24 -27
  175. package/src/client/managers/ManagersIndex.ts +1 -1
  176. package/src/client/managers/composed/MigrationAdapter.ts +1 -1
  177. package/src/client/managers/composed/index.ts +7 -7
  178. package/src/client/managers/implementations/ErrorHandlerImpl.ts +12 -26
  179. package/src/client/managers/implementations/ParameterValidatorImpl.ts +49 -49
  180. package/src/client/managers/interfaces/ManagerInterfaces.ts +13 -9
  181. package/src/config/index.ts +3 -3
  182. package/src/docs/MarkdownFormatter.ts +13 -9
  183. package/src/performance/PerformanceAnalytics.ts +9 -3
  184. package/src/security/InputValidator.ts +1 -1
  185. package/src/security/SecurityCIPipeline.ts +1 -1
  186. package/src/security/SecurityConfig.ts +9 -3
  187. package/src/server/index.ts +2 -2
  188. package/src/tools/cache.ts +3 -1
  189. package/src/tools/comments.ts +3 -1
  190. package/src/tools/performance.ts +7 -3
  191. package/src/tools/posts/PostHandlers.ts +3 -1
  192. package/src/tools/seo/SEOTools.ts +6 -2
  193. package/src/tools/seo/analyzers/ContentAnalyzer.ts +9 -3
  194. package/src/types/enhanced.ts +34 -34
  195. package/src/types/index.ts +13 -11
  196. package/src/types/requests.ts +19 -19
  197. package/src/types/tools.ts +137 -84
  198. package/src/utils/index.ts +7 -7
@@ -34,10 +34,10 @@ export class JWTAuthImplementation {
34
34
  private jwtToken: string | null = null;
35
35
  private tokenExpiry: number | null = null;
36
36
  private refreshTokenValue: string | null = null;
37
-
37
+
38
38
  constructor(
39
39
  private requestManager: RequestManager,
40
- private authConfig: AuthConfig
40
+ private authConfig: AuthConfig,
41
41
  ) {}
42
42
 
43
43
  /**
@@ -49,9 +49,9 @@ export class JWTAuthImplementation {
49
49
  }
50
50
 
51
51
  try {
52
- this.logger.info("Starting JWT authentication", {
52
+ this.logger.info("Starting JWT authentication", {
53
53
  username: this.authConfig.username,
54
- endpoint: "jwt-auth/v1/token"
54
+ endpoint: "jwt-auth/v1/token",
55
55
  });
56
56
 
57
57
  const response = await this.requestManager.request<JWTTokenResponse>(
@@ -64,7 +64,7 @@ export class JWTAuthImplementation {
64
64
  {
65
65
  skipAuth: true, // Don't use auth headers for the auth request itself
66
66
  timeout: 10000,
67
- } as RequestOptions & { skipAuth: boolean }
67
+ } as RequestOptions & { skipAuth: boolean },
68
68
  );
69
69
 
70
70
  if (!response.token) {
@@ -73,10 +73,10 @@ export class JWTAuthImplementation {
73
73
 
74
74
  // Store the JWT token
75
75
  this.jwtToken = response.token;
76
-
76
+
77
77
  // Calculate token expiry (default to 24 hours if not provided)
78
- const expiresInSeconds = response.expires_in || (24 * 60 * 60);
79
- this.tokenExpiry = Date.now() + (expiresInSeconds * 1000);
78
+ const expiresInSeconds = response.expires_in || 24 * 60 * 60;
79
+ this.tokenExpiry = Date.now() + expiresInSeconds * 1000;
80
80
 
81
81
  this.logger.info("JWT authentication successful", {
82
82
  user: response.user_nicename,
@@ -85,14 +85,13 @@ export class JWTAuthImplementation {
85
85
 
86
86
  // Test the token by validating it
87
87
  await this.validateToken();
88
-
89
88
  } catch (error) {
90
89
  this.jwtToken = null;
91
90
  this.tokenExpiry = null;
92
91
  this.logger.error("JWT authentication failed", {
93
92
  error: error instanceof Error ? error.message : String(error),
94
93
  });
95
-
94
+
96
95
  if (error instanceof Error) {
97
96
  throw new AuthenticationError(`JWT authentication failed: ${error.message}`, AUTH_METHODS.JWT);
98
97
  }
@@ -118,11 +117,11 @@ export class JWTAuthImplementation {
118
117
  Authorization: `Bearer ${this.jwtToken}`,
119
118
  },
120
119
  timeout: 5000,
121
- }
120
+ },
122
121
  );
123
122
 
124
123
  const isValid = response.data.status === 200;
125
-
124
+
126
125
  if (!isValid) {
127
126
  this.logger.warn("JWT token validation failed", { response });
128
127
  this.jwtToken = null;
@@ -130,7 +129,6 @@ export class JWTAuthImplementation {
130
129
  }
131
130
 
132
131
  return isValid;
133
-
134
132
  } catch (error) {
135
133
  this.logger.warn("JWT token validation error", {
136
134
  error: error instanceof Error ? error.message : String(error),
@@ -162,14 +160,14 @@ export class JWTAuthImplementation {
162
160
  Authorization: `Bearer ${this.jwtToken}`,
163
161
  },
164
162
  timeout: 5000,
165
- }
163
+ },
166
164
  );
167
165
 
168
166
  if (refreshResponse.token) {
169
167
  this.jwtToken = refreshResponse.token;
170
- const expiresInSeconds = refreshResponse.expires_in || (24 * 60 * 60);
171
- this.tokenExpiry = Date.now() + (expiresInSeconds * 1000);
172
-
168
+ const expiresInSeconds = refreshResponse.expires_in || 24 * 60 * 60;
169
+ this.tokenExpiry = Date.now() + expiresInSeconds * 1000;
170
+
173
171
  this.logger.info("JWT token refreshed successfully", {
174
172
  expiresAt: new Date(this.tokenExpiry).toISOString(),
175
173
  });
@@ -186,17 +184,16 @@ export class JWTAuthImplementation {
186
184
 
187
185
  this.logger.debug("Re-authenticating to refresh JWT token");
188
186
  await this.authenticateJWT();
189
-
190
187
  } catch (error) {
191
188
  this.jwtToken = null;
192
189
  this.tokenExpiry = null;
193
190
  this.logger.error("JWT token refresh failed", {
194
191
  error: error instanceof Error ? error.message : String(error),
195
192
  });
196
-
193
+
197
194
  throw new AuthenticationError(
198
- `JWT token refresh failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
199
- AUTH_METHODS.JWT
195
+ `JWT token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`,
196
+ AUTH_METHODS.JWT,
200
197
  );
201
198
  }
202
199
  }
@@ -208,10 +205,10 @@ export class JWTAuthImplementation {
208
205
  if (!this.tokenExpiry) {
209
206
  return true;
210
207
  }
211
-
208
+
212
209
  // Consider token expired if it expires within 5 minutes (300000ms)
213
210
  const buffer = 5 * 60 * 1000;
214
- return Date.now() >= (this.tokenExpiry - buffer);
211
+ return Date.now() >= this.tokenExpiry - buffer;
215
212
  }
216
213
 
217
214
  /**
@@ -245,7 +242,7 @@ export class JWTAuthImplementation {
245
242
  if (!this.jwtToken) {
246
243
  return {};
247
244
  }
248
-
245
+
249
246
  return {
250
247
  Authorization: `Bearer ${this.jwtToken}`,
251
248
  };
@@ -294,9 +291,9 @@ export class JWTAuthImplementation {
294
291
  {
295
292
  headers: this.getAuthHeaders(),
296
293
  timeout: 5000,
297
- }
294
+ },
298
295
  );
299
-
296
+
300
297
  this.logger.info("JWT token invalidated on server");
301
298
  } catch (error) {
302
299
  this.logger.warn("Failed to invalidate JWT token on server", {
@@ -323,4 +320,4 @@ export class JWTAuthImplementation {
323
320
  expiresIn: this.tokenExpiry ? Math.max(0, this.tokenExpiry - Date.now()) : null,
324
321
  };
325
322
  }
326
- }
323
+ }
@@ -3,4 +3,4 @@
3
3
  * Export all manager classes
4
4
  */
5
5
 
6
- export { AuthManager, type JWTToken } from "./AuthManager.js";
6
+ export { AuthManager, type JWTToken } from "./AuthManager.js";
@@ -245,7 +245,7 @@ import { MigrationAdapter } from '@/client/managers/composed';
245
245
  const USE_COMPOSITION = process.env.USE_COMPOSED_MANAGERS === 'true';
246
246
 
247
247
  const { requestManager, authManager } = await MigrationAdapter.createManagers(
248
- config,
248
+ config,
249
249
  USE_COMPOSITION
250
250
  );
251
251
  \`\`\`
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Composed Managers Export
3
- *
3
+ *
4
4
  * This module provides composition-based alternatives to the inheritance-based managers.
5
5
  * The composed managers offer better testability, flexibility, and adherence to SOLID principles.
6
- *
6
+ *
7
7
  * Usage:
8
8
  * ```typescript
9
9
  * import { createComposedWordPressClient } from '@/client/managers/composed';
10
- *
10
+ *
11
11
  * const client = await createComposedWordPressClient(config);
12
12
  * const posts = await client.getPosts();
13
13
  * ```
@@ -23,7 +23,7 @@ export type {
23
23
  BaseManagerContract,
24
24
  ComposedManager,
25
25
  ManagerFactory,
26
- ManagerCompositionConfig
26
+ ManagerCompositionConfig,
27
27
  } from "../interfaces/ManagerInterfaces.js";
28
28
 
29
29
  // Implementations
@@ -36,12 +36,12 @@ export { ComposedAuthenticationManager } from "../ComposedAuthenticationManager.
36
36
  export { ComposedRequestManager } from "../ComposedRequestManager.js";
37
37
 
38
38
  // Factory and Client
39
- export {
39
+ export {
40
40
  ComposedManagerFactory,
41
41
  ComposedWordPressClient,
42
42
  createComposedWordPressClient,
43
- type ComposedWordPressClientDependencies
43
+ type ComposedWordPressClientDependencies,
44
44
  } from "../ComposedManagerFactory.js";
45
45
 
46
46
  // Migration utilities (for gradual migration from inheritance to composition)
47
- export { MigrationAdapter } from "./MigrationAdapter.js";
47
+ export { MigrationAdapter } from "./MigrationAdapter.js";
@@ -28,18 +28,14 @@ export class ErrorHandlerImpl implements ErrorHandler {
28
28
 
29
29
  if (isErrorLike(error)) {
30
30
  if (error.name === "AbortError" || error.code === "ABORT_ERR") {
31
- throw new WordPressAPIError(
32
- `Request timeout after ${this.configProvider.config.timeout}ms`,
33
- 408,
34
- "timeout"
35
- );
31
+ throw new WordPressAPIError(`Request timeout after ${this.configProvider.config.timeout}ms`, 408, "timeout");
36
32
  }
37
33
 
38
34
  if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
39
35
  throw new WordPressAPIError(
40
- `Cannot connect to WordPress site: ${this.configProvider.config.baseUrl}`,
41
- 503,
42
- "connection_failed"
36
+ `Cannot connect to WordPress site: ${this.configProvider.config.baseUrl}`,
37
+ 503,
38
+ "connection_failed",
43
39
  );
44
40
  }
45
41
  }
@@ -60,27 +56,21 @@ export class ErrorHandlerImpl implements ErrorHandler {
60
56
  */
61
57
  handleAuthError(error: unknown, operation: string): never {
62
58
  logError(`Authentication failed during ${operation}:`, error as Record<string, unknown>);
63
-
59
+
64
60
  if (error instanceof WordPressAPIError) {
65
61
  throw error;
66
62
  }
67
63
 
68
64
  const message = getErrorMessage(error);
69
- throw new WordPressAPIError(
70
- `Authentication failed during ${operation}: ${message}`,
71
- 401,
72
- "auth_failed"
73
- );
65
+ throw new WordPressAPIError(`Authentication failed during ${operation}: ${message}`, 401, "auth_failed");
74
66
  }
75
67
 
76
68
  /**
77
69
  * Handle rate limit errors specifically
78
70
  */
79
71
  handleRateLimitError(retryAfter?: number): never {
80
- const message = retryAfter
81
- ? `Rate limit exceeded. Retry after ${retryAfter} seconds.`
82
- : "Rate limit exceeded.";
83
-
72
+ const message = retryAfter ? `Rate limit exceeded. Retry after ${retryAfter} seconds.` : "Rate limit exceeded.";
73
+
84
74
  throw new WordPressAPIError(message, 429, "rate_limited");
85
75
  }
86
76
 
@@ -91,12 +81,8 @@ export class ErrorHandlerImpl implements ErrorHandler {
91
81
  const message = getErrorMessage(baseError);
92
82
  const contextString = Object.entries(context)
93
83
  .map(([key, value]) => `${key}=${String(value)}`)
94
- .join(', ');
95
-
96
- return new WordPressAPIError(
97
- `${message} (Context: ${contextString})`,
98
- 500,
99
- "contextual_error"
100
- );
84
+ .join(", ");
85
+
86
+ return new WordPressAPIError(`${message} (Context: ${contextString})`, 500, "contextual_error");
101
87
  }
102
- }
88
+ }
@@ -42,12 +42,16 @@ export class ParameterValidatorImpl implements ParameterValidator {
42
42
  /**
43
43
  * Validate string parameters
44
44
  */
45
- validateString(value: unknown, fieldName: string, options?: {
46
- required?: boolean;
47
- minLength?: number;
48
- maxLength?: number;
49
- pattern?: RegExp;
50
- }): string {
45
+ validateString(
46
+ value: unknown,
47
+ fieldName: string,
48
+ options?: {
49
+ required?: boolean;
50
+ minLength?: number;
51
+ maxLength?: number;
52
+ pattern?: RegExp;
53
+ },
54
+ ): string {
51
55
  if (options?.required && (value === undefined || value === null || value === "")) {
52
56
  throw new WordPressAPIError(`${fieldName} is required`, 400, "missing_parameter");
53
57
  }
@@ -62,26 +66,22 @@ export class ParameterValidatorImpl implements ParameterValidator {
62
66
 
63
67
  if (options?.minLength && value.length < options.minLength) {
64
68
  throw new WordPressAPIError(
65
- `${fieldName} must be at least ${options.minLength} characters`,
66
- 400,
67
- "parameter_too_short"
69
+ `${fieldName} must be at least ${options.minLength} characters`,
70
+ 400,
71
+ "parameter_too_short",
68
72
  );
69
73
  }
70
74
 
71
75
  if (options?.maxLength && value.length > options.maxLength) {
72
76
  throw new WordPressAPIError(
73
- `${fieldName} must be no more than ${options.maxLength} characters`,
74
- 400,
75
- "parameter_too_long"
77
+ `${fieldName} must be no more than ${options.maxLength} characters`,
78
+ 400,
79
+ "parameter_too_long",
76
80
  );
77
81
  }
78
82
 
79
83
  if (options?.pattern && !options.pattern.test(value)) {
80
- throw new WordPressAPIError(
81
- `${fieldName} format is invalid`,
82
- 400,
83
- "invalid_parameter_format"
84
- );
84
+ throw new WordPressAPIError(`${fieldName} format is invalid`, 400, "invalid_parameter_format");
85
85
  }
86
86
 
87
87
  return value;
@@ -90,12 +90,16 @@ export class ParameterValidatorImpl implements ParameterValidator {
90
90
  /**
91
91
  * Validate numeric parameters
92
92
  */
93
- validateNumber(value: unknown, fieldName: string, options?: {
94
- required?: boolean;
95
- min?: number;
96
- max?: number;
97
- integer?: boolean;
98
- }): number {
93
+ validateNumber(
94
+ value: unknown,
95
+ fieldName: string,
96
+ options?: {
97
+ required?: boolean;
98
+ min?: number;
99
+ max?: number;
100
+ integer?: boolean;
101
+ },
102
+ ): number {
99
103
  if (options?.required && (value === undefined || value === null)) {
100
104
  throw new WordPressAPIError(`${fieldName} is required`, 400, "missing_parameter");
101
105
  }
@@ -115,19 +119,11 @@ export class ParameterValidatorImpl implements ParameterValidator {
115
119
  }
116
120
 
117
121
  if (options?.min !== undefined && numValue < options.min) {
118
- throw new WordPressAPIError(
119
- `${fieldName} must be at least ${options.min}`,
120
- 400,
121
- "parameter_too_small"
122
- );
122
+ throw new WordPressAPIError(`${fieldName} must be at least ${options.min}`, 400, "parameter_too_small");
123
123
  }
124
124
 
125
125
  if (options?.max !== undefined && numValue > options.max) {
126
- throw new WordPressAPIError(
127
- `${fieldName} must be no more than ${options.max}`,
128
- 400,
129
- "parameter_too_large"
130
- );
126
+ throw new WordPressAPIError(`${fieldName} must be no more than ${options.max}`, 400, "parameter_too_large");
131
127
  }
132
128
 
133
129
  return numValue;
@@ -136,12 +132,16 @@ export class ParameterValidatorImpl implements ParameterValidator {
136
132
  /**
137
133
  * Validate array parameters
138
134
  */
139
- validateArray<T>(value: unknown, fieldName: string, options?: {
140
- required?: boolean;
141
- minLength?: number;
142
- maxLength?: number;
143
- itemValidator?: (item: unknown) => T;
144
- }): T[] {
135
+ validateArray<T>(
136
+ value: unknown,
137
+ fieldName: string,
138
+ options?: {
139
+ required?: boolean;
140
+ minLength?: number;
141
+ maxLength?: number;
142
+ itemValidator?: (item: unknown) => T;
143
+ },
144
+ ): T[] {
145
145
  if (options?.required && (value === undefined || value === null)) {
146
146
  throw new WordPressAPIError(`${fieldName} is required`, 400, "missing_parameter");
147
147
  }
@@ -156,17 +156,17 @@ export class ParameterValidatorImpl implements ParameterValidator {
156
156
 
157
157
  if (options?.minLength && value.length < options.minLength) {
158
158
  throw new WordPressAPIError(
159
- `${fieldName} must contain at least ${options.minLength} items`,
160
- 400,
161
- "array_too_short"
159
+ `${fieldName} must contain at least ${options.minLength} items`,
160
+ 400,
161
+ "array_too_short",
162
162
  );
163
163
  }
164
164
 
165
165
  if (options?.maxLength && value.length > options.maxLength) {
166
166
  throw new WordPressAPIError(
167
- `${fieldName} must contain no more than ${options.maxLength} items`,
168
- 400,
169
- "array_too_long"
167
+ `${fieldName} must contain no more than ${options.maxLength} items`,
168
+ 400,
169
+ "array_too_long",
170
170
  );
171
171
  }
172
172
 
@@ -179,7 +179,7 @@ export class ParameterValidatorImpl implements ParameterValidator {
179
179
  throw new WordPressAPIError(
180
180
  `${fieldName}[${index}] validation failed: ${getErrorMessage(error)}`,
181
181
  400,
182
- "array_item_invalid"
182
+ "array_item_invalid",
183
183
  );
184
184
  }
185
185
  });
@@ -190,7 +190,7 @@ export class ParameterValidatorImpl implements ParameterValidator {
190
190
  throw new WordPressAPIError(
191
191
  `${fieldName} validation failed: ${getErrorMessage(error)}`,
192
192
  400,
193
- "array_validation_failed"
193
+ "array_validation_failed",
194
194
  );
195
195
  }
196
196
  }
@@ -205,7 +205,7 @@ export class ParameterValidatorImpl implements ParameterValidator {
205
205
  const id = this.validateNumber(value, fieldName, {
206
206
  required: true,
207
207
  min: 1,
208
- integer: true
208
+ integer: true,
209
209
  });
210
210
 
211
211
  return id;
@@ -218,4 +218,4 @@ function getErrorMessage(error: unknown): string {
218
218
  return error.message;
219
219
  }
220
220
  return String(error);
221
- }
221
+ }
@@ -10,7 +10,7 @@ import type { WordPressClientConfig } from "@/types/client.js";
10
10
  */
11
11
  export interface ConfigurationProvider {
12
12
  readonly config: WordPressClientConfig;
13
-
13
+
14
14
  /**
15
15
  * Get configuration value by path
16
16
  */
@@ -49,12 +49,16 @@ export interface ParameterValidator {
49
49
  /**
50
50
  * Validate string parameters
51
51
  */
52
- validateString(value: unknown, fieldName: string, options?: {
53
- required?: boolean;
54
- minLength?: number;
55
- maxLength?: number;
56
- pattern?: RegExp;
57
- }): string;
52
+ validateString(
53
+ value: unknown,
54
+ fieldName: string,
55
+ options?: {
56
+ required?: boolean;
57
+ minLength?: number;
58
+ maxLength?: number;
59
+ pattern?: RegExp;
60
+ },
61
+ ): string;
58
62
 
59
63
  /**
60
64
  * Validate WordPress ID parameters
@@ -148,7 +152,7 @@ export interface ManagerFactory {
148
152
  export interface ManagerCompositionConfig {
149
153
  /** WordPress client configuration */
150
154
  clientConfig: WordPressClientConfig;
151
-
155
+
152
156
  /** Optional custom implementations */
153
157
  customErrorHandler?: ErrorHandler;
154
158
  customValidator?: ParameterValidator;
@@ -168,4 +172,4 @@ export interface ComposedManager extends BaseManagerContract, RequestHandler, Au
168
172
  * Cleanup resources
169
173
  */
170
174
  dispose(): void;
171
- }
175
+ }
@@ -4,10 +4,10 @@
4
4
  */
5
5
 
6
6
  // Main Configuration System
7
- export { Config, ConfigHelpers, config } from './Config.js';
7
+ export { Config, ConfigHelpers, config } from "./Config.js";
8
8
 
9
9
  // Configuration Schema and Validation
10
- export * from './ConfigurationSchema.js';
10
+ export * from "./ConfigurationSchema.js";
11
11
 
12
12
  // Server Configuration (legacy)
13
- export * from './ServerConfiguration.js';
13
+ export * from "./ServerConfiguration.js";
@@ -25,10 +25,12 @@ ${this.generateBadges()}
25
25
 
26
26
  ## Overview
27
27
 
28
- The WordPress MCP Server provides **${summary.totalTools} tools** across **${summary.totalCategories} categories** for comprehensive WordPress management through the Model Context Protocol.
28
+ The WordPress MCP Server provides **${summary.totalTools} tools** across **${
29
+ summary.totalCategories
30
+ } categories** for comprehensive WordPress management through the Model Context Protocol.
29
31
 
30
- **Last Updated:** ${new Date(summary.lastUpdated).toLocaleDateString()}
31
- **Version:** ${summary.version}
32
+ **Last Updated:** ${new Date(summary.lastUpdated).toLocaleDateString()}
33
+ **Version:** ${summary.version}
32
34
  **Coverage:** ${summary.coverage.toolsWithExamples}/${summary.totalTools} tools with examples
33
35
 
34
36
  ## Quick Start
@@ -66,7 +68,7 @@ ${this.generateToolsTable(tools)}
66
68
 
67
69
  All tools support multiple authentication methods:
68
70
  - **Application Passwords** (recommended)
69
- - **JWT Authentication**
71
+ - **JWT Authentication**
70
72
  - **Basic Authentication** (development only)
71
73
  - **API Key Authentication**
72
74
 
@@ -214,7 +216,7 @@ wp_list_${category.name.toLowerCase()}
214
216
  # Get specific item
215
217
  wp_get_${category.name.toLowerCase().slice(0, -1)} --id=123
216
218
 
217
- # Create new item
219
+ # Create new item
218
220
  wp_create_${category.name.toLowerCase().slice(0, -1)} --title="Example"
219
221
  \`\`\`
220
222
 
@@ -272,7 +274,9 @@ ${type.examples.length > 1 ? this.generateAdditionalExamples(type.examples.slice
272
274
  const defaultVal = param.defaultValue !== undefined ? `\`${param.defaultValue}\`` : "-";
273
275
  const required = param.required ? "✅" : "❌";
274
276
 
275
- return `| \`${param.name}\` | \`${param.type}\` | ${required} | ${param.description} | ${defaultVal} | ${examples || "-"} |`;
277
+ return `| \`${param.name}\` | \`${param.type}\` | ${required} | ${param.description} | ${defaultVal} | ${
278
+ examples || "-"
279
+ } |`;
276
280
  });
277
281
 
278
282
  return [headers, separator, ...rows].join("\n");
@@ -375,7 +379,7 @@ ${permissions.map((perm) => `- \`${perm}\``).join("\n")}
375
379
  return `### Common Errors
376
380
 
377
381
  - **Authentication Error**: Invalid credentials or insufficient permissions
378
- - **Validation Error**: Invalid or missing required parameters
382
+ - **Validation Error**: Invalid or missing required parameters
379
383
  - **Not Found Error**: Requested resource does not exist
380
384
  - **Server Error**: Internal WordPress or network error
381
385
 
@@ -386,8 +390,8 @@ See [Error Handling Guide](../error-handling.md) for complete error reference.`;
386
390
  .map(
387
391
  (error) => `### ${(error as Record<string, unknown>).code}
388
392
 
389
- **Message:** ${(error as Record<string, unknown>).message}
390
- **Description:** ${(error as Record<string, unknown>).description}
393
+ **Message:** ${(error as Record<string, unknown>).message}
394
+ **Description:** ${(error as Record<string, unknown>).description}
391
395
  **Resolution:** ${(error as Record<string, unknown>).resolution}
392
396
  `,
393
397
  )
@@ -196,7 +196,9 @@ export class PerformanceAnalytics {
196
196
  category: "optimization",
197
197
  priority: "high",
198
198
  title: "Improve Cache Hit Rate",
199
- description: `Current cache hit rate is ${(currentMetrics.cache.hitRate * 100).toFixed(1)}%, which is below optimal performance.`,
199
+ description: `Current cache hit rate is ${(currentMetrics.cache.hitRate * 100).toFixed(
200
+ 1,
201
+ )}%, which is below optimal performance.`,
200
202
  impact: "performance",
201
203
  recommendation: "Implement cache warming strategies and optimize TTL values for frequently accessed data.",
202
204
  estimatedImprovement: "20-40% reduction in response times",
@@ -212,7 +214,9 @@ export class PerformanceAnalytics {
212
214
  category: "optimization",
213
215
  priority: "high",
214
216
  title: "Reduce Response Times",
215
- description: `Average response time of ${currentMetrics.requests.averageResponseTime.toFixed(0)}ms is above recommended threshold.`,
217
+ description: `Average response time of ${currentMetrics.requests.averageResponseTime.toFixed(
218
+ 0,
219
+ )}ms is above recommended threshold.`,
216
220
  impact: "user_experience",
217
221
  recommendation: "Enable aggressive caching, optimize database queries, or consider upgrading server resources.",
218
222
  estimatedImprovement: "50-70% reduction in response times",
@@ -249,7 +253,9 @@ export class PerformanceAnalytics {
249
253
  category: "optimization",
250
254
  priority: "low",
251
255
  title: "Optimize Frequently Used Tools",
252
- description: `Most used tools: ${mostUsed.map(([tool]) => tool).join(", ")}. Consider optimizing these workflows.`,
256
+ description: `Most used tools: ${mostUsed
257
+ .map(([tool]) => tool)
258
+ .join(", ")}. Consider optimizing these workflows.`,
253
259
  impact: "performance",
254
260
  recommendation: "Create cached workflows or batch operations for frequently used tools.",
255
261
  estimatedImprovement: "10-20% reduction in API calls",
@@ -175,7 +175,7 @@ export function validateSecurity(schema: z.ZodSchema) {
175
175
  logger.info(`Security validation passed for ${propertyName}`, {
176
176
  timestamp: new Date().toISOString(),
177
177
  method: propertyName,
178
- paramCount: typeof validatedParams === 'object' && validatedParams ? Object.keys(validatedParams).length : 0,
178
+ paramCount: typeof validatedParams === "object" && validatedParams ? Object.keys(validatedParams).length : 0,
179
179
  });
180
180
 
181
181
  // Call original method with validated params
@@ -237,7 +237,7 @@ export class SecurityCIPipeline {
237
237
  try {
238
238
  const scanPromise = scanner.scanCodeForVulnerabilities
239
239
  ? scanner.scanCodeForVulnerabilities()
240
- : (scanner.performScan?.() ?? Promise.resolve({ vulnerabilities: [], riskScore: 0 }));
240
+ : scanner.performScan?.() ?? Promise.resolve({ vulnerabilities: [], riskScore: 0 });
241
241
 
242
242
  if (opts.timeout && opts.timeout > 0) {
243
243
  const res = await Promise.race([
@@ -190,7 +190,9 @@ export class SecurityUtils {
190
190
  return obj;
191
191
  }
192
192
 
193
- const working: Record<string, unknown> | unknown[] = Array.isArray(obj) ? [...obj] : { ...(obj as Record<string, unknown>) };
193
+ const working: Record<string, unknown> | unknown[] = Array.isArray(obj)
194
+ ? [...obj]
195
+ : { ...(obj as Record<string, unknown>) };
194
196
 
195
197
  if (Array.isArray(working)) {
196
198
  return working.map((val) => (typeof val === "object" ? SecurityUtils.redactSensitiveData(val) : val));
@@ -276,8 +278,12 @@ export function createSecureError(
276
278
  const secureError = new Error(fallbackMessage);
277
279
 
278
280
  // Preserve error code if it's safe
279
- if (error && typeof (error as { code?: unknown }).code === "string" && !(error as { code: string }).code.includes("_")) {
280
- (secureError as unknown as Record<string, unknown>).code = (error as { code: string }).code;
281
+ if (
282
+ error &&
283
+ typeof (error as { code?: unknown }).code === "string" &&
284
+ !(error as { code: string }).code.includes("_")
285
+ ) {
286
+ (secureError as unknown as Record<string, unknown>).code = (error as { code: string }).code;
281
287
  }
282
288
 
283
289
  return secureError;