mcp-wordpress 2.4.2 → 2.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.
- package/README.md +114 -48
- package/dist/ajv-patch.js +34 -0
- package/dist/cache/CacheInvalidation.d.ts +3 -1
- package/dist/cache/CacheInvalidation.d.ts.map +1 -1
- package/dist/cache/CacheInvalidation.js +10 -4
- package/dist/cache/CacheInvalidation.js.map +1 -1
- package/dist/cache/CacheManager.d.ts +3 -2
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.js +11 -3
- package/dist/cache/CacheManager.js.map +1 -1
- package/dist/cache/HttpCacheWrapper.d.ts +7 -6
- package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
- package/dist/cache/HttpCacheWrapper.js +8 -5
- package/dist/cache/HttpCacheWrapper.js.map +1 -1
- package/dist/cache/__tests__/HttpCacheWrapper.test.js +6 -5
- package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -1
- package/dist/cache/index.d.ts +3 -3
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/client/CachedWordPressClient.d.ts +23 -9
- package/dist/client/CachedWordPressClient.d.ts.map +1 -1
- package/dist/client/CachedWordPressClient.js +4 -1
- package/dist/client/CachedWordPressClient.js.map +1 -1
- package/dist/client/MockWordPressClient.d.ts +2 -1
- package/dist/client/MockWordPressClient.d.ts.map +1 -1
- package/dist/client/MockWordPressClient.js +3 -1
- package/dist/client/MockWordPressClient.js.map +1 -1
- package/dist/client/api.d.ts +17 -13
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +135 -30
- package/dist/client/api.js.map +1 -1
- package/dist/client/auth.d.ts.map +1 -1
- package/dist/client/auth.js +2 -3
- package/dist/client/auth.js.map +1 -1
- package/dist/client/managers/AuthenticationManager.d.ts +55 -2
- package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
- package/dist/client/managers/AuthenticationManager.js +269 -71
- package/dist/client/managers/AuthenticationManager.js.map +1 -1
- package/dist/client/managers/BaseManager.d.ts +3 -3
- package/dist/client/managers/BaseManager.d.ts.map +1 -1
- package/dist/client/managers/BaseManager.js +11 -5
- package/dist/client/managers/BaseManager.js.map +1 -1
- package/dist/client/managers/RequestManager.d.ts +2 -2
- package/dist/client/managers/RequestManager.d.ts.map +1 -1
- package/dist/client/managers/RequestManager.js +25 -12
- package/dist/client/managers/RequestManager.js.map +1 -1
- package/dist/config/Config.d.ts +155 -0
- package/dist/config/Config.d.ts.map +1 -0
- package/dist/config/Config.js +215 -0
- package/dist/config/Config.js.map +1 -0
- package/dist/config/ConfigurationSchema.d.ts +21 -21
- package/dist/config/ConfigurationSchema.d.ts.map +1 -1
- package/dist/config/ConfigurationSchema.js +19 -2
- package/dist/config/ConfigurationSchema.js.map +1 -1
- package/dist/config/ServerConfiguration.d.ts +2 -1
- package/dist/config/ServerConfiguration.d.ts.map +1 -1
- package/dist/config/ServerConfiguration.js +50 -41
- package/dist/config/ServerConfiguration.js.map +1 -1
- package/dist/docs/DocumentationGenerator.d.ts +9 -8
- package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
- package/dist/docs/DocumentationGenerator.js +10 -7
- package/dist/docs/DocumentationGenerator.js.map +1 -1
- package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
- package/dist/docs/MarkdownFormatter.js +3 -2
- package/dist/docs/MarkdownFormatter.js.map +1 -1
- package/dist/dxt-entry.cjs +81 -0
- package/dist/dxt-entry.js +15 -14
- package/dist/dxt-entry.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -21
- package/dist/index.js.map +1 -1
- package/dist/performance/MetricsCollector.d.ts +13 -7
- package/dist/performance/MetricsCollector.d.ts.map +1 -1
- package/dist/performance/MetricsCollector.js +69 -27
- package/dist/performance/MetricsCollector.js.map +1 -1
- package/dist/performance/PerformanceAnalytics.d.ts +8 -2
- package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
- package/dist/performance/PerformanceAnalytics.js +17 -47
- package/dist/performance/PerformanceAnalytics.js.map +1 -1
- package/dist/performance/PerformanceMonitor.d.ts +2 -1
- package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
- package/dist/performance/PerformanceMonitor.js +12 -13
- package/dist/performance/PerformanceMonitor.js.map +1 -1
- package/dist/performance/index.d.ts +2 -2
- package/dist/performance/index.d.ts.map +1 -1
- package/dist/security/AISecurityScanner.d.ts +1 -0
- package/dist/security/AISecurityScanner.d.ts.map +1 -1
- package/dist/security/AISecurityScanner.js +22 -12
- package/dist/security/AISecurityScanner.js.map +1 -1
- package/dist/security/AutomatedRemediation.d.ts +4 -3
- package/dist/security/AutomatedRemediation.d.ts.map +1 -1
- package/dist/security/AutomatedRemediation.js +46 -15
- package/dist/security/AutomatedRemediation.js.map +1 -1
- package/dist/security/InputValidator.d.ts +13 -9
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +4 -2
- package/dist/security/InputValidator.js.map +1 -1
- package/dist/security/SecurityCIPipeline.d.ts +1 -1
- package/dist/security/SecurityCIPipeline.d.ts.map +1 -1
- package/dist/security/SecurityCIPipeline.js +38 -29
- package/dist/security/SecurityCIPipeline.js.map +1 -1
- package/dist/security/SecurityConfig.d.ts +3 -3
- package/dist/security/SecurityConfig.d.ts.map +1 -1
- package/dist/security/SecurityConfig.js +13 -9
- package/dist/security/SecurityConfig.js.map +1 -1
- package/dist/security/SecurityConfigManager.d.ts +2 -2
- package/dist/security/SecurityConfigManager.d.ts.map +1 -1
- package/dist/security/SecurityConfigManager.js +20 -15
- package/dist/security/SecurityConfigManager.js.map +1 -1
- package/dist/security/SecurityMonitoring.d.ts +2 -2
- package/dist/security/SecurityMonitoring.d.ts.map +1 -1
- package/dist/security/SecurityMonitoring.js +19 -17
- package/dist/security/SecurityMonitoring.js.map +1 -1
- package/dist/security/SecurityReviewer.d.ts.map +1 -1
- package/dist/security/SecurityReviewer.js +10 -7
- package/dist/security/SecurityReviewer.js.map +1 -1
- package/dist/security/index.d.ts +24 -23
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +52 -23
- package/dist/security/index.js.map +1 -1
- package/dist/server/ConnectionTester.d.ts +12 -4
- package/dist/server/ConnectionTester.d.ts.map +1 -1
- package/dist/server/ConnectionTester.js +96 -22
- package/dist/server/ConnectionTester.js.map +1 -1
- package/dist/server/ToolRegistry.d.ts +2 -2
- package/dist/server/ToolRegistry.d.ts.map +1 -1
- package/dist/server/ToolRegistry.js +10 -5
- package/dist/server/ToolRegistry.js.map +1 -1
- package/dist/tools/BaseToolManager.d.ts +47 -11
- package/dist/tools/BaseToolManager.d.ts.map +1 -1
- package/dist/tools/BaseToolManager.js +168 -29
- package/dist/tools/BaseToolManager.js.map +1 -1
- package/dist/tools/auth.d.ts +16 -10
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +3 -2
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/cache.d.ts +30 -30
- package/dist/tools/cache.d.ts.map +1 -1
- package/dist/tools/cache.js +1 -6
- package/dist/tools/cache.js.map +1 -1
- package/dist/tools/comments.d.ts +20 -20
- package/dist/tools/comments.d.ts.map +1 -1
- package/dist/tools/comments.js +16 -9
- package/dist/tools/comments.js.map +1 -1
- package/dist/tools/media.d.ts +18 -16
- package/dist/tools/media.d.ts.map +1 -1
- package/dist/tools/media.js +16 -15
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/pages.d.ts +19 -17
- package/dist/tools/pages.d.ts.map +1 -1
- package/dist/tools/pages.js +16 -12
- package/dist/tools/pages.js.map +1 -1
- package/dist/tools/performance.d.ts +11 -1
- package/dist/tools/performance.d.ts.map +1 -1
- package/dist/tools/performance.js +67 -34
- package/dist/tools/performance.js.map +1 -1
- package/dist/tools/posts/PostHandlers.d.ts +46 -0
- package/dist/tools/posts/PostHandlers.d.ts.map +1 -0
- package/dist/tools/posts/PostHandlers.js +400 -0
- package/dist/tools/posts/PostHandlers.js.map +1 -0
- package/dist/tools/posts/PostToolDefinitions.d.ts +37 -0
- package/dist/tools/posts/PostToolDefinitions.d.ts.map +1 -0
- package/dist/tools/posts/PostToolDefinitions.js +236 -0
- package/dist/tools/posts/PostToolDefinitions.js.map +1 -0
- package/dist/tools/posts/index.d.ts +138 -0
- package/dist/tools/posts/index.d.ts.map +1 -0
- package/dist/tools/posts/index.js +163 -0
- package/dist/tools/posts/index.js.map +1 -0
- package/dist/tools/posts.d.ts +10 -246
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +11 -723
- package/dist/tools/posts.js.map +1 -1
- package/dist/tools/site.d.ts +19 -18
- package/dist/tools/site.d.ts.map +1 -1
- package/dist/tools/site.js +14 -10
- package/dist/tools/site.js.map +1 -1
- package/dist/tools/taxonomies.d.ts +23 -24
- package/dist/tools/taxonomies.d.ts.map +1 -1
- package/dist/tools/taxonomies.js +24 -18
- package/dist/tools/taxonomies.js.map +1 -1
- package/dist/tools/users.d.ts +20 -15
- package/dist/tools/users.d.ts.map +1 -1
- package/dist/tools/users.js +12 -8
- package/dist/tools/users.js.map +1 -1
- package/dist/types/client.d.ts +48 -41
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js +30 -5
- package/dist/types/client.js.map +1 -1
- package/dist/types/enhanced.d.ts +237 -0
- package/dist/types/enhanced.d.ts.map +1 -0
- package/dist/types/enhanced.js +49 -0
- package/dist/types/enhanced.js.map +1 -0
- package/dist/types/index.d.ts +15 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/mcp.d.ts +12 -12
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/requests.d.ts +322 -0
- package/dist/types/requests.d.ts.map +1 -0
- package/dist/types/requests.js +8 -0
- package/dist/types/requests.js.map +1 -0
- package/dist/types/tools.d.ts +506 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +8 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/wordpress.d.ts +43 -15
- package/dist/types/wordpress.d.ts.map +1 -1
- package/dist/types/wordpress.js +8 -1
- package/dist/types/wordpress.js.map +1 -1
- package/dist/utils/debug.d.ts +19 -11
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist/utils/debug.js +46 -10
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/enhancedError.d.ts +8 -8
- package/dist/utils/enhancedError.d.ts.map +1 -1
- package/dist/utils/enhancedError.js.map +1 -1
- package/dist/utils/error.d.ts +2 -4
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js +42 -5
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/logger.d.ts +106 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +280 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/streaming.d.ts +9 -9
- package/dist/utils/streaming.d.ts.map +1 -1
- package/dist/utils/streaming.js +71 -52
- package/dist/utils/streaming.js.map +1 -1
- package/dist/utils/toolWrapper.d.ts +9 -7
- package/dist/utils/toolWrapper.d.ts.map +1 -1
- package/dist/utils/toolWrapper.js.map +1 -1
- package/dist/utils/validation/core.d.ts +21 -0
- package/dist/utils/validation/core.d.ts.map +1 -0
- package/dist/utils/validation/core.js +71 -0
- package/dist/utils/validation/core.js.map +1 -0
- package/dist/utils/validation/index.d.ts +25 -0
- package/dist/utils/validation/index.d.ts.map +1 -0
- package/dist/utils/validation/index.js +29 -0
- package/dist/utils/validation/index.js.map +1 -0
- package/dist/utils/validation/network.d.ts +19 -0
- package/dist/utils/validation/network.d.ts.map +1 -0
- package/dist/utils/validation/network.js +93 -0
- package/dist/utils/validation/network.js.map +1 -0
- package/dist/utils/validation/rateLimit.d.ts +21 -0
- package/dist/utils/validation/rateLimit.d.ts.map +1 -0
- package/dist/utils/validation/rateLimit.js +43 -0
- package/dist/utils/validation/rateLimit.js.map +1 -0
- package/dist/utils/validation/security.d.ts +29 -0
- package/dist/utils/validation/security.d.ts.map +1 -0
- package/dist/utils/validation/security.js +327 -0
- package/dist/utils/validation/security.js.map +1 -0
- package/dist/utils/validation/wordpress.d.ts +31 -0
- package/dist/utils/validation/wordpress.d.ts.map +1 -0
- package/dist/utils/validation/wordpress.js +146 -0
- package/dist/utils/validation/wordpress.js.map +1 -0
- package/dist/utils/validation.d.ts +13 -82
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +25 -343
- package/dist/utils/validation.js.map +1 -1
- package/docs/BADGE_UPDATES.md +132 -0
- package/docs/CI_CD_IMPROVEMENTS.md +191 -0
- package/docs/INCREMENTAL_COVERAGE.md +183 -0
- package/docs/api/README.md +3 -1
- package/docs/api/openapi.json +5 -1
- package/docs/api/summary.json +1 -1
- package/docs/api/tools/wp_create_post.md +12 -14
- package/docs/examples/claude-desktop-config.md +1 -1
- package/docs/examples/docker-production.md +100 -93
- package/docs/examples/multi-site-setup.md +5 -4
- package/docs/examples/single-site-setup.md +3 -4
- package/docs/examples/use-case-workflows.md +4 -5
- package/docs/integrations/claude-desktop.md +31 -31
- package/docs/integrations/cline.md +4 -4
- package/docs/integrations/vs-code.md +9 -8
- package/docs/user-guides/SMITHERY_SETUP.md +10 -10
- package/package.json +44 -25
- package/src/cache/CacheInvalidation.ts +12 -5
- package/src/cache/CacheManager.ts +18 -15
- package/src/cache/HttpCacheWrapper.ts +30 -59
- package/src/cache/__tests__/HttpCacheWrapper.test.ts +6 -5
- package/src/cache/index.ts +3 -14
- package/src/client/CachedWordPressClient.ts +32 -30
- package/src/client/MockWordPressClient.ts +4 -2
- package/src/client/api.ts +186 -64
- package/src/client/auth.ts +15 -40
- package/src/client/managers/AuthenticationManager.ts +337 -77
- package/src/client/managers/BaseManager.ts +18 -30
- package/src/client/managers/RequestManager.ts +39 -44
- package/src/config/Config.ts +308 -0
- package/src/config/ConfigurationSchema.ts +23 -2
- package/src/config/ServerConfiguration.ts +51 -47
- package/src/docs/DocumentationGenerator.ts +50 -39
- package/src/docs/MarkdownFormatter.ts +19 -29
- package/src/dxt-entry.cjs +26 -16
- package/src/dxt-entry.ts +17 -27
- package/src/index.ts +42 -28
- package/src/performance/MetricsCollector.ts +108 -86
- package/src/performance/PerformanceAnalytics.ts +69 -164
- package/src/performance/PerformanceMonitor.ts +32 -47
- package/src/performance/index.ts +2 -10
- package/src/security/AISecurityScanner.ts +22 -12
- package/src/security/AutomatedRemediation.ts +49 -18
- package/src/security/InputValidator.ts +9 -6
- package/src/security/SecurityCIPipeline.ts +53 -37
- package/src/security/SecurityConfig.ts +22 -22
- package/src/security/SecurityConfigManager.ts +23 -19
- package/src/security/SecurityMonitoring.ts +24 -21
- package/src/security/SecurityReviewer.ts +10 -7
- package/src/security/index.ts +64 -29
- package/src/server/ConnectionTester.ts +120 -31
- package/src/server/ToolRegistry.ts +31 -21
- package/src/tools/BaseToolManager.ts +286 -33
- package/src/tools/auth.ts +20 -8
- package/src/tools/cache.ts +5 -15
- package/src/tools/comments.ts +34 -48
- package/src/tools/media.ts +41 -53
- package/src/tools/pages.ts +32 -54
- package/src/tools/performance.ts +141 -176
- package/src/tools/posts/PostHandlers.ts +474 -0
- package/src/tools/posts/PostToolDefinitions.ts +250 -0
- package/src/tools/posts/index.ts +192 -0
- package/src/tools/posts.ts +24 -780
- package/src/tools/site.ts +34 -19
- package/src/tools/taxonomies.ts +41 -57
- package/src/tools/users.ts +28 -16
- package/src/types/client.ts +114 -138
- package/src/types/enhanced.ts +318 -0
- package/src/types/index.ts +51 -30
- package/src/types/mcp.ts +20 -42
- package/src/types/requests.ts +378 -0
- package/src/types/tools.ts +608 -0
- package/src/types/wordpress.ts +56 -34
- package/src/utils/debug.ts +77 -59
- package/src/utils/enhancedError.ts +8 -8
- package/src/utils/error.ts +53 -31
- package/src/utils/logger.ts +351 -0
- package/src/utils/streaming.ts +86 -68
- package/src/utils/toolWrapper.ts +10 -12
- package/src/utils/validation/core.ts +108 -0
- package/src/utils/validation/index.ts +36 -0
- package/src/utils/validation/network.ts +132 -0
- package/src/utils/validation/rateLimit.ts +54 -0
- package/src/utils/validation/security.ts +361 -0
- package/src/utils/validation/wordpress.ts +180 -0
- package/src/utils/validation.ts +47 -470
|
@@ -1,75 +1,164 @@
|
|
|
1
1
|
import { WordPressClient } from "../client/api.js";
|
|
2
2
|
import { getErrorMessage } from "../utils/error.js";
|
|
3
|
+
import { LoggerFactory } from "../utils/logger.js";
|
|
4
|
+
import { ConfigHelpers } from "../config/Config.js";
|
|
5
|
+
|
|
6
|
+
interface ErrorWithResponse {
|
|
7
|
+
response?: {
|
|
8
|
+
status?: number;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface ErrorWithCode {
|
|
13
|
+
code?: string;
|
|
14
|
+
}
|
|
3
15
|
|
|
4
16
|
/**
|
|
5
17
|
* Service for testing WordPress client connections
|
|
6
18
|
* Handles connection validation and health checks
|
|
7
19
|
*/
|
|
8
20
|
export class ConnectionTester {
|
|
21
|
+
private static logger = LoggerFactory.server().child({ component: "ConnectionTester" });
|
|
22
|
+
|
|
9
23
|
/**
|
|
10
|
-
* Test connections to all configured WordPress sites
|
|
24
|
+
* Test connections to all configured WordPress sites with timeout and concurrency control
|
|
11
25
|
*/
|
|
12
26
|
public static async testClientConnections(
|
|
13
27
|
wordpressClients: Map<string, WordPressClient>,
|
|
28
|
+
options: { timeout?: number; maxConcurrent?: number } = {},
|
|
14
29
|
): Promise<void> {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
30
|
+
const { timeout = 5000, maxConcurrent = 3 } = options;
|
|
31
|
+
|
|
32
|
+
this.logger.info("Testing connections to WordPress sites", {
|
|
33
|
+
siteCount: wordpressClients.size,
|
|
34
|
+
timeout,
|
|
35
|
+
maxConcurrent,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const entries = Array.from(wordpressClients.entries());
|
|
39
|
+
const results: Array<{ siteId: string; success: boolean; error?: string }> = [];
|
|
18
40
|
|
|
19
|
-
|
|
20
|
-
|
|
41
|
+
// Process sites in batches to control concurrency
|
|
42
|
+
for (let i = 0; i < entries.length; i += maxConcurrent) {
|
|
43
|
+
const batch = entries.slice(i, i + maxConcurrent);
|
|
44
|
+
|
|
45
|
+
const batchPromises = batch.map(async ([siteId, client]) => {
|
|
46
|
+
const startTime = Date.now();
|
|
21
47
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
`Authentication may have failed for site '${siteId}'. Please check credentials.`,
|
|
32
|
-
);
|
|
48
|
+
// Add timeout to ping operation (skip timeout in tests to avoid timer issues)
|
|
49
|
+
if (ConfigHelpers.isTest()) {
|
|
50
|
+
// In test environment, just run the ping without timeout to avoid Jest timer issues
|
|
51
|
+
await client.ping();
|
|
52
|
+
} else {
|
|
53
|
+
await Promise.race([
|
|
54
|
+
client.ping(),
|
|
55
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Connection timeout")), timeout)),
|
|
56
|
+
]);
|
|
33
57
|
}
|
|
58
|
+
|
|
59
|
+
const duration = Date.now() - startTime;
|
|
60
|
+
this.logger.info("Connection successful", { siteId, duration: `${duration}ms` });
|
|
61
|
+
results.push({ siteId, success: true });
|
|
62
|
+
} catch (error) {
|
|
63
|
+
const duration = Date.now() - startTime;
|
|
64
|
+
const errorMessage = getErrorMessage(error);
|
|
65
|
+
|
|
66
|
+
this.logger.warn("Connection failed", {
|
|
67
|
+
siteId,
|
|
68
|
+
error: errorMessage,
|
|
69
|
+
duration: `${duration}ms`,
|
|
70
|
+
isAuthError: ConnectionTester.isAuthenticationError(error),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
results.push({ siteId, success: false, error: errorMessage });
|
|
34
74
|
}
|
|
35
|
-
}
|
|
36
|
-
);
|
|
75
|
+
});
|
|
37
76
|
|
|
38
|
-
|
|
39
|
-
|
|
77
|
+
await Promise.allSettled(batchPromises);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Log summary
|
|
81
|
+
const successful = results.filter((r) => r.success).length;
|
|
82
|
+
const failed = results.length - successful;
|
|
83
|
+
|
|
84
|
+
this.logger.info("Connection tests complete", {
|
|
85
|
+
total: results.length,
|
|
86
|
+
successful,
|
|
87
|
+
failed,
|
|
88
|
+
successRate: `${((successful / results.length) * 100).toFixed(1)}%`,
|
|
89
|
+
});
|
|
40
90
|
}
|
|
41
91
|
|
|
42
92
|
/**
|
|
43
93
|
* Check if error is authentication-related
|
|
44
94
|
*/
|
|
45
|
-
private static isAuthenticationError(error:
|
|
46
|
-
|
|
47
|
-
|
|
95
|
+
private static isAuthenticationError(error: unknown): boolean {
|
|
96
|
+
// Check for HTTP response status
|
|
97
|
+
if (error && typeof error === "object" && "response" in error) {
|
|
98
|
+
const response = (error as ErrorWithResponse).response;
|
|
99
|
+
if (response?.status && [401, 403].includes(response.status)) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
48
102
|
}
|
|
49
|
-
|
|
103
|
+
const errorMessage = getErrorMessage(error);
|
|
104
|
+
return (
|
|
105
|
+
errorMessage.includes("401") ||
|
|
106
|
+
errorMessage.includes("403") ||
|
|
107
|
+
errorMessage.includes("Unauthorized") ||
|
|
108
|
+
errorMessage.includes("Forbidden") ||
|
|
109
|
+
(error as ErrorWithCode)?.code === "WORDPRESS_AUTH_ERROR"
|
|
110
|
+
);
|
|
50
111
|
}
|
|
51
112
|
|
|
52
113
|
/**
|
|
53
|
-
* Perform health check for a specific client
|
|
114
|
+
* Perform health check for a specific client with timeout
|
|
54
115
|
*/
|
|
55
|
-
public static async healthCheck(client: WordPressClient): Promise<boolean> {
|
|
116
|
+
public static async healthCheck(client: WordPressClient, siteId?: string, timeout: number = 3000): Promise<boolean> {
|
|
56
117
|
try {
|
|
57
|
-
await
|
|
118
|
+
await Promise.race([
|
|
119
|
+
client.ping(),
|
|
120
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Health check timeout")), timeout)),
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
this.logger.debug("Health check passed", { siteId });
|
|
58
124
|
return true;
|
|
59
125
|
} catch (error) {
|
|
60
|
-
|
|
126
|
+
this.logger.warn("Health check failed", {
|
|
127
|
+
siteId,
|
|
128
|
+
error: getErrorMessage(error),
|
|
129
|
+
});
|
|
61
130
|
return false;
|
|
62
131
|
}
|
|
63
132
|
}
|
|
64
133
|
|
|
65
134
|
/**
|
|
66
|
-
*
|
|
135
|
+
* Quick connectivity test without full authentication
|
|
67
136
|
*/
|
|
68
|
-
public static async
|
|
137
|
+
public static async quickConnectivityTest(
|
|
69
138
|
wordpressClients: Map<string, WordPressClient>,
|
|
70
139
|
): Promise<Map<string, boolean>> {
|
|
71
140
|
const results = new Map<string, boolean>();
|
|
72
141
|
|
|
142
|
+
const promises = Array.from(wordpressClients.entries()).map(async ([siteId, client]) => {
|
|
143
|
+
try {
|
|
144
|
+
// Just test basic connectivity, not full auth
|
|
145
|
+
const isHealthy = await this.healthCheck(client, siteId, 1000);
|
|
146
|
+
results.set(siteId, isHealthy);
|
|
147
|
+
} catch (_error) {
|
|
148
|
+
results.set(siteId, false);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await Promise.allSettled(promises);
|
|
153
|
+
return results;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Perform health checks for all clients
|
|
158
|
+
*/
|
|
159
|
+
public static async healthCheckAll(wordpressClients: Map<string, WordPressClient>): Promise<Map<string, boolean>> {
|
|
160
|
+
const results = new Map<string, boolean>();
|
|
161
|
+
|
|
73
162
|
for (const [siteId, client] of wordpressClients.entries()) {
|
|
74
163
|
const isHealthy = await ConnectionTester.healthCheck(client);
|
|
75
164
|
results.set(siteId, isHealthy);
|
|
@@ -2,6 +2,7 @@ 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
4
|
import { EnhancedError, ErrorHandlers } from "../utils/enhancedError.js";
|
|
5
|
+
import { config } from "../config/Config.js";
|
|
5
6
|
import * as Tools from "../tools/index.js";
|
|
6
7
|
import { z } from "zod";
|
|
7
8
|
|
|
@@ -13,11 +14,11 @@ export interface ToolDefinition {
|
|
|
13
14
|
description?: string;
|
|
14
15
|
parameters?: Array<{
|
|
15
16
|
name: string;
|
|
16
|
-
type
|
|
17
|
+
type?: string;
|
|
17
18
|
description?: string;
|
|
18
19
|
required?: boolean;
|
|
19
20
|
}>;
|
|
20
|
-
handler: (client: WordPressClient, args:
|
|
21
|
+
handler: (client: WordPressClient, args: Record<string, unknown>) => Promise<unknown>;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -39,19 +40,19 @@ export class ToolRegistry {
|
|
|
39
40
|
public registerAllTools(): void {
|
|
40
41
|
// Register all tools from the tools directory
|
|
41
42
|
Object.values(Tools).forEach((ToolClass) => {
|
|
42
|
-
let toolInstance:
|
|
43
|
+
let toolInstance: { getTools(): unknown[] };
|
|
43
44
|
|
|
44
45
|
// Cache and Performance tools need the clients map
|
|
45
46
|
if (ToolClass.name === "CacheTools" || ToolClass.name === "PerformanceTools") {
|
|
46
47
|
toolInstance = new ToolClass(this.wordpressClients);
|
|
47
48
|
} else {
|
|
48
|
-
toolInstance = new (ToolClass as new () =>
|
|
49
|
+
toolInstance = new (ToolClass as new () => { getTools(): unknown[] })();
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
const tools = toolInstance.getTools();
|
|
52
53
|
|
|
53
|
-
tools.forEach((tool:
|
|
54
|
-
this.registerTool(tool);
|
|
54
|
+
tools.forEach((tool: unknown) => {
|
|
55
|
+
this.registerTool(tool as ToolDefinition);
|
|
55
56
|
});
|
|
56
57
|
});
|
|
57
58
|
}
|
|
@@ -74,8 +75,13 @@ export class ToolRegistry {
|
|
|
74
75
|
const parameterSchema = this.buildParameterSchema(tool, baseSchema);
|
|
75
76
|
|
|
76
77
|
// Make site parameter required if multiple sites are configured
|
|
77
|
-
if (
|
|
78
|
-
|
|
78
|
+
if (
|
|
79
|
+
this.wordpressClients.size > 1 &&
|
|
80
|
+
parameterSchema.site &&
|
|
81
|
+
typeof parameterSchema.site === "object" &&
|
|
82
|
+
"describe" in parameterSchema.site
|
|
83
|
+
) {
|
|
84
|
+
parameterSchema.site = (parameterSchema.site as z.ZodString).describe(
|
|
79
85
|
"The ID of the WordPress site to target (from mcp-wordpress.config.json). Required when multiple sites are configured.",
|
|
80
86
|
);
|
|
81
87
|
}
|
|
@@ -84,7 +90,7 @@ export class ToolRegistry {
|
|
|
84
90
|
tool.name,
|
|
85
91
|
tool.description || `WordPress tool: ${tool.name}`,
|
|
86
92
|
parameterSchema,
|
|
87
|
-
async (args:
|
|
93
|
+
async (args: Record<string, unknown>) => {
|
|
88
94
|
try {
|
|
89
95
|
let siteId = args.site;
|
|
90
96
|
|
|
@@ -108,11 +114,11 @@ export class ToolRegistry {
|
|
|
108
114
|
siteId = this.selectBestSite(tool.name, args);
|
|
109
115
|
}
|
|
110
116
|
|
|
111
|
-
const client = this.wordpressClients.get(siteId);
|
|
117
|
+
const client = this.wordpressClients.get(siteId as string);
|
|
112
118
|
|
|
113
119
|
if (!client) {
|
|
114
120
|
const availableSites = Array.from(this.wordpressClients.keys());
|
|
115
|
-
const error = ErrorHandlers.siteNotFound(siteId, availableSites);
|
|
121
|
+
const error = ErrorHandlers.siteNotFound(siteId as string, availableSites);
|
|
116
122
|
return {
|
|
117
123
|
content: [
|
|
118
124
|
{
|
|
@@ -178,14 +184,17 @@ export class ToolRegistry {
|
|
|
178
184
|
/**
|
|
179
185
|
* Build Zod parameter schema from tool definition
|
|
180
186
|
*/
|
|
181
|
-
private buildParameterSchema(tool: ToolDefinition, baseSchema:
|
|
187
|
+
private buildParameterSchema(tool: ToolDefinition, baseSchema: Record<string, unknown>): Record<string, unknown> {
|
|
182
188
|
return (
|
|
183
189
|
tool.parameters?.reduce(
|
|
184
|
-
(
|
|
190
|
+
(
|
|
191
|
+
schema: Record<string, unknown>,
|
|
192
|
+
param: { name: string; type?: string; required?: boolean; [key: string]: unknown },
|
|
193
|
+
) => {
|
|
185
194
|
let zodType = this.getZodTypeForParameter(param);
|
|
186
195
|
|
|
187
196
|
if (param.description) {
|
|
188
|
-
zodType = zodType.describe(param.description);
|
|
197
|
+
zodType = zodType.describe(param.description as string);
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
if (!param.required) {
|
|
@@ -203,7 +212,7 @@ export class ToolRegistry {
|
|
|
203
212
|
/**
|
|
204
213
|
* Get appropriate Zod type for parameter definition
|
|
205
214
|
*/
|
|
206
|
-
private getZodTypeForParameter(param:
|
|
215
|
+
private getZodTypeForParameter(param: { type?: string; required?: boolean; [key: string]: unknown }): z.ZodType {
|
|
207
216
|
switch (param.type) {
|
|
208
217
|
case "string":
|
|
209
218
|
return z.string();
|
|
@@ -214,7 +223,7 @@ export class ToolRegistry {
|
|
|
214
223
|
case "array":
|
|
215
224
|
return z.array(z.string());
|
|
216
225
|
case "object":
|
|
217
|
-
return z.record(z.
|
|
226
|
+
return z.record(z.unknown());
|
|
218
227
|
default:
|
|
219
228
|
return z.string();
|
|
220
229
|
}
|
|
@@ -223,7 +232,7 @@ export class ToolRegistry {
|
|
|
223
232
|
/**
|
|
224
233
|
* Intelligent site selection based on context
|
|
225
234
|
*/
|
|
226
|
-
private selectBestSite(toolName: string, args:
|
|
235
|
+
private selectBestSite(toolName: string, args: Record<string, unknown>): string {
|
|
227
236
|
const availableSites = Array.from(this.wordpressClients.keys());
|
|
228
237
|
|
|
229
238
|
// Single site scenario - use it directly
|
|
@@ -249,7 +258,7 @@ export class ToolRegistry {
|
|
|
249
258
|
}
|
|
250
259
|
|
|
251
260
|
// 3. For development/test operations, prefer dev sites
|
|
252
|
-
if (toolName.includes("test") ||
|
|
261
|
+
if (toolName.includes("test") || config().app.isDevelopment) {
|
|
253
262
|
const devSites = availableSites.filter((site) =>
|
|
254
263
|
["dev", "test", "staging", "local"].includes(site.toLowerCase()),
|
|
255
264
|
);
|
|
@@ -269,10 +278,11 @@ export class ToolRegistry {
|
|
|
269
278
|
/**
|
|
270
279
|
* Check if error is authentication-related
|
|
271
280
|
*/
|
|
272
|
-
private isAuthenticationError(error:
|
|
273
|
-
|
|
281
|
+
private isAuthenticationError(error: unknown): boolean {
|
|
282
|
+
const errorObj = error as { response?: { status?: number }; code?: string };
|
|
283
|
+
if (errorObj?.response?.status && [401, 403].includes(errorObj.response.status)) {
|
|
274
284
|
return true;
|
|
275
285
|
}
|
|
276
|
-
return
|
|
286
|
+
return errorObj?.code === "WORDPRESS_AUTH_ERROR";
|
|
277
287
|
}
|
|
278
288
|
}
|