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
|
@@ -138,7 +138,7 @@ export class DocumentationGenerator {
|
|
|
138
138
|
* Generate complete documentation for all tools and types
|
|
139
139
|
*/
|
|
140
140
|
async generateFullDocumentation(): Promise<DocumentationOutput> {
|
|
141
|
-
console.
|
|
141
|
+
console.error("🚀 Starting API documentation generation...");
|
|
142
142
|
|
|
143
143
|
const tools = await this.extractAllToolDocumentation();
|
|
144
144
|
const categories = this.generateCategoryDocumentation(tools);
|
|
@@ -162,9 +162,7 @@ export class DocumentationGenerator {
|
|
|
162
162
|
// Write documentation to files
|
|
163
163
|
await this.writeDocumentationFiles(output);
|
|
164
164
|
|
|
165
|
-
console.
|
|
166
|
-
`✅ Documentation generation complete! ${tools.length} tools documented.`,
|
|
167
|
-
);
|
|
165
|
+
console.error(`✅ Documentation generation complete! ${tools.length} tools documented.`);
|
|
168
166
|
return output;
|
|
169
167
|
}
|
|
170
168
|
|
|
@@ -190,18 +188,11 @@ export class DocumentationGenerator {
|
|
|
190
188
|
const category = this.extractCategoryFromClassName(className);
|
|
191
189
|
|
|
192
190
|
for (const toolDef of toolDefinitions) {
|
|
193
|
-
const doc = await this.extractToolDocumentation(
|
|
194
|
-
toolDef,
|
|
195
|
-
category,
|
|
196
|
-
className,
|
|
197
|
-
);
|
|
191
|
+
const doc = await this.extractToolDocumentation(toolDef, category, className);
|
|
198
192
|
toolDocs.push(doc);
|
|
199
193
|
}
|
|
200
194
|
} catch (error) {
|
|
201
|
-
console.warn(
|
|
202
|
-
`⚠️ Failed to extract documentation for ${className}:`,
|
|
203
|
-
error,
|
|
204
|
-
);
|
|
195
|
+
console.warn(`⚠️ Failed to extract documentation for ${className}:`, error);
|
|
205
196
|
}
|
|
206
197
|
}
|
|
207
198
|
|
|
@@ -216,9 +207,7 @@ export class DocumentationGenerator {
|
|
|
216
207
|
category: string,
|
|
217
208
|
className: string,
|
|
218
209
|
): Promise<ToolDocumentation> {
|
|
219
|
-
const parameters = this.extractParameterDocumentation(
|
|
220
|
-
toolDef.parameters || [],
|
|
221
|
-
);
|
|
210
|
+
const parameters = this.extractParameterDocumentation(toolDef.parameters || []);
|
|
222
211
|
const examples = this.generateToolExamples(toolDef, category);
|
|
223
212
|
const wordpressEndpoint = this.wordpressEndpoints.get(toolDef.name);
|
|
224
213
|
const returnType = this.inferReturnType(toolDef.name, category);
|
|
@@ -242,9 +231,7 @@ export class DocumentationGenerator {
|
|
|
242
231
|
/**
|
|
243
232
|
* Extract parameter documentation
|
|
244
233
|
*/
|
|
245
|
-
private extractParameterDocumentation(
|
|
246
|
-
parameters: any[],
|
|
247
|
-
): ParameterDocumentation[] {
|
|
234
|
+
private extractParameterDocumentation(parameters: any[]): ParameterDocumentation[] {
|
|
248
235
|
return parameters.map((param) => ({
|
|
249
236
|
name: param.name,
|
|
250
237
|
type: param.type || "string",
|
|
@@ -259,10 +246,7 @@ export class DocumentationGenerator {
|
|
|
259
246
|
/**
|
|
260
247
|
* Generate usage examples for tools
|
|
261
248
|
*/
|
|
262
|
-
private generateToolExamples(
|
|
263
|
-
toolDef: ToolDefinition,
|
|
264
|
-
category: string,
|
|
265
|
-
): ExampleUsage[] {
|
|
249
|
+
private generateToolExamples(toolDef: ToolDefinition, category: string): ExampleUsage[] {
|
|
266
250
|
const examples: ExampleUsage[] = [];
|
|
267
251
|
|
|
268
252
|
// Basic usage example
|
|
@@ -291,10 +275,7 @@ export class DocumentationGenerator {
|
|
|
291
275
|
/**
|
|
292
276
|
* Generate basic usage example
|
|
293
277
|
*/
|
|
294
|
-
private generateBasicExample(
|
|
295
|
-
toolDef: ToolDefinition,
|
|
296
|
-
category: string,
|
|
297
|
-
): ExampleUsage | null {
|
|
278
|
+
private generateBasicExample(toolDef: ToolDefinition, category: string): ExampleUsage | null {
|
|
298
279
|
const toolName = toolDef.name;
|
|
299
280
|
const basicParams: Record<string, any> = {};
|
|
300
281
|
|
|
@@ -310,11 +291,7 @@ export class DocumentationGenerator {
|
|
|
310
291
|
description: `Simple example of using ${toolName}`,
|
|
311
292
|
command: toolName,
|
|
312
293
|
parameters: basicParams,
|
|
313
|
-
expectedResponse: this.generateExpectedResponse(
|
|
314
|
-
toolName,
|
|
315
|
-
category,
|
|
316
|
-
"basic",
|
|
317
|
-
),
|
|
294
|
+
expectedResponse: this.generateExpectedResponse(toolName, category, "basic"),
|
|
318
295
|
errorExample: {
|
|
319
296
|
scenario: "Authentication failure",
|
|
320
297
|
error: {
|
|
@@ -328,10 +305,7 @@ export class DocumentationGenerator {
|
|
|
328
305
|
/**
|
|
329
306
|
* Generate multi-site example
|
|
330
307
|
*/
|
|
331
|
-
private generateMultiSiteExample(
|
|
332
|
-
toolDef: ToolDefinition,
|
|
333
|
-
category: string,
|
|
334
|
-
): ExampleUsage | null {
|
|
308
|
+
private generateMultiSiteExample(toolDef: ToolDefinition, category: string): ExampleUsage | null {
|
|
335
309
|
const params = { site: "site1", ...this.getExampleParameters(toolDef, 1) };
|
|
336
310
|
|
|
337
311
|
return {
|
|
@@ -339,21 +313,14 @@ export class DocumentationGenerator {
|
|
|
339
313
|
description: `Using ${toolDef.name} with specific site targeting`,
|
|
340
314
|
command: toolDef.name,
|
|
341
315
|
parameters: params,
|
|
342
|
-
expectedResponse: this.generateExpectedResponse(
|
|
343
|
-
toolDef.name,
|
|
344
|
-
category,
|
|
345
|
-
"multisite",
|
|
346
|
-
),
|
|
316
|
+
expectedResponse: this.generateExpectedResponse(toolDef.name, category, "multisite"),
|
|
347
317
|
};
|
|
348
318
|
}
|
|
349
319
|
|
|
350
320
|
/**
|
|
351
321
|
* Generate advanced example with all parameters
|
|
352
322
|
*/
|
|
353
|
-
private generateAdvancedExample(
|
|
354
|
-
toolDef: ToolDefinition,
|
|
355
|
-
category: string,
|
|
356
|
-
): ExampleUsage | null {
|
|
323
|
+
private generateAdvancedExample(toolDef: ToolDefinition, category: string): ExampleUsage | null {
|
|
357
324
|
const allParams = this.getExampleParameters(toolDef, "all");
|
|
358
325
|
|
|
359
326
|
if (Object.keys(allParams).length <= 2) {
|
|
@@ -365,20 +332,14 @@ export class DocumentationGenerator {
|
|
|
365
332
|
description: "Comprehensive example using all available parameters",
|
|
366
333
|
command: toolDef.name,
|
|
367
334
|
parameters: allParams,
|
|
368
|
-
expectedResponse: this.generateExpectedResponse(
|
|
369
|
-
toolDef.name,
|
|
370
|
-
category,
|
|
371
|
-
"advanced",
|
|
372
|
-
),
|
|
335
|
+
expectedResponse: this.generateExpectedResponse(toolDef.name, category, "advanced"),
|
|
373
336
|
};
|
|
374
337
|
}
|
|
375
338
|
|
|
376
339
|
/**
|
|
377
340
|
* Generate category documentation
|
|
378
341
|
*/
|
|
379
|
-
private generateCategoryDocumentation(
|
|
380
|
-
tools: ToolDocumentation[],
|
|
381
|
-
): CategoryDocumentation[] {
|
|
342
|
+
private generateCategoryDocumentation(tools: ToolDocumentation[]): CategoryDocumentation[] {
|
|
382
343
|
const categories = new Map<string, ToolDocumentation[]>();
|
|
383
344
|
|
|
384
345
|
// Group tools by category
|
|
@@ -389,15 +350,13 @@ export class DocumentationGenerator {
|
|
|
389
350
|
categories.get(tool.category)!.push(tool);
|
|
390
351
|
}
|
|
391
352
|
|
|
392
|
-
return Array.from(categories.entries()).map(
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}),
|
|
400
|
-
);
|
|
353
|
+
return Array.from(categories.entries()).map(([categoryName, categoryTools]) => ({
|
|
354
|
+
name: categoryName,
|
|
355
|
+
description: this.getCategoryDescription(categoryName),
|
|
356
|
+
toolCount: categoryTools.length,
|
|
357
|
+
tools: categoryTools.map((t) => t.name).sort(),
|
|
358
|
+
usagePatterns: this.generateUsagePatterns(categoryName, categoryTools),
|
|
359
|
+
}));
|
|
401
360
|
}
|
|
402
361
|
|
|
403
362
|
/**
|
|
@@ -446,10 +405,7 @@ export class DocumentationGenerator {
|
|
|
446
405
|
/**
|
|
447
406
|
* Generate OpenAPI specification
|
|
448
407
|
*/
|
|
449
|
-
private generateOpenAPISpecification(
|
|
450
|
-
tools: ToolDocumentation[],
|
|
451
|
-
types: TypeDocumentation[],
|
|
452
|
-
): OpenAPISpecification {
|
|
408
|
+
private generateOpenAPISpecification(tools: ToolDocumentation[], types: TypeDocumentation[]): OpenAPISpecification {
|
|
453
409
|
const paths: Record<string, any> = {};
|
|
454
410
|
const components: Record<string, any> = {
|
|
455
411
|
schemas: {},
|
|
@@ -524,9 +480,7 @@ export class DocumentationGenerator {
|
|
|
524
480
|
/**
|
|
525
481
|
* Write all documentation files
|
|
526
482
|
*/
|
|
527
|
-
private async writeDocumentationFiles(
|
|
528
|
-
output: DocumentationOutput,
|
|
529
|
-
): Promise<void> {
|
|
483
|
+
private async writeDocumentationFiles(output: DocumentationOutput): Promise<void> {
|
|
530
484
|
const outputDir = this.config.outputDir;
|
|
531
485
|
|
|
532
486
|
// Ensure output directory exists
|
|
@@ -560,19 +514,13 @@ export class DocumentationGenerator {
|
|
|
560
514
|
|
|
561
515
|
// Write OpenAPI specification
|
|
562
516
|
if (output.openApiSpec) {
|
|
563
|
-
await fs.promises.writeFile(
|
|
564
|
-
path.join(outputDir, "openapi.json"),
|
|
565
|
-
JSON.stringify(output.openApiSpec, null, 2),
|
|
566
|
-
);
|
|
517
|
+
await fs.promises.writeFile(path.join(outputDir, "openapi.json"), JSON.stringify(output.openApiSpec, null, 2));
|
|
567
518
|
}
|
|
568
519
|
|
|
569
520
|
// Write summary
|
|
570
|
-
await fs.promises.writeFile(
|
|
571
|
-
path.join(outputDir, "summary.json"),
|
|
572
|
-
JSON.stringify(output.summary, null, 2),
|
|
573
|
-
);
|
|
521
|
+
await fs.promises.writeFile(path.join(outputDir, "summary.json"), JSON.stringify(output.summary, null, 2));
|
|
574
522
|
|
|
575
|
-
console.
|
|
523
|
+
console.error(`📁 Documentation written to ${outputDir}/`);
|
|
576
524
|
}
|
|
577
525
|
|
|
578
526
|
// Helper methods for specific documentation tasks...
|
|
@@ -624,8 +572,7 @@ export class DocumentationGenerator {
|
|
|
624
572
|
version: "1.2.0",
|
|
625
573
|
coverage: {
|
|
626
574
|
toolsWithExamples: tools.filter((t) => t.examples.length > 0).length,
|
|
627
|
-
toolsWithWordPressMapping: tools.filter((t) => t.wordpressEndpoint)
|
|
628
|
-
.length,
|
|
575
|
+
toolsWithWordPressMapping: tools.filter((t) => t.wordpressEndpoint).length,
|
|
629
576
|
typesDocumented: types.length,
|
|
630
577
|
},
|
|
631
578
|
};
|
|
@@ -709,11 +656,7 @@ export class DocumentationGenerator {
|
|
|
709
656
|
return exampleValues[param.name] || "example_value";
|
|
710
657
|
}
|
|
711
658
|
|
|
712
|
-
private generateExpectedResponse(
|
|
713
|
-
toolName: string,
|
|
714
|
-
category: string,
|
|
715
|
-
type: string,
|
|
716
|
-
): any {
|
|
659
|
+
private generateExpectedResponse(toolName: string, category: string, type: string): any {
|
|
717
660
|
if (toolName.includes("list")) {
|
|
718
661
|
return {
|
|
719
662
|
success: true,
|
|
@@ -781,10 +724,7 @@ export class DocumentationGenerator {
|
|
|
781
724
|
};
|
|
782
725
|
}
|
|
783
726
|
|
|
784
|
-
private getExampleParameters(
|
|
785
|
-
toolDef: ToolDefinition,
|
|
786
|
-
type: string | number,
|
|
787
|
-
): Record<string, any> {
|
|
727
|
+
private getExampleParameters(toolDef: ToolDefinition, type: string | number): Record<string, any> {
|
|
788
728
|
const params: Record<string, any> = {};
|
|
789
729
|
const parameters = toolDef.parameters || [];
|
|
790
730
|
|
|
@@ -816,16 +756,10 @@ export class DocumentationGenerator {
|
|
|
816
756
|
cache: "Performance caching and optimization tools",
|
|
817
757
|
performance: "Performance monitoring and analytics tools",
|
|
818
758
|
};
|
|
819
|
-
return (
|
|
820
|
-
descriptions[categoryName.toLowerCase()] ||
|
|
821
|
-
`${categoryName} management tools`
|
|
822
|
-
);
|
|
759
|
+
return descriptions[categoryName.toLowerCase()] || `${categoryName} management tools`;
|
|
823
760
|
}
|
|
824
761
|
|
|
825
|
-
private generateUsagePatterns(
|
|
826
|
-
categoryName: string,
|
|
827
|
-
tools: ToolDocumentation[],
|
|
828
|
-
): string[] {
|
|
762
|
+
private generateUsagePatterns(categoryName: string, tools: ToolDocumentation[]): string[] {
|
|
829
763
|
const patterns: Record<string, string[]> = {
|
|
830
764
|
posts: [
|
|
831
765
|
"Create and publish blog posts",
|
|
@@ -865,8 +799,7 @@ export class DocumentationGenerator {
|
|
|
865
799
|
return {
|
|
866
800
|
id: 123,
|
|
867
801
|
title: "Welcome to WordPress",
|
|
868
|
-
content:
|
|
869
|
-
"<p>This is your first post. Edit or delete it to get started!</p>",
|
|
802
|
+
content: "<p>This is your first post. Edit or delete it to get started!</p>",
|
|
870
803
|
status: "publish",
|
|
871
804
|
date: "2024-01-01T00:00:00Z",
|
|
872
805
|
author: 1,
|
|
@@ -953,8 +886,7 @@ export class DocumentationGenerator {
|
|
|
953
886
|
code: "AUTHENTICATION_FAILED",
|
|
954
887
|
message: "Authentication failed",
|
|
955
888
|
description: "Invalid credentials or insufficient permissions",
|
|
956
|
-
resolution:
|
|
957
|
-
"Check your authentication credentials and user permissions",
|
|
889
|
+
resolution: "Check your authentication credentials and user permissions",
|
|
958
890
|
},
|
|
959
891
|
{
|
|
960
892
|
code: "VALIDATION_ERROR",
|
|
@@ -972,8 +904,7 @@ export class DocumentationGenerator {
|
|
|
972
904
|
code: "PERMISSION_DENIED",
|
|
973
905
|
message: "Insufficient permissions",
|
|
974
906
|
description: "The user does not have permission to perform this action",
|
|
975
|
-
resolution:
|
|
976
|
-
"Contact an administrator to grant the necessary permissions",
|
|
907
|
+
resolution: "Contact an administrator to grant the necessary permissions",
|
|
977
908
|
},
|
|
978
909
|
];
|
|
979
910
|
}
|
|
@@ -1012,10 +943,7 @@ export class DocumentationGenerator {
|
|
|
1012
943
|
const formatter = new MarkdownFormatter();
|
|
1013
944
|
const content = formatter.generateApiOverview(output);
|
|
1014
945
|
|
|
1015
|
-
await fs.promises.writeFile(
|
|
1016
|
-
path.join(this.config.outputDir, "README.md"),
|
|
1017
|
-
content,
|
|
1018
|
-
);
|
|
946
|
+
await fs.promises.writeFile(path.join(this.config.outputDir, "README.md"), content);
|
|
1019
947
|
}
|
|
1020
948
|
|
|
1021
949
|
private async writeToolDocumentation(tool: ToolDocumentation): Promise<void> {
|
|
@@ -1023,25 +951,16 @@ export class DocumentationGenerator {
|
|
|
1023
951
|
const formatter = new MarkdownFormatter();
|
|
1024
952
|
const content = formatter.generateToolDocumentation(tool);
|
|
1025
953
|
|
|
1026
|
-
await fs.promises.writeFile(
|
|
1027
|
-
path.join(this.config.outputDir, "tools", `${tool.name}.md`),
|
|
1028
|
-
content,
|
|
1029
|
-
);
|
|
954
|
+
await fs.promises.writeFile(path.join(this.config.outputDir, "tools", `${tool.name}.md`), content);
|
|
1030
955
|
}
|
|
1031
956
|
|
|
1032
|
-
private async writeCategoryDocumentation(
|
|
1033
|
-
category: CategoryDocumentation,
|
|
1034
|
-
): Promise<void> {
|
|
957
|
+
private async writeCategoryDocumentation(category: CategoryDocumentation): Promise<void> {
|
|
1035
958
|
const { MarkdownFormatter } = await import("./MarkdownFormatter.js");
|
|
1036
959
|
const formatter = new MarkdownFormatter();
|
|
1037
960
|
const content = formatter.generateCategoryDocumentation(category);
|
|
1038
961
|
|
|
1039
962
|
await fs.promises.writeFile(
|
|
1040
|
-
path.join(
|
|
1041
|
-
this.config.outputDir,
|
|
1042
|
-
"categories",
|
|
1043
|
-
`${category.name.toLowerCase()}.md`,
|
|
1044
|
-
),
|
|
963
|
+
path.join(this.config.outputDir, "categories", `${category.name.toLowerCase()}.md`),
|
|
1045
964
|
content,
|
|
1046
965
|
);
|
|
1047
966
|
}
|
|
@@ -1051,9 +970,6 @@ export class DocumentationGenerator {
|
|
|
1051
970
|
const formatter = new MarkdownFormatter();
|
|
1052
971
|
const content = formatter.generateTypeDocumentation(type);
|
|
1053
972
|
|
|
1054
|
-
await fs.promises.writeFile(
|
|
1055
|
-
path.join(this.config.outputDir, "types", `${type.name}.md`),
|
|
1056
|
-
content,
|
|
1057
|
-
);
|
|
973
|
+
await fs.promises.writeFile(path.join(this.config.outputDir, "types", `${type.name}.md`), content);
|
|
1058
974
|
}
|
|
1059
975
|
}
|
package/src/dxt-entry.cjs
CHANGED
|
@@ -16,6 +16,9 @@ console.error(`DEBUG: Current working directory: ${process.cwd()}`);
|
|
|
16
16
|
console.error(`DEBUG: __dirname: ${__dirname}`);
|
|
17
17
|
console.error(`DEBUG: Node version: ${process.version}`);
|
|
18
18
|
|
|
19
|
+
// Set DXT mode environment variable
|
|
20
|
+
process.env.NODE_ENV = "dxt";
|
|
21
|
+
|
|
19
22
|
console.error("DEBUG: Environment variables passed from DXT:");
|
|
20
23
|
console.error(` WORDPRESS_SITE_URL: ${process.env.WORDPRESS_SITE_URL ? 'SET' : 'NOT SET'}`);
|
|
21
24
|
console.error(` WORDPRESS_USERNAME: ${process.env.WORDPRESS_USERNAME ? 'SET' : 'NOT SET'}`);
|
|
@@ -30,7 +33,7 @@ async function startDXTServer() {
|
|
|
30
33
|
console.error("DEBUG: Creating MCPWordPressServer instance from DXT entry point...");
|
|
31
34
|
const server = new MCPWordPressServer();
|
|
32
35
|
|
|
33
|
-
console.error("DEBUG: Starting server...");
|
|
36
|
+
console.error("DEBUG: Starting server (DXT mode - fast startup)...");
|
|
34
37
|
await server.run();
|
|
35
38
|
|
|
36
39
|
// Handle graceful shutdown
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
console.error("DEBUG: MCP WordPress Server module loading started...");
|
|
2
|
-
|
|
3
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
3
|
import { fileURLToPath } from "url";
|
|
6
4
|
import { WordPressClient } from "./client/api.js";
|
|
7
|
-
import {
|
|
8
|
-
ServerConfiguration,
|
|
9
|
-
SiteConfig,
|
|
10
|
-
} from "./config/ServerConfiguration.js";
|
|
5
|
+
import { ServerConfiguration, SiteConfig } from "./config/ServerConfiguration.js";
|
|
11
6
|
import { ToolRegistry } from "./server/ToolRegistry.js";
|
|
12
7
|
import { ConnectionTester } from "./server/ConnectionTester.js";
|
|
13
8
|
import { getErrorMessage } from "./utils/error.js";
|
|
14
9
|
|
|
15
|
-
console.error("DEBUG: All imports completed successfully");
|
|
16
|
-
|
|
17
10
|
// --- Constants ---
|
|
18
11
|
const SERVER_VERSION = "1.1.8"; // Technical debt resolution and modular architecture
|
|
19
12
|
|
|
@@ -26,20 +19,6 @@ class MCPWordPressServer {
|
|
|
26
19
|
private toolRegistry: ToolRegistry;
|
|
27
20
|
|
|
28
21
|
constructor(mcpConfig?: any) {
|
|
29
|
-
// Add debugging output for DXT troubleshooting
|
|
30
|
-
console.error("DEBUG: Starting MCP WordPress Server initialization...");
|
|
31
|
-
console.error("DEBUG: Environment variables:");
|
|
32
|
-
console.error(
|
|
33
|
-
` WORDPRESS_SITE_URL: ${process.env.WORDPRESS_SITE_URL ? "SET" : "NOT SET"}`,
|
|
34
|
-
);
|
|
35
|
-
console.error(
|
|
36
|
-
` WORDPRESS_USERNAME: ${process.env.WORDPRESS_USERNAME ? "SET" : "NOT SET"}`,
|
|
37
|
-
);
|
|
38
|
-
console.error(
|
|
39
|
-
` WORDPRESS_APP_PASSWORD: ${process.env.WORDPRESS_APP_PASSWORD ? "SET" : "NOT SET"}`,
|
|
40
|
-
);
|
|
41
|
-
console.error(` Working directory: ${process.cwd()}`);
|
|
42
|
-
|
|
43
22
|
this.loadConfiguration(mcpConfig);
|
|
44
23
|
|
|
45
24
|
if (this.wordpressClients.size === 0) {
|
|
@@ -64,8 +43,7 @@ class MCPWordPressServer {
|
|
|
64
43
|
|
|
65
44
|
private loadConfiguration(mcpConfig?: any) {
|
|
66
45
|
const serverConfig = ServerConfiguration.getInstance();
|
|
67
|
-
const { clients, configs } =
|
|
68
|
-
serverConfig.loadClientConfigurations(mcpConfig);
|
|
46
|
+
const { clients, configs } = serverConfig.loadClientConfigurations(mcpConfig);
|
|
69
47
|
|
|
70
48
|
this.wordpressClients = clients;
|
|
71
49
|
this.siteConfigs = configs;
|
|
@@ -81,21 +59,45 @@ class MCPWordPressServer {
|
|
|
81
59
|
}
|
|
82
60
|
|
|
83
61
|
async run() {
|
|
84
|
-
|
|
85
|
-
|
|
62
|
+
// Skip connection testing in DXT environment to prevent timeouts
|
|
63
|
+
const isDXTMode = process.env.NODE_ENV === "dxt" || process.argv[0]?.includes("dxt-entry");
|
|
64
|
+
|
|
65
|
+
if (!this.initialized && !isDXTMode) {
|
|
66
|
+
console.error("INFO: Testing connections to configured WordPress sites...");
|
|
67
|
+
try {
|
|
68
|
+
await this.testClientConnections();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error(`WARNING: Connection test failed: ${getErrorMessage(error)}`);
|
|
71
|
+
console.error("INFO: Continuing with server startup. Tools will be available but connections may fail.");
|
|
72
|
+
}
|
|
73
|
+
} else if (isDXTMode) {
|
|
74
|
+
console.error("INFO: DXT mode detected - skipping connection tests for faster startup");
|
|
75
|
+
this.initialized = true;
|
|
86
76
|
}
|
|
77
|
+
|
|
87
78
|
console.error("INFO: Starting MCP WordPress Server...");
|
|
88
79
|
|
|
89
|
-
// Connect to stdio transport
|
|
80
|
+
// Connect to stdio transport with timeout
|
|
90
81
|
const transport = new StdioServerTransport();
|
|
91
|
-
await this.server.connect(transport);
|
|
92
82
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
83
|
+
// Add timeout protection for server connection
|
|
84
|
+
const connectionTimeout = setTimeout(() => {
|
|
85
|
+
console.error("ERROR: Server connection timed out after 30 seconds");
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}, 30000);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await this.server.connect(transport);
|
|
91
|
+
clearTimeout(connectionTimeout);
|
|
92
|
+
|
|
93
|
+
console.error(`INFO: Server started and connected. Tools available for ${this.wordpressClients.size} site(s).`);
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
// Keep the process alive
|
|
96
|
+
process.stdin.resume();
|
|
97
|
+
} catch (error) {
|
|
98
|
+
clearTimeout(connectionTimeout);
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
async shutdown() {
|
|
@@ -107,16 +109,8 @@ class MCPWordPressServer {
|
|
|
107
109
|
|
|
108
110
|
// --- Main Execution ---
|
|
109
111
|
async function main() {
|
|
110
|
-
console.error("DEBUG: main() function started");
|
|
111
|
-
console.error(`DEBUG: process.argv: ${JSON.stringify(process.argv)}`);
|
|
112
|
-
console.error(
|
|
113
|
-
`DEBUG: fileURLToPath(import.meta.url): ${fileURLToPath(import.meta.url)}`,
|
|
114
|
-
);
|
|
115
|
-
|
|
116
112
|
try {
|
|
117
|
-
console.error("DEBUG: Creating MCPWordPressServer instance...");
|
|
118
113
|
const mcpServer = new MCPWordPressServer();
|
|
119
|
-
console.error("DEBUG: MCPWordPressServer created, calling run()...");
|
|
120
114
|
await mcpServer.run();
|
|
121
115
|
|
|
122
116
|
const shutdown = async () => {
|
|
@@ -128,18 +122,10 @@ async function main() {
|
|
|
128
122
|
process.on("SIGTERM", shutdown);
|
|
129
123
|
} catch (error) {
|
|
130
124
|
console.error(`FATAL: Failed to start server: ${getErrorMessage(error)}`);
|
|
131
|
-
console.error(`FATAL: Error stack: ${(error as Error).stack}`);
|
|
132
125
|
process.exit(1);
|
|
133
126
|
}
|
|
134
127
|
}
|
|
135
128
|
|
|
136
|
-
console.error(
|
|
137
|
-
`DEBUG: Checking if should run main - process.argv[1]: ${process.argv[1]}`,
|
|
138
|
-
);
|
|
139
|
-
console.error(
|
|
140
|
-
`DEBUG: fileURLToPath(import.meta.url): ${fileURLToPath(import.meta.url)}`,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
129
|
// Check if running as main module - handle both direct execution and DXT entry point
|
|
144
130
|
const isMainModule =
|
|
145
131
|
process.argv[1] === fileURLToPath(import.meta.url) ||
|
|
@@ -148,12 +134,7 @@ const isMainModule =
|
|
|
148
134
|
!process.argv[1]; // When run through DXT, process.argv[1] might be undefined
|
|
149
135
|
|
|
150
136
|
if (isMainModule) {
|
|
151
|
-
console.error("DEBUG: Running main function...");
|
|
152
137
|
main();
|
|
153
|
-
} else {
|
|
154
|
-
console.error(
|
|
155
|
-
"DEBUG: Not running main function - module imported, not executed directly",
|
|
156
|
-
);
|
|
157
138
|
}
|
|
158
139
|
|
|
159
140
|
export default MCPWordPressServer;
|
|
@@ -10,8 +10,7 @@ const URL_PATTERN = /^https?:\/\/[^\s<>'"{}|\\^`\[\]]+$/;
|
|
|
10
10
|
const EMAIL_PATTERN = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
11
11
|
const SLUG_PATTERN = /^[a-z0-9-]+$/;
|
|
12
12
|
const SCRIPT_PATTERN = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
|
|
13
|
-
const SQL_INJECTION_PATTERN =
|
|
14
|
-
/('|(\\')|(;)|(\\x00)|(\\n)|(\\r)|(\\x1a)|(\\x22)|(\\x27)|(\\x5c)|(\\x60))/i;
|
|
13
|
+
const SQL_INJECTION_PATTERN = /('|(\\')|(;)|(\\x00)|(\\n)|(\\r)|(\\x1a)|(\\x22)|(\\x27)|(\\x5c)|(\\x60))/i;
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Security validation schemas
|
|
@@ -22,10 +21,7 @@ export const SecuritySchemas = {
|
|
|
22
21
|
.string()
|
|
23
22
|
.max(10000, "String too long")
|
|
24
23
|
.refine((val) => !SCRIPT_PATTERN.test(val), "Script tags not allowed")
|
|
25
|
-
.refine(
|
|
26
|
-
(val) => !val.includes("javascript:"),
|
|
27
|
-
"JavaScript URLs not allowed",
|
|
28
|
-
)
|
|
24
|
+
.refine((val) => !val.includes("javascript:"), "JavaScript URLs not allowed")
|
|
29
25
|
.refine((val) => !val.includes("data:"), "Data URLs not allowed")
|
|
30
26
|
.refine((val) => !val.includes("onerror="), "Event handlers not allowed")
|
|
31
27
|
.refine((val) => !val.includes("onload="), "Event handlers not allowed")
|
|
@@ -36,10 +32,7 @@ export const SecuritySchemas = {
|
|
|
36
32
|
.string()
|
|
37
33
|
.max(100000, "Content too long")
|
|
38
34
|
.refine((val) => !SCRIPT_PATTERN.test(val), "Script tags not allowed")
|
|
39
|
-
.refine(
|
|
40
|
-
(val) => !val.includes("javascript:"),
|
|
41
|
-
"JavaScript URLs not allowed",
|
|
42
|
-
)
|
|
35
|
+
.refine((val) => !val.includes("javascript:"), "JavaScript URLs not allowed")
|
|
43
36
|
.refine((val) => !val.includes("on[a-z]+="), "Event handlers not allowed"),
|
|
44
37
|
|
|
45
38
|
// URL validation
|
|
@@ -47,10 +40,7 @@ export const SecuritySchemas = {
|
|
|
47
40
|
.string()
|
|
48
41
|
.url("Invalid URL format")
|
|
49
42
|
.regex(URL_PATTERN, "URL contains invalid characters")
|
|
50
|
-
.refine(
|
|
51
|
-
(val) => !val.includes("javascript:"),
|
|
52
|
-
"JavaScript URLs not allowed",
|
|
53
|
-
)
|
|
43
|
+
.refine((val) => !val.includes("javascript:"), "JavaScript URLs not allowed")
|
|
54
44
|
.refine((val) => !val.includes("data:"), "Data URLs not allowed"),
|
|
55
45
|
|
|
56
46
|
// Email validation
|
|
@@ -65,49 +55,30 @@ export const SecuritySchemas = {
|
|
|
65
55
|
.string()
|
|
66
56
|
.min(1, "Slug cannot be empty")
|
|
67
57
|
.max(100, "Slug too long")
|
|
68
|
-
.regex(
|
|
69
|
-
SLUG_PATTERN,
|
|
70
|
-
"Slug can only contain lowercase letters, numbers, and hyphens",
|
|
71
|
-
),
|
|
58
|
+
.regex(SLUG_PATTERN, "Slug can only contain lowercase letters, numbers, and hyphens"),
|
|
72
59
|
|
|
73
60
|
// WordPress post/page content
|
|
74
61
|
wpContent: z
|
|
75
62
|
.string()
|
|
76
63
|
.max(1000000, "Content too long")
|
|
77
|
-
.refine(
|
|
78
|
-
|
|
79
|
-
"Script tags not allowed in content",
|
|
80
|
-
)
|
|
81
|
-
.refine(
|
|
82
|
-
(val) => !val.includes("javascript:"),
|
|
83
|
-
"JavaScript URLs not allowed",
|
|
84
|
-
),
|
|
64
|
+
.refine((val) => !SCRIPT_PATTERN.test(val), "Script tags not allowed in content")
|
|
65
|
+
.refine((val) => !val.includes("javascript:"), "JavaScript URLs not allowed"),
|
|
85
66
|
|
|
86
67
|
// Site ID validation
|
|
87
68
|
siteId: z
|
|
88
69
|
.string()
|
|
89
70
|
.min(1, "Site ID cannot be empty")
|
|
90
71
|
.max(50, "Site ID too long")
|
|
91
|
-
.regex(
|
|
92
|
-
/^[a-zA-Z0-9\-_]+$/,
|
|
93
|
-
"Site ID can only contain letters, numbers, hyphens, and underscores",
|
|
94
|
-
),
|
|
72
|
+
.regex(/^[a-zA-Z0-9\-_]+$/, "Site ID can only contain letters, numbers, hyphens, and underscores"),
|
|
95
73
|
|
|
96
74
|
// WordPress ID (numeric)
|
|
97
|
-
wpId: z
|
|
98
|
-
.number()
|
|
99
|
-
.int("ID must be an integer")
|
|
100
|
-
.positive("ID must be positive")
|
|
101
|
-
.max(999999999, "ID too large"),
|
|
75
|
+
wpId: z.number().int("ID must be an integer").positive("ID must be positive").max(999999999, "ID too large"),
|
|
102
76
|
|
|
103
77
|
// Search query with SQL injection protection
|
|
104
78
|
searchQuery: z
|
|
105
79
|
.string()
|
|
106
80
|
.max(500, "Search query too long")
|
|
107
|
-
.refine(
|
|
108
|
-
(val) => !SQL_INJECTION_PATTERN.test(val),
|
|
109
|
-
"Invalid characters in search query",
|
|
110
|
-
)
|
|
81
|
+
.refine((val) => !SQL_INJECTION_PATTERN.test(val), "Invalid characters in search query")
|
|
111
82
|
.refine((val) => !val.includes("--"), "SQL comments not allowed")
|
|
112
83
|
.refine((val) => !val.includes("/*"), "SQL comments not allowed"),
|
|
113
84
|
|
|
@@ -188,11 +159,7 @@ export class InputSanitizer {
|
|
|
188
159
|
* Security validation decorator for tool methods
|
|
189
160
|
*/
|
|
190
161
|
export function validateSecurity(schema: z.ZodSchema) {
|
|
191
|
-
return function (
|
|
192
|
-
target: any,
|
|
193
|
-
propertyName: string,
|
|
194
|
-
descriptor: PropertyDescriptor,
|
|
195
|
-
) {
|
|
162
|
+
return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
|
|
196
163
|
const method = descriptor.value;
|
|
197
164
|
|
|
198
165
|
descriptor.value = async function (...args: any[]) {
|
|
@@ -202,7 +169,7 @@ export function validateSecurity(schema: z.ZodSchema) {
|
|
|
202
169
|
const validatedParams = schema.parse(params);
|
|
203
170
|
|
|
204
171
|
// Log security validation (without sensitive data)
|
|
205
|
-
console.
|
|
172
|
+
console.error(`Security validation passed for ${propertyName}`, {
|
|
206
173
|
timestamp: new Date().toISOString(),
|
|
207
174
|
method: propertyName,
|
|
208
175
|
paramCount: Object.keys(validatedParams).length,
|
|
@@ -215,12 +182,7 @@ export function validateSecurity(schema: z.ZodSchema) {
|
|
|
215
182
|
console.error(`Security validation failed for ${propertyName}`, {
|
|
216
183
|
timestamp: new Date().toISOString(),
|
|
217
184
|
method: propertyName,
|
|
218
|
-
error:
|
|
219
|
-
error instanceof z.ZodError
|
|
220
|
-
? error.errors
|
|
221
|
-
: error instanceof Error
|
|
222
|
-
? error.message
|
|
223
|
-
: String(error),
|
|
185
|
+
error: error instanceof z.ZodError ? error.errors : error instanceof Error ? error.message : String(error),
|
|
224
186
|
});
|
|
225
187
|
|
|
226
188
|
throw new SecurityValidationError(
|
|
@@ -229,8 +191,7 @@ export function validateSecurity(schema: z.ZodSchema) {
|
|
|
229
191
|
? error.errors
|
|
230
192
|
: [
|
|
231
193
|
{
|
|
232
|
-
message:
|
|
233
|
-
error instanceof Error ? error.message : String(error),
|
|
194
|
+
message: error instanceof Error ? error.message : String(error),
|
|
234
195
|
},
|
|
235
196
|
],
|
|
236
197
|
);
|
|
@@ -328,10 +289,7 @@ export const ToolSchemas = {
|
|
|
328
289
|
* Rate limiting and DoS protection
|
|
329
290
|
*/
|
|
330
291
|
export class SecurityLimiter {
|
|
331
|
-
private static requestCounts = new Map<
|
|
332
|
-
string,
|
|
333
|
-
{ count: number; resetTime: number }
|
|
334
|
-
>();
|
|
292
|
+
private static requestCounts = new Map<string, { count: number; resetTime: number }>();
|
|
335
293
|
private static readonly RATE_LIMIT = 1000; // requests per window
|
|
336
294
|
private static readonly WINDOW_MS = 60 * 1000; // 1 minute
|
|
337
295
|
|