mcp-wordpress 1.5.2 → 2.0.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 (190) hide show
  1. package/README.md +332 -61
  2. package/dist/cache/CacheInvalidation.d.ts.map +1 -1
  3. package/dist/cache/CacheInvalidation.js +4 -4
  4. package/dist/cache/CacheInvalidation.js.map +1 -1
  5. package/dist/client/MockWordPressClient.d.ts +55 -0
  6. package/dist/client/MockWordPressClient.d.ts.map +1 -0
  7. package/dist/client/MockWordPressClient.js +369 -0
  8. package/dist/client/MockWordPressClient.js.map +1 -0
  9. package/dist/client/api.d.ts +1 -0
  10. package/dist/client/api.d.ts.map +1 -1
  11. package/dist/client/api.js +26 -60
  12. package/dist/client/api.js.map +1 -1
  13. package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
  14. package/dist/client/managers/AuthenticationManager.js +4 -3
  15. package/dist/client/managers/AuthenticationManager.js.map +1 -1
  16. package/dist/config/ConfigurationSchema.d.ts +3 -3
  17. package/dist/config/ConfigurationSchema.d.ts.map +1 -1
  18. package/dist/config/ConfigurationSchema.js +7 -24
  19. package/dist/config/ConfigurationSchema.js.map +1 -1
  20. package/dist/config/ServerConfiguration.d.ts +8 -0
  21. package/dist/config/ServerConfiguration.d.ts.map +1 -1
  22. package/dist/config/ServerConfiguration.js +80 -31
  23. package/dist/config/ServerConfiguration.js.map +1 -1
  24. package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
  25. package/dist/docs/DocumentationGenerator.js +5 -7
  26. package/dist/docs/DocumentationGenerator.js.map +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +33 -29
  29. package/dist/index.js.map +1 -1
  30. package/dist/security/InputValidator.d.ts.map +1 -1
  31. package/dist/security/InputValidator.js +3 -11
  32. package/dist/security/InputValidator.js.map +1 -1
  33. package/dist/server/ToolRegistry.d.ts +4 -0
  34. package/dist/server/ToolRegistry.d.ts.map +1 -1
  35. package/dist/server/ToolRegistry.js +71 -8
  36. package/dist/server/ToolRegistry.js.map +1 -1
  37. package/dist/tools/auth.d.ts.map +1 -1
  38. package/dist/tools/auth.js +8 -3
  39. package/dist/tools/auth.js.map +1 -1
  40. package/dist/tools/posts.d.ts.map +1 -1
  41. package/dist/tools/posts.js +287 -20
  42. package/dist/tools/posts.js.map +1 -1
  43. package/dist/tools/site.d.ts.map +1 -1
  44. package/dist/tools/site.js +47 -9
  45. package/dist/tools/site.js.map +1 -1
  46. package/dist/tools/users.d.ts.map +1 -1
  47. package/dist/tools/users.js +113 -10
  48. package/dist/tools/users.js.map +1 -1
  49. package/dist/utils/enhancedError.d.ts +61 -0
  50. package/dist/utils/enhancedError.d.ts.map +1 -0
  51. package/dist/utils/enhancedError.js +221 -0
  52. package/dist/utils/enhancedError.js.map +1 -0
  53. package/dist/utils/streaming.d.ts +104 -0
  54. package/dist/utils/streaming.d.ts.map +1 -0
  55. package/dist/utils/streaming.js +312 -0
  56. package/dist/utils/streaming.js.map +1 -0
  57. package/dist/utils/validation.d.ts +19 -3
  58. package/dist/utils/validation.d.ts.map +1 -1
  59. package/dist/utils/validation.js +174 -24
  60. package/dist/utils/validation.js.map +1 -1
  61. package/docs/ARCHITECTURE.md +850 -0
  62. package/docs/CACHING.md +20 -17
  63. package/docs/CONFIGURATION.md +660 -0
  64. package/docs/DOCKER.md +61 -60
  65. package/docs/EVALUATION.md +397 -0
  66. package/docs/INSTALLATION.md +423 -0
  67. package/docs/PERFORMANCE_MONITORING.md +17 -15
  68. package/docs/SECURITY.md +621 -0
  69. package/docs/SECURITY_TESTING.md +22 -26
  70. package/docs/TEST_SITE_SETUP.md +136 -0
  71. package/docs/TROUBLESHOOTING.md +578 -0
  72. package/docs/api/README.md +76 -91
  73. package/docs/api/categories/auth.md +0 -2
  74. package/docs/api/categories/cache.md +0 -2
  75. package/docs/api/categories/comment.md +0 -2
  76. package/docs/api/categories/media.md +0 -2
  77. package/docs/api/categories/page.md +0 -2
  78. package/docs/api/categories/performance.md +0 -2
  79. package/docs/api/categories/post.md +0 -2
  80. package/docs/api/categories/site.md +0 -2
  81. package/docs/api/categories/taxonomy.md +0 -2
  82. package/docs/api/categories/user.md +0 -2
  83. package/docs/api/summary.json +1 -1
  84. package/docs/api/tools/wp_approve_comment.md +11 -3
  85. package/docs/api/tools/wp_cache_clear.md +14 -5
  86. package/docs/api/tools/wp_cache_info.md +14 -5
  87. package/docs/api/tools/wp_cache_stats.md +14 -5
  88. package/docs/api/tools/wp_cache_warm.md +14 -5
  89. package/docs/api/tools/wp_create_application_password.md +11 -3
  90. package/docs/api/tools/wp_create_category.md +11 -3
  91. package/docs/api/tools/wp_create_comment.md +14 -5
  92. package/docs/api/tools/wp_create_page.md +13 -5
  93. package/docs/api/tools/wp_create_post.md +14 -7
  94. package/docs/api/tools/wp_create_tag.md +11 -3
  95. package/docs/api/tools/wp_create_user.md +13 -5
  96. package/docs/api/tools/wp_delete_application_password.md +11 -3
  97. package/docs/api/tools/wp_delete_category.md +11 -3
  98. package/docs/api/tools/wp_delete_comment.md +11 -3
  99. package/docs/api/tools/wp_delete_media.md +10 -3
  100. package/docs/api/tools/wp_delete_page.md +10 -3
  101. package/docs/api/tools/wp_delete_post.md +11 -5
  102. package/docs/api/tools/wp_delete_tag.md +11 -3
  103. package/docs/api/tools/wp_delete_user.md +10 -3
  104. package/docs/api/tools/wp_get_application_passwords.md +11 -3
  105. package/docs/api/tools/wp_get_auth_status.md +11 -3
  106. package/docs/api/tools/wp_get_category.md +11 -3
  107. package/docs/api/tools/wp_get_comment.md +11 -3
  108. package/docs/api/tools/wp_get_current_user.md +11 -3
  109. package/docs/api/tools/wp_get_media.md +11 -3
  110. package/docs/api/tools/wp_get_page.md +11 -3
  111. package/docs/api/tools/wp_get_page_revisions.md +11 -3
  112. package/docs/api/tools/wp_get_post.md +12 -5
  113. package/docs/api/tools/wp_get_post_revisions.md +11 -3
  114. package/docs/api/tools/wp_get_site_settings.md +10 -3
  115. package/docs/api/tools/wp_get_tag.md +11 -3
  116. package/docs/api/tools/wp_get_user.md +11 -3
  117. package/docs/api/tools/wp_list_categories.md +11 -3
  118. package/docs/api/tools/wp_list_comments.md +11 -3
  119. package/docs/api/tools/wp_list_media.md +14 -5
  120. package/docs/api/tools/wp_list_pages.md +14 -5
  121. package/docs/api/tools/wp_list_posts.md +15 -7
  122. package/docs/api/tools/wp_list_tags.md +11 -3
  123. package/docs/api/tools/wp_list_users.md +11 -3
  124. package/docs/api/tools/wp_performance_alerts.md +17 -7
  125. package/docs/api/tools/wp_performance_benchmark.md +17 -7
  126. package/docs/api/tools/wp_performance_export.md +17 -7
  127. package/docs/api/tools/wp_performance_history.md +17 -7
  128. package/docs/api/tools/wp_performance_optimize.md +17 -7
  129. package/docs/api/tools/wp_performance_stats.md +17 -7
  130. package/docs/api/tools/wp_search_site.md +11 -3
  131. package/docs/api/tools/wp_spam_comment.md +11 -3
  132. package/docs/api/tools/wp_switch_auth_method.md +14 -5
  133. package/docs/api/tools/wp_test_auth.md +11 -3
  134. package/docs/api/tools/wp_update_category.md +11 -3
  135. package/docs/api/tools/wp_update_comment.md +14 -5
  136. package/docs/api/tools/wp_update_media.md +14 -5
  137. package/docs/api/tools/wp_update_page.md +13 -5
  138. package/docs/api/tools/wp_update_post.md +14 -7
  139. package/docs/api/tools/wp_update_site_settings.md +14 -5
  140. package/docs/api/tools/wp_update_tag.md +11 -3
  141. package/docs/api/tools/wp_update_user.md +13 -5
  142. package/docs/api/tools/wp_upload_media.md +13 -5
  143. package/docs/api/types/WordPressPost.md +2 -0
  144. package/docs/code-improvements.md +40 -0
  145. package/docs/contract-testing.md +1 -1
  146. package/docs/developer/API_REFERENCE.md +19 -59
  147. package/docs/developer/ARCHITECTURE.md +8 -11
  148. package/docs/developer/BUILD_SYSTEM.md +2 -2
  149. package/docs/developer/CONTRIBUTING.md +3 -5
  150. package/docs/developer/GITHUB_ACTIONS_SETUP.md +2 -2
  151. package/docs/developer/MIGRATION_GUIDE.md +5 -6
  152. package/docs/developer/README.md +2 -1
  153. package/docs/developer/REFACTORING.md +9 -15
  154. package/docs/developer/RELEASE_PROCESS.md +4 -3
  155. package/docs/developer/TESTING.md +2 -2
  156. package/docs/examples/claude-desktop-config.md +8 -0
  157. package/docs/integrations/claude-desktop.md +426 -0
  158. package/docs/integrations/cline.md +537 -0
  159. package/docs/integrations/vs-code.md +515 -0
  160. package/docs/releases/COMMUNITY_ANNOUNCEMENT_v1.1.2.md +30 -23
  161. package/docs/releases/RELEASE_NOTES_v1.1.2.md +7 -6
  162. package/docs/testing-configurations.md +11 -0
  163. package/docs/user-guides/DOCKER_NPM_DTX_SETUP.md +3 -2
  164. package/docs/user-guides/DOCKER_SETUP.md +3 -2
  165. package/docs/user-guides/DTX_SETUP.md +6 -5
  166. package/docs/user-guides/DXT_INSTALLATION.md +4 -4
  167. package/docs/user-guides/NPM_SETUP.md +4 -2
  168. package/docs/user-guides/NPX_SETUP.md +4 -2
  169. package/docs/user-guides/SMITHERY_SETUP.md +402 -0
  170. package/docs/wordpress-rest-api-authentication-troubleshooting.md +45 -42
  171. package/package.json +12 -2
  172. package/src/cache/CacheInvalidation.ts +7 -18
  173. package/src/client/MockWordPressClient.ts +398 -0
  174. package/src/client/api.ts +77 -237
  175. package/src/client/managers/AuthenticationManager.ts +19 -56
  176. package/src/config/ConfigurationSchema.ts +14 -45
  177. package/src/config/ServerConfiguration.ts +98 -71
  178. package/src/docs/DocumentationGenerator.ts +39 -123
  179. package/src/dxt-entry.cjs +4 -1
  180. package/src/index.ts +35 -54
  181. package/src/security/InputValidator.ts +15 -57
  182. package/src/server/ToolRegistry.ts +88 -17
  183. package/src/tools/auth.ts +15 -22
  184. package/src/tools/posts.ts +347 -64
  185. package/src/tools/site.ts +69 -46
  186. package/src/tools/users.ts +142 -44
  187. package/src/utils/enhancedError.ts +248 -0
  188. package/src/utils/streaming.ts +428 -0
  189. package/src/utils/validation.ts +253 -92
  190. package/dist/mcp-wordpress-1.5.2.tgz +0 -0
