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.
- package/README.md +332 -61
- package/dist/cache/CacheInvalidation.d.ts.map +1 -1
- package/dist/cache/CacheInvalidation.js +4 -4
- package/dist/cache/CacheInvalidation.js.map +1 -1
- package/dist/client/MockWordPressClient.d.ts +55 -0
- package/dist/client/MockWordPressClient.d.ts.map +1 -0
- package/dist/client/MockWordPressClient.js +369 -0
- package/dist/client/MockWordPressClient.js.map +1 -0
- package/dist/client/api.d.ts +1 -0
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +26 -60
- package/dist/client/api.js.map +1 -1
- package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
- package/dist/client/managers/AuthenticationManager.js +4 -3
- package/dist/client/managers/AuthenticationManager.js.map +1 -1
- package/dist/config/ConfigurationSchema.d.ts +3 -3
- package/dist/config/ConfigurationSchema.d.ts.map +1 -1
- package/dist/config/ConfigurationSchema.js +7 -24
- package/dist/config/ConfigurationSchema.js.map +1 -1
- package/dist/config/ServerConfiguration.d.ts +8 -0
- package/dist/config/ServerConfiguration.d.ts.map +1 -1
- package/dist/config/ServerConfiguration.js +80 -31
- package/dist/config/ServerConfiguration.js.map +1 -1
- package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
- package/dist/docs/DocumentationGenerator.js +5 -7
- package/dist/docs/DocumentationGenerator.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -29
- package/dist/index.js.map +1 -1
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +3 -11
- package/dist/security/InputValidator.js.map +1 -1
- package/dist/server/ToolRegistry.d.ts +4 -0
- package/dist/server/ToolRegistry.d.ts.map +1 -1
- package/dist/server/ToolRegistry.js +71 -8
- package/dist/server/ToolRegistry.js.map +1 -1
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +8 -3
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +287 -20
- package/dist/tools/posts.js.map +1 -1
- package/dist/tools/site.d.ts.map +1 -1
- package/dist/tools/site.js +47 -9
- package/dist/tools/site.js.map +1 -1
- package/dist/tools/users.d.ts.map +1 -1
- package/dist/tools/users.js +113 -10
- package/dist/tools/users.js.map +1 -1
- package/dist/utils/enhancedError.d.ts +61 -0
- package/dist/utils/enhancedError.d.ts.map +1 -0
- package/dist/utils/enhancedError.js +221 -0
- package/dist/utils/enhancedError.js.map +1 -0
- package/dist/utils/streaming.d.ts +104 -0
- package/dist/utils/streaming.d.ts.map +1 -0
- package/dist/utils/streaming.js +312 -0
- package/dist/utils/streaming.js.map +1 -0
- package/dist/utils/validation.d.ts +19 -3
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +174 -24
- package/dist/utils/validation.js.map +1 -1
- package/docs/ARCHITECTURE.md +850 -0
- package/docs/CACHING.md +20 -17
- package/docs/CONFIGURATION.md +660 -0
- package/docs/DOCKER.md +61 -60
- package/docs/EVALUATION.md +397 -0
- package/docs/INSTALLATION.md +423 -0
- package/docs/PERFORMANCE_MONITORING.md +17 -15
- package/docs/SECURITY.md +621 -0
- package/docs/SECURITY_TESTING.md +22 -26
- package/docs/TEST_SITE_SETUP.md +136 -0
- package/docs/TROUBLESHOOTING.md +578 -0
- package/docs/api/README.md +76 -91
- package/docs/api/categories/auth.md +0 -2
- package/docs/api/categories/cache.md +0 -2
- package/docs/api/categories/comment.md +0 -2
- package/docs/api/categories/media.md +0 -2
- package/docs/api/categories/page.md +0 -2
- package/docs/api/categories/performance.md +0 -2
- package/docs/api/categories/post.md +0 -2
- package/docs/api/categories/site.md +0 -2
- package/docs/api/categories/taxonomy.md +0 -2
- package/docs/api/categories/user.md +0 -2
- package/docs/api/summary.json +1 -1
- package/docs/api/tools/wp_approve_comment.md +11 -3
- package/docs/api/tools/wp_cache_clear.md +14 -5
- package/docs/api/tools/wp_cache_info.md +14 -5
- package/docs/api/tools/wp_cache_stats.md +14 -5
- package/docs/api/tools/wp_cache_warm.md +14 -5
- package/docs/api/tools/wp_create_application_password.md +11 -3
- package/docs/api/tools/wp_create_category.md +11 -3
- package/docs/api/tools/wp_create_comment.md +14 -5
- package/docs/api/tools/wp_create_page.md +13 -5
- package/docs/api/tools/wp_create_post.md +14 -7
- package/docs/api/tools/wp_create_tag.md +11 -3
- package/docs/api/tools/wp_create_user.md +13 -5
- package/docs/api/tools/wp_delete_application_password.md +11 -3
- package/docs/api/tools/wp_delete_category.md +11 -3
- package/docs/api/tools/wp_delete_comment.md +11 -3
- package/docs/api/tools/wp_delete_media.md +10 -3
- package/docs/api/tools/wp_delete_page.md +10 -3
- package/docs/api/tools/wp_delete_post.md +11 -5
- package/docs/api/tools/wp_delete_tag.md +11 -3
- package/docs/api/tools/wp_delete_user.md +10 -3
- package/docs/api/tools/wp_get_application_passwords.md +11 -3
- package/docs/api/tools/wp_get_auth_status.md +11 -3
- package/docs/api/tools/wp_get_category.md +11 -3
- package/docs/api/tools/wp_get_comment.md +11 -3
- package/docs/api/tools/wp_get_current_user.md +11 -3
- package/docs/api/tools/wp_get_media.md +11 -3
- package/docs/api/tools/wp_get_page.md +11 -3
- package/docs/api/tools/wp_get_page_revisions.md +11 -3
- package/docs/api/tools/wp_get_post.md +12 -5
- package/docs/api/tools/wp_get_post_revisions.md +11 -3
- package/docs/api/tools/wp_get_site_settings.md +10 -3
- package/docs/api/tools/wp_get_tag.md +11 -3
- package/docs/api/tools/wp_get_user.md +11 -3
- package/docs/api/tools/wp_list_categories.md +11 -3
- package/docs/api/tools/wp_list_comments.md +11 -3
- package/docs/api/tools/wp_list_media.md +14 -5
- package/docs/api/tools/wp_list_pages.md +14 -5
- package/docs/api/tools/wp_list_posts.md +15 -7
- package/docs/api/tools/wp_list_tags.md +11 -3
- package/docs/api/tools/wp_list_users.md +11 -3
- package/docs/api/tools/wp_performance_alerts.md +17 -7
- package/docs/api/tools/wp_performance_benchmark.md +17 -7
- package/docs/api/tools/wp_performance_export.md +17 -7
- package/docs/api/tools/wp_performance_history.md +17 -7
- package/docs/api/tools/wp_performance_optimize.md +17 -7
- package/docs/api/tools/wp_performance_stats.md +17 -7
- package/docs/api/tools/wp_search_site.md +11 -3
- package/docs/api/tools/wp_spam_comment.md +11 -3
- package/docs/api/tools/wp_switch_auth_method.md +14 -5
- package/docs/api/tools/wp_test_auth.md +11 -3
- package/docs/api/tools/wp_update_category.md +11 -3
- package/docs/api/tools/wp_update_comment.md +14 -5
- package/docs/api/tools/wp_update_media.md +14 -5
- package/docs/api/tools/wp_update_page.md +13 -5
- package/docs/api/tools/wp_update_post.md +14 -7
- package/docs/api/tools/wp_update_site_settings.md +14 -5
- package/docs/api/tools/wp_update_tag.md +11 -3
- package/docs/api/tools/wp_update_user.md +13 -5
- package/docs/api/tools/wp_upload_media.md +13 -5
- package/docs/api/types/WordPressPost.md +2 -0
- package/docs/code-improvements.md +40 -0
- package/docs/contract-testing.md +1 -1
- package/docs/developer/API_REFERENCE.md +19 -59
- package/docs/developer/ARCHITECTURE.md +8 -11
- package/docs/developer/BUILD_SYSTEM.md +2 -2
- package/docs/developer/CONTRIBUTING.md +3 -5
- package/docs/developer/GITHUB_ACTIONS_SETUP.md +2 -2
- package/docs/developer/MIGRATION_GUIDE.md +5 -6
- package/docs/developer/README.md +2 -1
- package/docs/developer/REFACTORING.md +9 -15
- package/docs/developer/RELEASE_PROCESS.md +4 -3
- package/docs/developer/TESTING.md +2 -2
- package/docs/examples/claude-desktop-config.md +8 -0
- package/docs/integrations/claude-desktop.md +426 -0
- package/docs/integrations/cline.md +537 -0
- package/docs/integrations/vs-code.md +515 -0
- package/docs/releases/COMMUNITY_ANNOUNCEMENT_v1.1.2.md +30 -23
- package/docs/releases/RELEASE_NOTES_v1.1.2.md +7 -6
- package/docs/testing-configurations.md +11 -0
- package/docs/user-guides/DOCKER_NPM_DTX_SETUP.md +3 -2
- package/docs/user-guides/DOCKER_SETUP.md +3 -2
- package/docs/user-guides/DTX_SETUP.md +6 -5
- package/docs/user-guides/DXT_INSTALLATION.md +4 -4
- package/docs/user-guides/NPM_SETUP.md +4 -2
- package/docs/user-guides/NPX_SETUP.md +4 -2
- package/docs/user-guides/SMITHERY_SETUP.md +402 -0
- package/docs/wordpress-rest-api-authentication-troubleshooting.md +45 -42
- package/package.json +12 -2
- package/src/cache/CacheInvalidation.ts +7 -18
- package/src/client/MockWordPressClient.ts +398 -0
- package/src/client/api.ts +77 -237
- package/src/client/managers/AuthenticationManager.ts +19 -56
- package/src/config/ConfigurationSchema.ts +14 -45
- package/src/config/ServerConfiguration.ts +98 -71
- package/src/docs/DocumentationGenerator.ts +39 -123
- package/src/dxt-entry.cjs +4 -1
- package/src/index.ts +35 -54
- package/src/security/InputValidator.ts +15 -57
- package/src/server/ToolRegistry.ts +88 -17
- package/src/tools/auth.ts +15 -22
- package/src/tools/posts.ts +347 -64
- package/src/tools/site.ts +69 -46
- package/src/tools/users.ts +142 -44
- package/src/utils/enhancedError.ts +248 -0
- package/src/utils/streaming.ts +428 -0
- package/src/utils/validation.ts +253 -92
- package/dist/mcp-wordpress-1.5.2.tgz +0 -0
|
@@ -16,8 +16,7 @@ export class AuthenticationManager extends BaseManager {
|
|
|
16
16
|
* Get authentication from environment variables
|
|
17
17
|
*/
|
|
18
18
|
static getAuthFromEnv(): AuthConfig {
|
|
19
|
-
const method: AuthMethod =
|
|
20
|
-
(process.env.WORDPRESS_AUTH_METHOD as AuthMethod) || "app-password";
|
|
19
|
+
const method: AuthMethod = (process.env.WORDPRESS_AUTH_METHOD as AuthMethod) || "app-password";
|
|
21
20
|
|
|
22
21
|
switch (method) {
|
|
23
22
|
case "app-password":
|
|
@@ -31,10 +30,7 @@ export class AuthenticationManager extends BaseManager {
|
|
|
31
30
|
return {
|
|
32
31
|
method: "jwt",
|
|
33
32
|
username: process.env.WORDPRESS_USERNAME || "",
|
|
34
|
-
password:
|
|
35
|
-
process.env.WORDPRESS_JWT_PASSWORD ||
|
|
36
|
-
process.env.WORDPRESS_PASSWORD ||
|
|
37
|
-
"",
|
|
33
|
+
password: process.env.WORDPRESS_JWT_PASSWORD || process.env.WORDPRESS_PASSWORD || "",
|
|
38
34
|
secret: process.env.WORDPRESS_JWT_SECRET || "",
|
|
39
35
|
};
|
|
40
36
|
|
|
@@ -52,10 +48,7 @@ export class AuthenticationManager extends BaseManager {
|
|
|
52
48
|
};
|
|
53
49
|
|
|
54
50
|
default:
|
|
55
|
-
throw new AuthenticationError(
|
|
56
|
-
`Unsupported authentication method: ${method}`,
|
|
57
|
-
method,
|
|
58
|
-
);
|
|
51
|
+
throw new AuthenticationError(`Unsupported authentication method: ${method}`, method);
|
|
59
52
|
}
|
|
60
53
|
}
|
|
61
54
|
|
|
@@ -65,18 +58,17 @@ export class AuthenticationManager extends BaseManager {
|
|
|
65
58
|
async getAuthHeaders(): Promise<Record<string, string>> {
|
|
66
59
|
const auth = this.config.auth;
|
|
67
60
|
|
|
61
|
+
if (!auth) {
|
|
62
|
+
throw new AuthenticationError("Authentication configuration is required", "app-password");
|
|
63
|
+
}
|
|
64
|
+
|
|
68
65
|
switch (auth.method) {
|
|
69
66
|
case "app-password":
|
|
70
67
|
if (!auth.username || !auth.appPassword) {
|
|
71
|
-
throw new AuthenticationError(
|
|
72
|
-
"Username and app password are required",
|
|
73
|
-
auth.method,
|
|
74
|
-
);
|
|
68
|
+
throw new AuthenticationError("Username and app password are required", auth.method);
|
|
75
69
|
}
|
|
76
70
|
|
|
77
|
-
const credentials = Buffer.from(
|
|
78
|
-
`${auth.username}:${auth.appPassword}`,
|
|
79
|
-
).toString("base64");
|
|
71
|
+
const credentials = Buffer.from(`${auth.username}:${auth.appPassword}`).toString("base64");
|
|
80
72
|
return { Authorization: `Basic ${credentials}` };
|
|
81
73
|
|
|
82
74
|
case "jwt":
|
|
@@ -87,15 +79,10 @@ export class AuthenticationManager extends BaseManager {
|
|
|
87
79
|
|
|
88
80
|
case "basic":
|
|
89
81
|
if (!auth.username || !auth.password) {
|
|
90
|
-
throw new AuthenticationError(
|
|
91
|
-
"Username and password are required",
|
|
92
|
-
auth.method,
|
|
93
|
-
);
|
|
82
|
+
throw new AuthenticationError("Username and password are required", auth.method);
|
|
94
83
|
}
|
|
95
84
|
|
|
96
|
-
const basicCredentials = Buffer.from(
|
|
97
|
-
`${auth.username}:${auth.password}`,
|
|
98
|
-
).toString("base64");
|
|
85
|
+
const basicCredentials = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
|
|
99
86
|
return { Authorization: `Basic ${basicCredentials}` };
|
|
100
87
|
|
|
101
88
|
case "api-key":
|
|
@@ -105,10 +92,7 @@ export class AuthenticationManager extends BaseManager {
|
|
|
105
92
|
return { "X-API-Key": auth.apiKey };
|
|
106
93
|
|
|
107
94
|
default:
|
|
108
|
-
throw new AuthenticationError(
|
|
109
|
-
`Unsupported authentication method: ${auth.method}`,
|
|
110
|
-
auth.method,
|
|
111
|
-
);
|
|
95
|
+
throw new AuthenticationError(`Unsupported authentication method: ${auth.method}`, auth.method);
|
|
112
96
|
}
|
|
113
97
|
}
|
|
114
98
|
|
|
@@ -119,19 +103,13 @@ export class AuthenticationManager extends BaseManager {
|
|
|
119
103
|
const auth = this.config.auth;
|
|
120
104
|
|
|
121
105
|
if (auth.method !== "jwt" || !auth.username || !auth.password) {
|
|
122
|
-
throw new AuthenticationError(
|
|
123
|
-
"JWT authentication requires username and password",
|
|
124
|
-
"jwt",
|
|
125
|
-
);
|
|
106
|
+
throw new AuthenticationError("JWT authentication requires username and password", "jwt");
|
|
126
107
|
}
|
|
127
108
|
|
|
128
109
|
try {
|
|
129
110
|
// This would need the RequestManager instance to make the request
|
|
130
111
|
// For now, we'll throw an error indicating this needs to be implemented
|
|
131
|
-
throw new AuthenticationError(
|
|
132
|
-
"JWT authentication requires RequestManager integration",
|
|
133
|
-
"jwt",
|
|
134
|
-
);
|
|
112
|
+
throw new AuthenticationError("JWT authentication requires RequestManager integration", "jwt");
|
|
135
113
|
} catch (error) {
|
|
136
114
|
this.handleError(error, "JWT authentication");
|
|
137
115
|
}
|
|
@@ -180,10 +158,7 @@ export class AuthenticationManager extends BaseManager {
|
|
|
180
158
|
const auth = this.config.auth;
|
|
181
159
|
|
|
182
160
|
if (!auth.method) {
|
|
183
|
-
throw new AuthenticationError(
|
|
184
|
-
"Authentication method is required",
|
|
185
|
-
"app-password",
|
|
186
|
-
);
|
|
161
|
+
throw new AuthenticationError("Authentication method is required", "app-password");
|
|
187
162
|
}
|
|
188
163
|
|
|
189
164
|
switch (auth.method) {
|
|
@@ -198,36 +173,24 @@ export class AuthenticationManager extends BaseManager {
|
|
|
198
173
|
|
|
199
174
|
case "jwt":
|
|
200
175
|
if (!auth.username || !auth.password || !auth.secret) {
|
|
201
|
-
throw new AuthenticationError(
|
|
202
|
-
"JWT authentication requires username, password, and secret",
|
|
203
|
-
"jwt",
|
|
204
|
-
);
|
|
176
|
+
throw new AuthenticationError("JWT authentication requires username, password, and secret", "jwt");
|
|
205
177
|
}
|
|
206
178
|
break;
|
|
207
179
|
|
|
208
180
|
case "basic":
|
|
209
181
|
if (!auth.username || !auth.password) {
|
|
210
|
-
throw new AuthenticationError(
|
|
211
|
-
"Basic authentication requires username and password",
|
|
212
|
-
"basic",
|
|
213
|
-
);
|
|
182
|
+
throw new AuthenticationError("Basic authentication requires username and password", "basic");
|
|
214
183
|
}
|
|
215
184
|
break;
|
|
216
185
|
|
|
217
186
|
case "api-key":
|
|
218
187
|
if (!auth.apiKey) {
|
|
219
|
-
throw new AuthenticationError(
|
|
220
|
-
"API key authentication requires apiKey",
|
|
221
|
-
"api-key",
|
|
222
|
-
);
|
|
188
|
+
throw new AuthenticationError("API key authentication requires apiKey", "api-key");
|
|
223
189
|
}
|
|
224
190
|
break;
|
|
225
191
|
|
|
226
192
|
default:
|
|
227
|
-
throw new AuthenticationError(
|
|
228
|
-
`Unsupported authentication method: ${auth.method}`,
|
|
229
|
-
auth.method,
|
|
230
|
-
);
|
|
193
|
+
throw new AuthenticationError(`Unsupported authentication method: ${auth.method}`, auth.method);
|
|
231
194
|
}
|
|
232
195
|
}
|
|
233
196
|
}
|
|
@@ -3,13 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
/**
|
|
4
4
|
* Zod schema for WordPress authentication methods
|
|
5
5
|
*/
|
|
6
|
-
const AuthMethodSchema = z.enum([
|
|
7
|
-
"app-password",
|
|
8
|
-
"jwt",
|
|
9
|
-
"basic",
|
|
10
|
-
"api-key",
|
|
11
|
-
"cookie",
|
|
12
|
-
] as const);
|
|
6
|
+
const AuthMethodSchema = z.enum(["app-password", "jwt", "basic", "api-key", "cookie"] as const);
|
|
13
7
|
|
|
14
8
|
/**
|
|
15
9
|
* Zod schema for URL validation
|
|
@@ -51,14 +45,8 @@ const SiteSchema = z.object({
|
|
|
51
45
|
.string()
|
|
52
46
|
.min(1, "Site ID is required")
|
|
53
47
|
.max(50, "Site ID must be 50 characters or less")
|
|
54
|
-
.regex(
|
|
55
|
-
|
|
56
|
-
"Site ID can only contain letters, numbers, underscores, and hyphens",
|
|
57
|
-
),
|
|
58
|
-
name: z
|
|
59
|
-
.string()
|
|
60
|
-
.min(1, "Site name is required")
|
|
61
|
-
.max(100, "Site name must be 100 characters or less"),
|
|
48
|
+
.regex(/^[a-zA-Z0-9_-]+$/, "Site ID can only contain letters, numbers, underscores, and hyphens"),
|
|
49
|
+
name: z.string().min(1, "Site name is required").max(100, "Site name must be 100 characters or less"),
|
|
62
50
|
config: SiteConfigSchema,
|
|
63
51
|
});
|
|
64
52
|
|
|
@@ -96,7 +84,7 @@ const EnvironmentConfigSchema = z.object({
|
|
|
96
84
|
WORDPRESS_APP_PASSWORD: SiteConfigSchema.shape.WORDPRESS_APP_PASSWORD,
|
|
97
85
|
WORDPRESS_AUTH_METHOD: AuthMethodSchema.optional().default("app-password"),
|
|
98
86
|
// Optional environment variables
|
|
99
|
-
NODE_ENV: z.enum(["development", "production", "test"]).optional(),
|
|
87
|
+
NODE_ENV: z.enum(["development", "production", "test", "dxt", "ci"]).optional(),
|
|
100
88
|
DEBUG: z.string().optional(),
|
|
101
89
|
DISABLE_CACHE: z.string().optional(),
|
|
102
90
|
LOG_LEVEL: z.enum(["error", "warn", "info", "debug"]).optional(),
|
|
@@ -109,8 +97,7 @@ const McpConfigSchema = z
|
|
|
109
97
|
.object({
|
|
110
98
|
wordpressSiteUrl: UrlSchema.optional(),
|
|
111
99
|
wordpressUsername: SiteConfigSchema.shape.WORDPRESS_USERNAME.optional(),
|
|
112
|
-
wordpressAppPassword:
|
|
113
|
-
SiteConfigSchema.shape.WORDPRESS_APP_PASSWORD.optional(),
|
|
100
|
+
wordpressAppPassword: SiteConfigSchema.shape.WORDPRESS_APP_PASSWORD.optional(),
|
|
114
101
|
wordpressAuthMethod: AuthMethodSchema.optional(),
|
|
115
102
|
})
|
|
116
103
|
.optional();
|
|
@@ -136,12 +123,8 @@ export class ConfigurationValidator {
|
|
|
136
123
|
return MultiSiteConfigSchema.parse(config);
|
|
137
124
|
} catch (error) {
|
|
138
125
|
if (error instanceof z.ZodError) {
|
|
139
|
-
const messages = error.errors
|
|
140
|
-
|
|
141
|
-
.join("; ");
|
|
142
|
-
throw new Error(
|
|
143
|
-
`Multi-site configuration validation failed: ${messages}`,
|
|
144
|
-
);
|
|
126
|
+
const messages = error.errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
|
|
127
|
+
throw new Error(`Multi-site configuration validation failed: ${messages}`);
|
|
145
128
|
}
|
|
146
129
|
throw error;
|
|
147
130
|
}
|
|
@@ -150,19 +133,13 @@ export class ConfigurationValidator {
|
|
|
150
133
|
/**
|
|
151
134
|
* Validate environment configuration for single-site mode
|
|
152
135
|
*/
|
|
153
|
-
static validateEnvironmentConfig(
|
|
154
|
-
env: Record<string, string | undefined>,
|
|
155
|
-
): EnvironmentConfigType {
|
|
136
|
+
static validateEnvironmentConfig(env: Record<string, string | undefined>): EnvironmentConfigType {
|
|
156
137
|
try {
|
|
157
138
|
return EnvironmentConfigSchema.parse(env);
|
|
158
139
|
} catch (error) {
|
|
159
140
|
if (error instanceof z.ZodError) {
|
|
160
|
-
const messages = error.errors
|
|
161
|
-
|
|
162
|
-
.join("; ");
|
|
163
|
-
throw new Error(
|
|
164
|
-
`Environment configuration validation failed: ${messages}`,
|
|
165
|
-
);
|
|
141
|
+
const messages = error.errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
|
|
142
|
+
throw new Error(`Environment configuration validation failed: ${messages}`);
|
|
166
143
|
}
|
|
167
144
|
throw error;
|
|
168
145
|
}
|
|
@@ -176,9 +153,7 @@ export class ConfigurationValidator {
|
|
|
176
153
|
return McpConfigSchema.parse(config);
|
|
177
154
|
} catch (error) {
|
|
178
155
|
if (error instanceof z.ZodError) {
|
|
179
|
-
const messages = error.errors
|
|
180
|
-
.map((err) => `${err.path.join(".")}: ${err.message}`)
|
|
181
|
-
.join("; ");
|
|
156
|
+
const messages = error.errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
|
|
182
157
|
throw new Error(`MCP configuration validation failed: ${messages}`);
|
|
183
158
|
}
|
|
184
159
|
throw error;
|
|
@@ -193,9 +168,7 @@ export class ConfigurationValidator {
|
|
|
193
168
|
return SiteSchema.parse(config);
|
|
194
169
|
} catch (error) {
|
|
195
170
|
if (error instanceof z.ZodError) {
|
|
196
|
-
const messages = error.errors
|
|
197
|
-
.map((err) => `${err.path.join(".")}: ${err.message}`)
|
|
198
|
-
.join("; ");
|
|
171
|
+
const messages = error.errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
|
|
199
172
|
throw new Error(`Site configuration validation failed: ${messages}`);
|
|
200
173
|
}
|
|
201
174
|
throw error;
|
|
@@ -213,9 +186,7 @@ export class ConfigurationValidator {
|
|
|
213
186
|
/**
|
|
214
187
|
* Check if environment configuration is valid without throwing
|
|
215
188
|
*/
|
|
216
|
-
static isValidEnvironmentConfig(
|
|
217
|
-
env: Record<string, string | undefined>,
|
|
218
|
-
): boolean {
|
|
189
|
+
static isValidEnvironmentConfig(env: Record<string, string | undefined>): boolean {
|
|
219
190
|
const result = EnvironmentConfigSchema.safeParse(env);
|
|
220
191
|
return result.success;
|
|
221
192
|
}
|
|
@@ -228,9 +199,7 @@ export class ConfigurationValidator {
|
|
|
228
199
|
if (result.success) {
|
|
229
200
|
return [];
|
|
230
201
|
}
|
|
231
|
-
return result.error.errors.map(
|
|
232
|
-
(err) => `${err.path.join(".")}: ${err.message}`,
|
|
233
|
-
);
|
|
202
|
+
return result.error.errors.map((err) => `${err.path.join(".")}: ${err.message}`);
|
|
234
203
|
}
|
|
235
204
|
}
|
|
236
205
|
|
|
@@ -4,6 +4,7 @@ import * as path from "path";
|
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
import { WordPressClient } from "../client/api.js";
|
|
6
6
|
import { CachedWordPressClient } from "../client/CachedWordPressClient.js";
|
|
7
|
+
import { MockWordPressClient } from "../client/MockWordPressClient.js";
|
|
7
8
|
import { WordPressClientConfig } from "../types/client.js";
|
|
8
9
|
import { getErrorMessage } from "../utils/error.js";
|
|
9
10
|
import {
|
|
@@ -34,13 +35,14 @@ export class ServerConfiguration {
|
|
|
34
35
|
// Load environment variables
|
|
35
36
|
dotenv.config({ path: this.envPath });
|
|
36
37
|
|
|
37
|
-
// Debug output for DXT troubleshooting
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
`DEBUG: Environment file
|
|
43
|
-
|
|
38
|
+
// Debug output for DXT troubleshooting (reduced in DXT mode)
|
|
39
|
+
const isDXTMode = process.env.NODE_ENV === "dxt";
|
|
40
|
+
if (!isDXTMode) {
|
|
41
|
+
console.error("DEBUG: ServerConfiguration initialized");
|
|
42
|
+
console.error(`DEBUG: Root directory: ${this.rootDir}`);
|
|
43
|
+
console.error(`DEBUG: Environment file path: ${this.envPath}`);
|
|
44
|
+
console.error(`DEBUG: Environment file exists: ${fs.existsSync(this.envPath)}`);
|
|
45
|
+
}
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
/**
|
|
@@ -65,9 +67,7 @@ export class ServerConfiguration {
|
|
|
65
67
|
|
|
66
68
|
if (fs.existsSync(configPath)) {
|
|
67
69
|
if (process.env.NODE_ENV !== "test") {
|
|
68
|
-
console.error(
|
|
69
|
-
"INFO: Found mcp-wordpress.config.json, loading multi-site configuration.",
|
|
70
|
-
);
|
|
70
|
+
console.error("INFO: Found mcp-wordpress.config.json, loading multi-site configuration.");
|
|
71
71
|
}
|
|
72
72
|
return this.loadMultiSiteConfig(configPath);
|
|
73
73
|
} else {
|
|
@@ -116,21 +116,69 @@ export class ServerConfiguration {
|
|
|
116
116
|
validConfigs.push(site);
|
|
117
117
|
|
|
118
118
|
if (process.env.NODE_ENV !== "test") {
|
|
119
|
-
console.error(
|
|
120
|
-
`INFO: Initialized client for site: ${site.name} (ID: ${site.id})`,
|
|
121
|
-
);
|
|
119
|
+
console.error(`INFO: Initialized client for site: ${site.name} (ID: ${site.id})`);
|
|
122
120
|
}
|
|
123
121
|
}
|
|
124
122
|
|
|
125
123
|
return { clients, configs: validConfigs };
|
|
126
124
|
} catch (error) {
|
|
127
|
-
console.error(
|
|
128
|
-
`FATAL: Error reading or parsing mcp-wordpress.config.json: ${getErrorMessage(error)}`,
|
|
129
|
-
);
|
|
125
|
+
console.error(`FATAL: Error reading or parsing mcp-wordpress.config.json: ${getErrorMessage(error)}`);
|
|
130
126
|
process.exit(1);
|
|
131
127
|
}
|
|
132
128
|
}
|
|
133
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Check if we're in CI environment
|
|
132
|
+
*/
|
|
133
|
+
private isCIEnvironment(): boolean {
|
|
134
|
+
return (
|
|
135
|
+
process.env.CI === "true" ||
|
|
136
|
+
process.env.NODE_ENV === "ci" ||
|
|
137
|
+
process.env.NODE_ENV === "test" ||
|
|
138
|
+
process.env.GITHUB_ACTIONS === "true" ||
|
|
139
|
+
process.env.TRAVIS === "true" ||
|
|
140
|
+
process.env.CIRCLECI === "true"
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Create mock configuration for CI environments
|
|
146
|
+
*/
|
|
147
|
+
private createMockConfiguration(): {
|
|
148
|
+
clients: Map<string, WordPressClient>;
|
|
149
|
+
configs: SiteConfig[];
|
|
150
|
+
} {
|
|
151
|
+
const mockConfig = {
|
|
152
|
+
WORDPRESS_SITE_URL: "https://demo.wordpress.com",
|
|
153
|
+
WORDPRESS_USERNAME: "ci-user",
|
|
154
|
+
WORDPRESS_APP_PASSWORD: "ci-mock-password",
|
|
155
|
+
WORDPRESS_AUTH_METHOD: "app-password" as const,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const clientConfig: WordPressClientConfig = {
|
|
159
|
+
baseUrl: mockConfig.WORDPRESS_SITE_URL,
|
|
160
|
+
auth: {
|
|
161
|
+
method: mockConfig.WORDPRESS_AUTH_METHOD,
|
|
162
|
+
username: mockConfig.WORDPRESS_USERNAME,
|
|
163
|
+
appPassword: mockConfig.WORDPRESS_APP_PASSWORD,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Create mock client that won't actually connect to WordPress
|
|
168
|
+
const client = new MockWordPressClient(clientConfig);
|
|
169
|
+
const clients = new Map<string, WordPressClient>();
|
|
170
|
+
clients.set("default", client);
|
|
171
|
+
|
|
172
|
+
const siteConfig: SiteConfig = {
|
|
173
|
+
id: "default",
|
|
174
|
+
name: "Demo Site (CI Mode)",
|
|
175
|
+
config: mockConfig,
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
console.error("INFO: Using mock configuration for CI environment.");
|
|
179
|
+
return { clients, configs: [siteConfig] };
|
|
180
|
+
}
|
|
181
|
+
|
|
134
182
|
/**
|
|
135
183
|
* Load single-site configuration from environment variables
|
|
136
184
|
*/
|
|
@@ -139,66 +187,49 @@ export class ServerConfiguration {
|
|
|
139
187
|
configs: SiteConfig[];
|
|
140
188
|
} {
|
|
141
189
|
try {
|
|
142
|
-
// Debug output for DXT troubleshooting
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
`
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
190
|
+
// Debug output for DXT troubleshooting (reduced in DXT mode)
|
|
191
|
+
const isDXTMode = process.env.NODE_ENV === "dxt";
|
|
192
|
+
if (!isDXTMode) {
|
|
193
|
+
console.error("DEBUG: loadSingleSiteFromEnv called");
|
|
194
|
+
console.error(`DEBUG: mcpConfig provided: ${mcpConfig ? "YES" : "NO"}`);
|
|
195
|
+
console.error("DEBUG: Current environment variables:");
|
|
196
|
+
console.error(` WORDPRESS_SITE_URL: ${process.env.WORDPRESS_SITE_URL || "NOT SET"}`);
|
|
197
|
+
console.error(` WORDPRESS_USERNAME: ${process.env.WORDPRESS_USERNAME || "NOT SET"}`);
|
|
198
|
+
console.error(` WORDPRESS_APP_PASSWORD: ${process.env.WORDPRESS_APP_PASSWORD ? "SET" : "NOT SET"}`);
|
|
199
|
+
console.error(` WORDPRESS_AUTH_METHOD: ${process.env.WORDPRESS_AUTH_METHOD || "NOT SET"}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Check if we're in CI environment and credentials are missing
|
|
203
|
+
if (this.isCIEnvironment() && !process.env.WORDPRESS_SITE_URL) {
|
|
204
|
+
return this.createMockConfiguration();
|
|
205
|
+
}
|
|
158
206
|
|
|
159
207
|
// Validate MCP config if provided
|
|
160
|
-
const validatedMcpConfig = mcpConfig
|
|
161
|
-
? ConfigurationValidator.validateMcpConfig(mcpConfig)
|
|
162
|
-
: undefined;
|
|
208
|
+
const validatedMcpConfig = mcpConfig ? ConfigurationValidator.validateMcpConfig(mcpConfig) : undefined;
|
|
163
209
|
|
|
164
210
|
// Prepare environment configuration for validation
|
|
165
211
|
const envConfig = {
|
|
166
|
-
WORDPRESS_SITE_URL:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
WORDPRESS_USERNAME:
|
|
170
|
-
validatedMcpConfig?.wordpressUsername ||
|
|
171
|
-
process.env.WORDPRESS_USERNAME,
|
|
172
|
-
WORDPRESS_APP_PASSWORD:
|
|
173
|
-
validatedMcpConfig?.wordpressAppPassword ||
|
|
174
|
-
process.env.WORDPRESS_APP_PASSWORD,
|
|
212
|
+
WORDPRESS_SITE_URL: validatedMcpConfig?.wordpressSiteUrl || process.env.WORDPRESS_SITE_URL,
|
|
213
|
+
WORDPRESS_USERNAME: validatedMcpConfig?.wordpressUsername || process.env.WORDPRESS_USERNAME,
|
|
214
|
+
WORDPRESS_APP_PASSWORD: validatedMcpConfig?.wordpressAppPassword || process.env.WORDPRESS_APP_PASSWORD,
|
|
175
215
|
WORDPRESS_AUTH_METHOD:
|
|
176
|
-
validatedMcpConfig?.wordpressAuthMethod ||
|
|
177
|
-
process.env.WORDPRESS_AUTH_METHOD ||
|
|
178
|
-
"app-password",
|
|
216
|
+
validatedMcpConfig?.wordpressAuthMethod || process.env.WORDPRESS_AUTH_METHOD || "app-password",
|
|
179
217
|
NODE_ENV: process.env.NODE_ENV,
|
|
180
218
|
DEBUG: process.env.DEBUG,
|
|
181
219
|
DISABLE_CACHE: process.env.DISABLE_CACHE,
|
|
182
220
|
LOG_LEVEL: process.env.LOG_LEVEL,
|
|
183
221
|
};
|
|
184
222
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
` WORDPRESS_SITE_URL: ${envConfig.WORDPRESS_SITE_URL || "NOT SET"}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
`
|
|
191
|
-
|
|
192
|
-
console.error(
|
|
193
|
-
` WORDPRESS_APP_PASSWORD: ${envConfig.WORDPRESS_APP_PASSWORD ? "SET" : "NOT SET"}`,
|
|
194
|
-
);
|
|
195
|
-
console.error(
|
|
196
|
-
` WORDPRESS_AUTH_METHOD: ${envConfig.WORDPRESS_AUTH_METHOD || "NOT SET"}`,
|
|
197
|
-
);
|
|
223
|
+
if (!isDXTMode) {
|
|
224
|
+
console.error("DEBUG: Final envConfig for validation:");
|
|
225
|
+
console.error(` WORDPRESS_SITE_URL: ${envConfig.WORDPRESS_SITE_URL || "NOT SET"}`);
|
|
226
|
+
console.error(` WORDPRESS_USERNAME: ${envConfig.WORDPRESS_USERNAME || "NOT SET"}`);
|
|
227
|
+
console.error(` WORDPRESS_APP_PASSWORD: ${envConfig.WORDPRESS_APP_PASSWORD ? "SET" : "NOT SET"}`);
|
|
228
|
+
console.error(` WORDPRESS_AUTH_METHOD: ${envConfig.WORDPRESS_AUTH_METHOD || "NOT SET"}`);
|
|
229
|
+
}
|
|
198
230
|
|
|
199
231
|
// Validate environment configuration using Zod schema
|
|
200
|
-
const validatedConfig =
|
|
201
|
-
ConfigurationValidator.validateEnvironmentConfig(envConfig);
|
|
232
|
+
const validatedConfig = ConfigurationValidator.validateEnvironmentConfig(envConfig);
|
|
202
233
|
|
|
203
234
|
const clientConfig: WordPressClientConfig = {
|
|
204
235
|
baseUrl: validatedConfig.WORDPRESS_SITE_URL,
|
|
@@ -228,19 +259,15 @@ export class ServerConfiguration {
|
|
|
228
259
|
},
|
|
229
260
|
};
|
|
230
261
|
|
|
231
|
-
|
|
232
|
-
"INFO: Initialized client for default site in single-site mode."
|
|
233
|
-
|
|
262
|
+
if (!isDXTMode) {
|
|
263
|
+
console.error("INFO: Initialized client for default site in single-site mode.");
|
|
264
|
+
}
|
|
234
265
|
|
|
235
266
|
return { clients, configs: [siteConfig] };
|
|
236
267
|
} catch (error) {
|
|
237
|
-
console.error(
|
|
238
|
-
"ERROR: Configuration validation failed for single-site mode.",
|
|
239
|
-
);
|
|
268
|
+
console.error("ERROR: Configuration validation failed for single-site mode.");
|
|
240
269
|
console.error(`Details: ${getErrorMessage(error)}`);
|
|
241
|
-
console.error(
|
|
242
|
-
"Please check your environment variables or MCP configuration.",
|
|
243
|
-
);
|
|
270
|
+
console.error("Please check your environment variables or MCP configuration.");
|
|
244
271
|
return { clients: new Map(), configs: [] };
|
|
245
272
|
}
|
|
246
273
|
}
|