@@ -1,6 +1,7 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { WordPressClient } from "../client/api.js";
3
3
  import { getErrorMessage } from "../utils/error.js";
4
+ import { EnhancedError, ErrorHandlers } from "../utils/enhancedError.js";
4
5
  import * as Tools from "../tools/index.js";
5
6
  import { z } from "zod";
6
7
 
@@ -27,10 +28,7 @@ export class ToolRegistry {
27
28
  private server: McpServer;
28
29
  private wordpressClients: Map<string, WordPressClient>;
29
30
 
30
- constructor(
31
- server: McpServer,
32
- wordpressClients: Map<string, WordPressClient>,
33
- ) {
31
+ constructor(server: McpServer, wordpressClients: Map<string, WordPressClient>) {
34
32
  this.server = server;
35
33
  this.wordpressClients = wordpressClients;
36
34
  }
@@ -44,10 +42,7 @@ export class ToolRegistry {
44
42
  let toolInstance: any;
45
43
 
46
44
  // Cache and Performance tools need the clients map
47
- if (
48
- ToolClass.name === "CacheTools" ||
49
- ToolClass.name === "PerformanceTools"
50
- ) {
45
+ if (ToolClass.name === "CacheTools" || ToolClass.name === "PerformanceTools") {
51
46
  toolInstance = new ToolClass(this.wordpressClients);
52
47
  } else {
53
48
  toolInstance = new (ToolClass as new () => any)();
@@ -91,18 +86,38 @@ export class ToolRegistry {
91
86
  parameterSchema,
92
87
  async (args: any) => {
93
88
  try {
94
- const siteId = args.site || "default";
89
+ let siteId = args.site;
90
+
91
+ // If no site specified and multiple sites configured, require site parameter
92
+ if (!siteId && this.wordpressClients.size > 1) {
93
+ const availableSites = Array.from(this.wordpressClients.keys());
94
+ const error = ErrorHandlers.siteParameterMissing(availableSites);
95
+ return {
96
+ content: [
97
+ {
98
+ type: "text" as const,
99
+ text: error.toString(),
100
+ },
101
+ ],
102
+ isError: true,
103
+ };
104
+ }
105
+
106
+ // Intelligent site selection for single-site configurations
107
+ if (!siteId) {
108
+ siteId = this.selectBestSite(tool.name, args);
109
+ }
110
+
95
111
  const client = this.wordpressClients.get(siteId);
96
112
 
97
113
  if (!client) {
98
- const availableSites = Array.from(
99
- this.wordpressClients.keys(),
100
- ).join(", ");
114
+ const availableSites = Array.from(this.wordpressClients.keys());
115
+ const error = ErrorHandlers.siteNotFound(siteId, availableSites);
101
116
  return {
102
117
  content: [
103
118
  {
104
119
  type: "text" as const,
105
- text: `Error: Site with ID '${siteId}' not found. Available sites: ${availableSites}`,
120
+ text: error.toString(),
106
121
  },
107
122
  ],
108
123
  isError: true,
@@ -116,10 +131,7 @@ export class ToolRegistry {
116
131
  content: [
117
132
  {
118
133
  type: "text" as const,
119
- text:
120
- typeof result === "string"
121
- ? result
122
- : JSON.stringify(result, null, 2),
134
+ text: typeof result === "string" ? result : JSON.stringify(result, null, 2),
123
135
  },
124
136
  ],
125
137
  };
@@ -136,6 +148,19 @@ export class ToolRegistry {
136
148
  };
137
149
  }
138
150
 
151
+ // Handle enhanced errors with suggestions
152
+ if (error instanceof EnhancedError) {
153
+ return {
154
+ content: [
155
+ {
156
+ type: "text" as const,
157
+ text: error.toString(),
158
+ },
159
+ ],
160
+ isError: true,
161
+ };
162
+ }
163
+
139
164
  return {
140
165
  content: [
141
166
  {
@@ -195,6 +220,52 @@ export class ToolRegistry {
195
220
  }
196
221
  }
197
222
 
223
+ /**
224
+ * Intelligent site selection based on context
225
+ */
226
+ private selectBestSite(toolName: string, args: any): string {
227
+ const availableSites = Array.from(this.wordpressClients.keys());
228
+
229
+ // Single site scenario - use it directly
230
+ if (availableSites.length === 1) {
231
+ return availableSites[0];
232
+ }
233
+
234
+ // Multiple sites scenario - intelligent selection
235
+ if (availableSites.length > 1) {
236
+ // Try to find a site based on context clues
237
+
238
+ // 1. Check if there's a 'default' site
239
+ if (availableSites.includes("default")) {
240
+ return "default";
241
+ }
242
+
243
+ // 2. Check if there's a 'main' or 'primary' site
244
+ const primarySites = availableSites.filter((site) =>
245
+ ["main", "primary", "prod", "production"].includes(site.toLowerCase()),
246
+ );
247
+ if (primarySites.length > 0) {
248
+ return primarySites[0];
249
+ }
250
+
251
+ // 3. For development/test operations, prefer dev sites
252
+ if (toolName.includes("test") || process.env.NODE_ENV === "development") {
253
+ const devSites = availableSites.filter((site) =>
254
+ ["dev", "test", "staging", "local"].includes(site.toLowerCase()),
255
+ );
256
+ if (devSites.length > 0) {
257
+ return devSites[0];
258
+ }
259
+ }
260
+
261
+ // 4. Default to first available site
262
+ return availableSites[0];
263
+ }
264
+
265
+ // Fallback to 'default' if no sites available
266
+ return "default";
267
+ }
268
+
198
269
  /**
199
270
  * Check if error is authentication-related
200
271
  */
package/src/tools/auth.ts CHANGED
@@ -16,21 +16,25 @@ export class AuthTools {
16
16
  {
17
17
  name: "wp_test_auth",
18
18
  description:
19
- "Tests the authentication and connectivity for a configured WordPress site.",
19
+ "Tests the authentication and connectivity for a configured WordPress site with detailed connection diagnostics.\n\n" +
20
+ "**Usage Examples:**\n" +
21
+ "• Test connection: `wp_test_auth`\n" +
22
+ '• Multi-site test: `wp_test_auth --site="my-site"`\n' +
23
+ "• Verify setup: Use this after configuring new credentials\n" +
24
+ "• Troubleshoot: Run when experiencing connection issues\n" +
25
+ "• Health check: Regular verification of WordPress connectivity",
20
26
  parameters: [], // The 'site' parameter is added dynamically by the server
21
27
  handler: this.handleTestAuth.bind(this),
22
28
  },
23
29
  {
24
30
  name: "wp_get_auth_status",
25
- description:
26
- "Gets the current authentication status for a configured WordPress site.",
31
+ description: "Gets the current authentication status for a configured WordPress site.",
27
32
  parameters: [],
28
33
  handler: this.handleGetAuthStatus.bind(this),
29
34
  },
30
35
  {
31
36
  name: "wp_switch_auth_method",
32
- description:
33
- "Switches the authentication method for a site for the current session.",
37
+ description: "Switches the authentication method for a site for the current session.",
34
38
  parameters: [
35
39
  {
36
40
  name: "method",
@@ -42,14 +46,12 @@ export class AuthTools {
42
46
  {
43
47
  name: "username",
44
48
  type: "string",
45
- description:
46
- "The username for 'app-password' or 'basic' authentication.",
49
+ description: "The username for 'app-password' or 'basic' authentication.",
47
50
  },
48
51
  {
49
52
  name: "password",
50
53
  type: "string",
51
- description:
52
- "The Application Password for 'app-password' or password for 'basic' auth.",
54
+ description: "The Application Password for 'app-password' or password for 'basic' auth.",
53
55
  },
54
56
  {
55
57
  name: "jwt_token",
@@ -69,10 +71,7 @@ export class AuthTools {
69
71
  * @param params - The parameters for the tool request.
70
72
  * @returns A promise that resolves to an MCPToolResponse.
71
73
  */
72
- public async handleTestAuth(
73
- client: WordPressClient,
74
- params: any,
75
- ): Promise<any> {
74
+ public async handleTestAuth(client: WordPressClient, params: any): Promise<any> {
76
75
  try {
77
76
  await client.ping();
78
77
  const user = await client.getCurrentUser();
@@ -99,10 +98,7 @@ export class AuthTools {
99
98
  * @param params - The parameters for the tool request.
100
99
  * @returns A promise that resolves to an MCPToolResponse.
101
100
  */
102
- public async handleGetAuthStatus(
103
- client: WordPressClient,
104
- params: any,
105
- ): Promise<any> {
101
+ public async handleGetAuthStatus(client: WordPressClient, params: any): Promise<any> {
106
102
  try {
107
103
  const isAuthenticated = client.isAuthenticated;
108
104
  const config = client.config;
@@ -115,8 +111,7 @@ export class AuthTools {
115
111
  const user = await client.getCurrentUser();
116
112
  content += `**User:** ${user.name} (@${user.slug})\n`;
117
113
  } else {
118
- content +=
119
- "**Status:** Not connected. Use 'wp_test_auth' to connect and verify credentials.";
114
+ content += "**Status:** Not connected. Use 'wp_test_auth' to connect and verify credentials.";
120
115
  }
121
116
 
122
117
  return content;
@@ -148,9 +143,7 @@ export class AuthTools {
148
143
  "Dynamic authentication method switching is not currently supported. Please update your configuration file and restart the server.",
149
144
  );
150
145
  } catch (error) {
151
- throw new Error(
152
- `Failed to switch auth method: ${getErrorMessage(error)}`,
153
- );
146
+ throw new Error(`Failed to switch auth method: ${getErrorMessage(error)}`);
154
147
  }
155
148
  }
156
149
  }