mcp-wordpress 1.4.0 → 1.5.1
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 +20 -1
- package/dist/cache/CacheInvalidation.d.ts.map +1 -1
- package/dist/client/CachedWordPressClient.d.ts.map +1 -1
- package/dist/client/CachedWordPressClient.js.map +1 -1
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +11 -3
- package/dist/client/api.js.map +1 -1
- package/dist/client/auth.js.map +1 -1
- package/dist/client/managers/AuthenticationManager.js.map +1 -1
- package/dist/client/managers/RequestManager.js +0 -1
- package/dist/client/managers/RequestManager.js.map +1 -1
- package/dist/config/ServerConfiguration.d.ts.map +1 -1
- package/dist/config/ServerConfiguration.js +18 -0
- package/dist/config/ServerConfiguration.js.map +1 -1
- package/dist/docs/MarkdownFormatter.js.map +1 -1
- package/dist/dxt-entry.d.ts +6 -0
- package/dist/dxt-entry.d.ts.map +1 -0
- package/dist/dxt-entry.js +38 -0
- package/dist/dxt-entry.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-wordpress-1.5.1.tgz +0 -0
- package/dist/performance/MetricsCollector.d.ts.map +1 -1
- package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
- package/dist/performance/PerformanceAnalytics.js.map +1 -1
- package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
- package/dist/security/InputValidator.js.map +1 -1
- package/dist/security/SecurityConfig.d.ts.map +1 -1
- package/dist/server/ToolRegistry.js.map +1 -1
- package/dist/tools/cache.js +1 -1
- package/dist/tools/cache.js.map +1 -1
- package/dist/tools/performance.js.map +1 -1
- package/docs/developer/API_REFERENCE.md +97 -57
- package/docs/developer/ARCHITECTURE.md +7 -7
- package/docs/developer/BUILD_SYSTEM.md +8 -13
- package/docs/developer/CONTRIBUTING.md +29 -23
- package/docs/developer/DXT-DEBUG-BEST-PRACTICES.md +212 -0
- package/docs/developer/README.md +24 -1
- package/docs/developer/RELEASE_PROCESS.md +33 -28
- package/docs/developer/TESTING.md +122 -118
- package/docs/user-guides/DXT_INSTALLATION.md +149 -0
- package/package.json +4 -3
- package/src/cache/CacheInvalidation.ts +1 -1
- package/src/client/CachedWordPressClient.ts +15 -15
- package/src/client/api.ts +54 -47
- package/src/client/auth.ts +88 -88
- package/src/client/managers/AuthenticationManager.ts +112 -112
- package/src/client/managers/RequestManager.ts +1 -1
- package/src/config/ServerConfiguration.ts +39 -0
- package/src/docs/MarkdownFormatter.ts +4 -4
- package/src/dxt-entry.cjs +55 -0
- package/src/dxt-entry.ts +55 -0
- package/src/index.ts +55 -2
- package/src/performance/MetricsCollector.ts +3 -3
- package/src/performance/PerformanceAnalytics.ts +16 -16
- package/src/performance/PerformanceMonitor.ts +1 -1
- package/src/security/InputValidator.ts +4 -4
- package/src/security/SecurityConfig.ts +1 -1
- package/src/server/ToolRegistry.ts +12 -12
- package/src/tools/cache.ts +1 -1
- package/src/tools/performance.ts +17 -17
- package/dist/mcp-wordpress-1.4.0.tgz +0 -0
|
@@ -65,7 +65,7 @@ npm test
|
|
|
65
65
|
|
|
66
66
|
# Run specific test suites
|
|
67
67
|
npm run test:unit # Unit tests only
|
|
68
|
-
npm run test:integration # Integration tests only
|
|
68
|
+
npm run test:integration # Integration tests only
|
|
69
69
|
npm run test:security # Security tests only
|
|
70
70
|
npm run test:performance # Performance tests only
|
|
71
71
|
npm run test:cache # Cache tests only
|
|
@@ -106,23 +106,19 @@ npm run test:with-env # Tests with Docker WordPress
|
|
|
106
106
|
```javascript
|
|
107
107
|
// jest.config.js
|
|
108
108
|
module.exports = {
|
|
109
|
-
testEnvironment:
|
|
110
|
-
testMatch: [
|
|
111
|
-
collectCoverageFrom: [
|
|
112
|
-
'src/**/*.ts',
|
|
113
|
-
'!src/**/*.d.ts',
|
|
114
|
-
'!src/**/*.test.ts'
|
|
115
|
-
],
|
|
109
|
+
testEnvironment: "node",
|
|
110
|
+
testMatch: ["**/tests/**/*.test.js"],
|
|
111
|
+
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts", "!src/**/*.test.ts"],
|
|
116
112
|
coverageThreshold: {
|
|
117
113
|
global: {
|
|
118
114
|
branches: 50,
|
|
119
115
|
functions: 50,
|
|
120
116
|
lines: 50,
|
|
121
|
-
statements: 50
|
|
122
|
-
}
|
|
117
|
+
statements: 50,
|
|
118
|
+
},
|
|
123
119
|
},
|
|
124
|
-
setupFilesAfterEnv: [
|
|
125
|
-
testTimeout: 30000
|
|
120
|
+
setupFilesAfterEnv: ["<rootDir>/tests/setup.js"],
|
|
121
|
+
testTimeout: 30000,
|
|
126
122
|
};
|
|
127
123
|
```
|
|
128
124
|
|
|
@@ -130,24 +126,28 @@ module.exports = {
|
|
|
130
126
|
|
|
131
127
|
```javascript
|
|
132
128
|
// tests/setup.js
|
|
133
|
-
const { performance } = require(
|
|
129
|
+
const { performance } = require("perf_hooks");
|
|
134
130
|
|
|
135
131
|
// Global test utilities
|
|
136
132
|
global.testUtils = {
|
|
137
|
-
createMockClient: () => ({
|
|
138
|
-
|
|
133
|
+
createMockClient: () => ({
|
|
134
|
+
/* mock client */
|
|
135
|
+
}),
|
|
136
|
+
generateTestData: (schema) => ({
|
|
137
|
+
/* generated data */
|
|
138
|
+
}),
|
|
139
139
|
measurePerformance: (fn) => {
|
|
140
140
|
const start = performance.now();
|
|
141
141
|
const result = fn();
|
|
142
142
|
const duration = performance.now() - start;
|
|
143
143
|
return { result, duration };
|
|
144
|
-
}
|
|
144
|
+
},
|
|
145
145
|
};
|
|
146
146
|
|
|
147
147
|
// Setup test environment
|
|
148
148
|
beforeAll(() => {
|
|
149
|
-
process.env.NODE_ENV =
|
|
150
|
-
process.env.DEBUG =
|
|
149
|
+
process.env.NODE_ENV = "test";
|
|
150
|
+
process.env.DEBUG = "false";
|
|
151
151
|
});
|
|
152
152
|
|
|
153
153
|
afterAll(() => {
|
|
@@ -172,16 +172,16 @@ afterAll(() => {
|
|
|
172
172
|
|
|
173
173
|
```javascript
|
|
174
174
|
// tests/unit/security-utils.test.js
|
|
175
|
-
describe(
|
|
176
|
-
test(
|
|
175
|
+
describe("SecurityUtils", () => {
|
|
176
|
+
test("should sanitize input correctly", () => {
|
|
177
177
|
const input = '<script>alert("xss")</script>';
|
|
178
178
|
const sanitized = SecurityUtils.sanitizeInput(input);
|
|
179
|
-
expect(sanitized).not.toContain(
|
|
179
|
+
expect(sanitized).not.toContain("<script>");
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
-
test(
|
|
183
|
-
expect(SecurityUtils.isValidEmail(
|
|
184
|
-
expect(SecurityUtils.isValidEmail(
|
|
182
|
+
test("should validate email format", () => {
|
|
183
|
+
expect(SecurityUtils.isValidEmail("test@example.com")).toBe(true);
|
|
184
|
+
expect(SecurityUtils.isValidEmail("invalid-email")).toBe(false);
|
|
185
185
|
});
|
|
186
186
|
});
|
|
187
187
|
```
|
|
@@ -201,29 +201,29 @@ describe('SecurityUtils', () => {
|
|
|
201
201
|
|
|
202
202
|
```javascript
|
|
203
203
|
// tests/integration/wordpress-api.test.js
|
|
204
|
-
describe(
|
|
204
|
+
describe("WordPress API Integration", () => {
|
|
205
205
|
let client;
|
|
206
206
|
|
|
207
207
|
beforeAll(async () => {
|
|
208
208
|
client = new WordPressClient({
|
|
209
209
|
siteUrl: process.env.WORDPRESS_TEST_URL,
|
|
210
|
-
username:
|
|
211
|
-
appPassword:
|
|
210
|
+
username: "admin",
|
|
211
|
+
appPassword: "test test test test test test",
|
|
212
212
|
});
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
-
test(
|
|
215
|
+
test("should create and retrieve post", async () => {
|
|
216
216
|
const post = await client.posts.create({
|
|
217
|
-
title:
|
|
218
|
-
content:
|
|
219
|
-
status:
|
|
217
|
+
title: "Test Post",
|
|
218
|
+
content: "Test content",
|
|
219
|
+
status: "publish",
|
|
220
220
|
});
|
|
221
221
|
|
|
222
222
|
expect(post.id).toBeDefined();
|
|
223
|
-
expect(post.title).toBe(
|
|
223
|
+
expect(post.title).toBe("Test Post");
|
|
224
224
|
|
|
225
225
|
const retrieved = await client.posts.get({ id: post.id });
|
|
226
|
-
expect(retrieved.title).toBe(
|
|
226
|
+
expect(retrieved.title).toBe("Test Post");
|
|
227
227
|
});
|
|
228
228
|
});
|
|
229
229
|
```
|
|
@@ -244,23 +244,23 @@ describe('WordPress API Integration', () => {
|
|
|
244
244
|
|
|
245
245
|
```javascript
|
|
246
246
|
// tests/security/input-validation.test.js
|
|
247
|
-
describe(
|
|
248
|
-
test(
|
|
247
|
+
describe("Input Validation Security", () => {
|
|
248
|
+
test("should reject malicious script injection", () => {
|
|
249
249
|
const maliciousInput = {
|
|
250
250
|
title: '<script>alert("xss")</script>',
|
|
251
|
-
content: '"><script>alert("xss")</script>'
|
|
251
|
+
content: '"><script>alert("xss")</script>',
|
|
252
252
|
};
|
|
253
253
|
|
|
254
254
|
expect(() => {
|
|
255
255
|
createPostSchema.parse(maliciousInput);
|
|
256
|
-
}).toThrow(
|
|
256
|
+
}).toThrow("Invalid input");
|
|
257
257
|
});
|
|
258
258
|
|
|
259
|
-
test(
|
|
259
|
+
test("should prevent SQL injection in search", () => {
|
|
260
260
|
const sqlInjection = "'; DROP TABLE posts; --";
|
|
261
261
|
expect(() => {
|
|
262
262
|
searchSchema.parse({ query: sqlInjection });
|
|
263
|
-
}).toThrow(
|
|
263
|
+
}).toThrow("Invalid characters");
|
|
264
264
|
});
|
|
265
265
|
});
|
|
266
266
|
```
|
|
@@ -280,24 +280,24 @@ describe('Input Validation Security', () => {
|
|
|
280
280
|
|
|
281
281
|
```javascript
|
|
282
282
|
// tests/performance/benchmarks.test.js
|
|
283
|
-
describe(
|
|
284
|
-
test(
|
|
283
|
+
describe("Performance Benchmarks", () => {
|
|
284
|
+
test("should handle post creation under 500ms", async () => {
|
|
285
285
|
const start = performance.now();
|
|
286
|
-
|
|
286
|
+
|
|
287
287
|
await client.posts.create({
|
|
288
|
-
title:
|
|
289
|
-
content:
|
|
288
|
+
title: "Performance Test",
|
|
289
|
+
content: "Test content",
|
|
290
290
|
});
|
|
291
|
-
|
|
291
|
+
|
|
292
292
|
const duration = performance.now() - start;
|
|
293
293
|
expect(duration).toBeLessThan(500);
|
|
294
294
|
});
|
|
295
295
|
|
|
296
|
-
test(
|
|
296
|
+
test("should maintain cache hit rate above 70%", async () => {
|
|
297
297
|
// Warm cache
|
|
298
298
|
await client.posts.list();
|
|
299
299
|
await client.posts.list();
|
|
300
|
-
|
|
300
|
+
|
|
301
301
|
const stats = await client.cache.getStats();
|
|
302
302
|
expect(stats.hitRate).toBeGreaterThan(0.7);
|
|
303
303
|
});
|
|
@@ -319,39 +319,39 @@ describe('Performance Benchmarks', () => {
|
|
|
319
319
|
|
|
320
320
|
```javascript
|
|
321
321
|
// tests/cache/cache-functionality.test.js
|
|
322
|
-
describe(
|
|
323
|
-
test(
|
|
322
|
+
describe("Cache Functionality", () => {
|
|
323
|
+
test("should cache GET requests", async () => {
|
|
324
324
|
const client = new CachedWordPressClient(config);
|
|
325
|
-
|
|
325
|
+
|
|
326
326
|
// First request - cache miss
|
|
327
327
|
const start1 = performance.now();
|
|
328
328
|
const posts1 = await client.posts.list();
|
|
329
329
|
const duration1 = performance.now() - start1;
|
|
330
|
-
|
|
330
|
+
|
|
331
331
|
// Second request - cache hit
|
|
332
332
|
const start2 = performance.now();
|
|
333
333
|
const posts2 = await client.posts.list();
|
|
334
334
|
const duration2 = performance.now() - start2;
|
|
335
|
-
|
|
335
|
+
|
|
336
336
|
expect(posts1).toEqual(posts2);
|
|
337
337
|
expect(duration2).toBeLessThan(duration1 * 0.1); // 90% faster
|
|
338
338
|
});
|
|
339
339
|
|
|
340
|
-
test(
|
|
340
|
+
test("should invalidate cache on updates", async () => {
|
|
341
341
|
const client = new CachedWordPressClient(config);
|
|
342
|
-
|
|
342
|
+
|
|
343
343
|
// Cache posts list
|
|
344
344
|
await client.posts.list();
|
|
345
|
-
|
|
345
|
+
|
|
346
346
|
// Create new post
|
|
347
347
|
await client.posts.create({
|
|
348
|
-
title:
|
|
349
|
-
content:
|
|
348
|
+
title: "New Post",
|
|
349
|
+
content: "Content",
|
|
350
350
|
});
|
|
351
|
-
|
|
351
|
+
|
|
352
352
|
// List should be refreshed
|
|
353
353
|
const posts = await client.posts.list();
|
|
354
|
-
expect(posts.some(p => p.title ===
|
|
354
|
+
expect(posts.some((p) => p.title === "New Post")).toBe(true);
|
|
355
355
|
});
|
|
356
356
|
});
|
|
357
357
|
```
|
|
@@ -371,22 +371,24 @@ describe('Cache Functionality', () => {
|
|
|
371
371
|
|
|
372
372
|
```javascript
|
|
373
373
|
// tests/property/data-structure.test.js
|
|
374
|
-
const fc = require(
|
|
375
|
-
|
|
376
|
-
describe(
|
|
377
|
-
test(
|
|
378
|
-
fc.assert(
|
|
379
|
-
fc.
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
374
|
+
const fc = require("fast-check");
|
|
375
|
+
|
|
376
|
+
describe("Property-Based Testing", () => {
|
|
377
|
+
test("should handle any valid post data", () => {
|
|
378
|
+
fc.assert(
|
|
379
|
+
fc.property(
|
|
380
|
+
fc.record({
|
|
381
|
+
title: fc.string({ minLength: 1, maxLength: 200 }),
|
|
382
|
+
content: fc.string(),
|
|
383
|
+
status: fc.constantFrom("draft", "publish", "private"),
|
|
384
|
+
}),
|
|
385
|
+
async (postData) => {
|
|
386
|
+
const result = await client.posts.create(postData);
|
|
387
|
+
expect(result.title).toBe(postData.title);
|
|
388
|
+
expect(result.status).toBe(postData.status);
|
|
389
|
+
},
|
|
390
|
+
),
|
|
391
|
+
);
|
|
390
392
|
});
|
|
391
393
|
});
|
|
392
394
|
```
|
|
@@ -406,20 +408,20 @@ describe('Property-Based Testing', () => {
|
|
|
406
408
|
|
|
407
409
|
```javascript
|
|
408
410
|
// tests/config/schema-validation.test.js
|
|
409
|
-
describe(
|
|
410
|
-
test(
|
|
411
|
+
describe("Configuration Schema Validation", () => {
|
|
412
|
+
test("should validate multi-site configuration", () => {
|
|
411
413
|
const validConfig = {
|
|
412
414
|
sites: [
|
|
413
415
|
{
|
|
414
|
-
id:
|
|
415
|
-
name:
|
|
416
|
+
id: "site1",
|
|
417
|
+
name: "Test Site",
|
|
416
418
|
config: {
|
|
417
|
-
WORDPRESS_SITE_URL:
|
|
418
|
-
WORDPRESS_USERNAME:
|
|
419
|
-
WORDPRESS_APP_PASSWORD:
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
]
|
|
419
|
+
WORDPRESS_SITE_URL: "https://example.com",
|
|
420
|
+
WORDPRESS_USERNAME: "admin",
|
|
421
|
+
WORDPRESS_APP_PASSWORD: "test test test test test test",
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
],
|
|
423
425
|
};
|
|
424
426
|
|
|
425
427
|
expect(() => {
|
|
@@ -427,22 +429,24 @@ describe('Configuration Schema Validation', () => {
|
|
|
427
429
|
}).not.toThrow();
|
|
428
430
|
});
|
|
429
431
|
|
|
430
|
-
test(
|
|
432
|
+
test("should reject invalid site URLs", () => {
|
|
431
433
|
const invalidConfig = {
|
|
432
|
-
sites: [
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
434
|
+
sites: [
|
|
435
|
+
{
|
|
436
|
+
id: "site1",
|
|
437
|
+
name: "Test Site",
|
|
438
|
+
config: {
|
|
439
|
+
WORDPRESS_SITE_URL: "invalid-url",
|
|
440
|
+
WORDPRESS_USERNAME: "admin",
|
|
441
|
+
WORDPRESS_APP_PASSWORD: "password",
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
],
|
|
441
445
|
};
|
|
442
446
|
|
|
443
447
|
expect(() => {
|
|
444
448
|
multiSiteConfigSchema.parse(invalidConfig);
|
|
445
|
-
}).toThrow(
|
|
449
|
+
}).toThrow("Invalid URL");
|
|
446
450
|
});
|
|
447
451
|
});
|
|
448
452
|
```
|
|
@@ -466,7 +470,7 @@ describe('Configuration Schema Validation', () => {
|
|
|
466
470
|
|
|
467
471
|
```yaml
|
|
468
472
|
# docker-compose.test.yml
|
|
469
|
-
version:
|
|
473
|
+
version: "3.8"
|
|
470
474
|
services:
|
|
471
475
|
wordpress:
|
|
472
476
|
image: wordpress:latest
|
|
@@ -481,7 +485,7 @@ services:
|
|
|
481
485
|
- db
|
|
482
486
|
volumes:
|
|
483
487
|
- ./tests/wordpress-config.php:/var/www/html/wp-config.php
|
|
484
|
-
|
|
488
|
+
|
|
485
489
|
db:
|
|
486
490
|
image: mysql:8.0
|
|
487
491
|
environment:
|
|
@@ -592,7 +596,7 @@ jobs:
|
|
|
592
596
|
|
|
593
597
|
```javascript
|
|
594
598
|
// Standard test structure
|
|
595
|
-
describe(
|
|
599
|
+
describe("Component Name", () => {
|
|
596
600
|
// Setup
|
|
597
601
|
beforeAll(() => {
|
|
598
602
|
// One-time setup
|
|
@@ -603,16 +607,16 @@ describe('Component Name', () => {
|
|
|
603
607
|
});
|
|
604
608
|
|
|
605
609
|
// Test cases
|
|
606
|
-
describe(
|
|
607
|
-
test(
|
|
610
|
+
describe("method name", () => {
|
|
611
|
+
test("should do something specific", () => {
|
|
608
612
|
// Arrange
|
|
609
|
-
const input =
|
|
610
|
-
|
|
613
|
+
const input = "test data";
|
|
614
|
+
|
|
611
615
|
// Act
|
|
612
616
|
const result = component.method(input);
|
|
613
|
-
|
|
617
|
+
|
|
614
618
|
// Assert
|
|
615
|
-
expect(result).toBe(
|
|
619
|
+
expect(result).toBe("expected output");
|
|
616
620
|
});
|
|
617
621
|
});
|
|
618
622
|
|
|
@@ -646,18 +650,18 @@ export const mockWordPressClient = {
|
|
|
646
650
|
update: jest.fn(),
|
|
647
651
|
delete: jest.fn(),
|
|
648
652
|
get: jest.fn(),
|
|
649
|
-
list: jest.fn()
|
|
653
|
+
list: jest.fn(),
|
|
650
654
|
},
|
|
651
655
|
auth: {
|
|
652
656
|
authenticate: jest.fn(),
|
|
653
|
-
getAuthHeaders: jest.fn()
|
|
654
|
-
}
|
|
657
|
+
getAuthHeaders: jest.fn(),
|
|
658
|
+
},
|
|
655
659
|
};
|
|
656
660
|
|
|
657
661
|
export const mockConfig = {
|
|
658
|
-
siteUrl:
|
|
659
|
-
username:
|
|
660
|
-
appPassword:
|
|
662
|
+
siteUrl: "https://test.example.com",
|
|
663
|
+
username: "testuser",
|
|
664
|
+
appPassword: "test test test test test test",
|
|
661
665
|
};
|
|
662
666
|
```
|
|
663
667
|
|
|
@@ -703,15 +707,15 @@ node --inspect-brk ./node_modules/.bin/jest --runInBand
|
|
|
703
707
|
|
|
704
708
|
```javascript
|
|
705
709
|
// Debug utility functions
|
|
706
|
-
const debug = require(
|
|
710
|
+
const debug = require("debug")("test:debug");
|
|
711
|
+
|
|
712
|
+
describe("Debug Example", () => {
|
|
713
|
+
test("should debug test execution", () => {
|
|
714
|
+
debug("Starting test execution");
|
|
707
715
|
|
|
708
|
-
describe('Debug Example', () => {
|
|
709
|
-
test('should debug test execution', () => {
|
|
710
|
-
debug('Starting test execution');
|
|
711
|
-
|
|
712
716
|
const result = someFunction();
|
|
713
|
-
debug(
|
|
714
|
-
|
|
717
|
+
debug("Function result:", result);
|
|
718
|
+
|
|
715
719
|
expect(result).toBeDefined();
|
|
716
720
|
});
|
|
717
721
|
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# DXT Installation Guide
|
|
2
|
+
|
|
3
|
+
This guide walks you through installing the WordPress MCP Server as a Claude Desktop Extension (DXT).
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Claude Desktop application installed
|
|
8
|
+
- WordPress site with admin access
|
|
9
|
+
- WordPress Application Password (recommended)
|
|
10
|
+
|
|
11
|
+
## Installation Steps
|
|
12
|
+
|
|
13
|
+
### 1. Download or Build the DXT Package
|
|
14
|
+
|
|
15
|
+
**Option A: Download Pre-built Package**
|
|
16
|
+
|
|
17
|
+
- Download `mcp-wordpress.dxt` from the releases page
|
|
18
|
+
- Skip to step 2
|
|
19
|
+
|
|
20
|
+
**Option B: Build from Source**
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Install the official DXT CLI tool
|
|
24
|
+
npm install -g @anthropic-ai/dxt
|
|
25
|
+
|
|
26
|
+
# Build the DXT package
|
|
27
|
+
npm run dxt:package:official
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Install in Claude Desktop
|
|
31
|
+
|
|
32
|
+
1. Open Claude Desktop
|
|
33
|
+
2. Navigate to **Extensions** menu
|
|
34
|
+
3. Click **Install Extension**
|
|
35
|
+
4. Select the `mcp-wordpress.dxt` file
|
|
36
|
+
5. Click **Install**
|
|
37
|
+
|
|
38
|
+
### 3. Configure WordPress Credentials
|
|
39
|
+
|
|
40
|
+
After installation, you'll be prompted to configure:
|
|
41
|
+
|
|
42
|
+
#### Required Fields
|
|
43
|
+
|
|
44
|
+
- **WordPress Site URL**: Your site's full URL (e.g., `https://yoursite.com`)
|
|
45
|
+
- **WordPress Username**: Your WordPress admin username
|
|
46
|
+
- **WordPress Application Password**: Generate this in WordPress Admin
|
|
47
|
+
|
|
48
|
+
#### Optional Fields
|
|
49
|
+
|
|
50
|
+
- **Authentication Method**: Default is "app-password" (recommended)
|
|
51
|
+
- **Debug Mode**: Enable for troubleshooting (default: false)
|
|
52
|
+
|
|
53
|
+
#### Generating Application Password
|
|
54
|
+
|
|
55
|
+
1. Go to WordPress Admin → Users → Your Profile
|
|
56
|
+
2. Scroll to "Application Passwords" section
|
|
57
|
+
3. Enter a name (e.g., "Claude Desktop")
|
|
58
|
+
4. Click "Add New Application Password"
|
|
59
|
+
5. Copy the generated password (format: `xxxx xxxx xxxx xxxx xxxx xxxx`)
|
|
60
|
+
6. Use this password in the DXT configuration
|
|
61
|
+
|
|
62
|
+
### 4. Verify Installation
|
|
63
|
+
|
|
64
|
+
After configuration, the extension should appear in your Claude Desktop extensions list. You can test it by
|
|
65
|
+
asking Claude to:
|
|
66
|
+
|
|
67
|
+
- "List my recent WordPress posts"
|
|
68
|
+
- "Check my WordPress site status"
|
|
69
|
+
- "Show available WordPress tools"
|
|
70
|
+
|
|
71
|
+
## Troubleshooting
|
|
72
|
+
|
|
73
|
+
### Installation Fails
|
|
74
|
+
|
|
75
|
+
- Ensure you're using the official DXT package built with the DXT CLI tool
|
|
76
|
+
- Check that all required files are included in the package
|
|
77
|
+
- Verify Claude Desktop is up to date
|
|
78
|
+
|
|
79
|
+
### Server Crashes After Installation
|
|
80
|
+
|
|
81
|
+
- **Entry Point Issues**: Ensure manifest.json points to correct entry_point (`dist/index.js`)
|
|
82
|
+
- **Path Resolution**: Use `${__dirname}/dist/index.js` in mcp_config.args for absolute paths
|
|
83
|
+
- **Missing Dependencies**: Verify node_modules are included in the DXT package
|
|
84
|
+
- **Configuration Issues**: Check that user configuration fields are properly filled
|
|
85
|
+
|
|
86
|
+
### Authentication Issues
|
|
87
|
+
|
|
88
|
+
- Ensure Application Password is correctly formatted (spaces between groups)
|
|
89
|
+
- Verify WordPress REST API is enabled
|
|
90
|
+
- Check that your user has appropriate permissions
|
|
91
|
+
|
|
92
|
+
### Connection Problems
|
|
93
|
+
|
|
94
|
+
- Verify WordPress site URL is correct and accessible
|
|
95
|
+
- Check for SSL certificate issues
|
|
96
|
+
- Ensure WordPress REST API endpoints are not blocked
|
|
97
|
+
|
|
98
|
+
## Build Process Details
|
|
99
|
+
|
|
100
|
+
The DXT package is built using the official Anthropic DXT CLI tool to ensure compatibility:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Clean previous builds
|
|
104
|
+
npm run dxt:clean
|
|
105
|
+
|
|
106
|
+
# Install DXT CLI if not already installed
|
|
107
|
+
npm install -g @anthropic-ai/dxt
|
|
108
|
+
|
|
109
|
+
# Copy manifest and icon to root (required by DXT CLI)
|
|
110
|
+
cp dxt/manifest.json .
|
|
111
|
+
cp dxt/icon.png .
|
|
112
|
+
|
|
113
|
+
# Create .dxtignore to exclude development files
|
|
114
|
+
# (See .dxtignore file for exclusion patterns)
|
|
115
|
+
|
|
116
|
+
# Build with official DXT tool
|
|
117
|
+
dxt pack . mcp-wordpress.dxt
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Key Requirements for DXT Packaging
|
|
121
|
+
|
|
122
|
+
1. **Use Official DXT CLI**: The `dxt pack` command ensures proper package structure
|
|
123
|
+
2. **Proper .dxtignore**: Exclude development files, tests, and unnecessary dependencies
|
|
124
|
+
3. **Root-level manifest.json**: DXT CLI expects manifest at project root
|
|
125
|
+
4. **Include node_modules**: Production dependencies must be included
|
|
126
|
+
5. **Compiled Code**: Include `dist/` directory with compiled TypeScript
|
|
127
|
+
|
|
128
|
+
## Package Contents
|
|
129
|
+
|
|
130
|
+
The final DXT package includes:
|
|
131
|
+
|
|
132
|
+
- `manifest.json` - Extension metadata and configuration
|
|
133
|
+
- `icon.png` - Extension icon
|
|
134
|
+
- `dist/` - Compiled TypeScript code
|
|
135
|
+
- `node_modules/` - Production dependencies (filtered)
|
|
136
|
+
- `package.json` - Node.js package configuration
|
|
137
|
+
- `LICENSE` - License file
|
|
138
|
+
|
|
139
|
+
## Security Notes
|
|
140
|
+
|
|
141
|
+
- Application Passwords are stored securely by Claude Desktop
|
|
142
|
+
- Never commit `mcp-wordpress.config.json` containing credentials
|
|
143
|
+
- Use `.gitignore` to exclude sensitive configuration files
|
|
144
|
+
- Rotate Application Passwords if accidentally exposed
|
|
145
|
+
|
|
146
|
+
## Multi-Site Support
|
|
147
|
+
|
|
148
|
+
The DXT extension supports managing multiple WordPress sites. Configure additional sites through the extension
|
|
149
|
+
settings or use site-specific commands with the `--site` parameter.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-wordpress",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Comprehensive Model Context Protocol server for WordPress management with 59 tools, performance monitoring, intelligent caching, auto-generated documentation, Docker support, TypeScript, and production-ready authentication",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -50,8 +50,9 @@
|
|
|
50
50
|
"docs:validate": "npm run docs:generate && node scripts/validate-docs.js",
|
|
51
51
|
"docs:watch": "npm run docs:generate && echo 'Watching for changes...' && npm run docs:serve",
|
|
52
52
|
"dxt:build": "node scripts/build-dxt.js",
|
|
53
|
-
"dxt:clean": "rm -rf dxt-build mcp-wordpress.dxt",
|
|
53
|
+
"dxt:clean": "rm -rf dxt-build mcp-wordpress.dxt minimal-dxt-build mcp-wordpress-minimal.dxt mcp-wordpress-official.dxt",
|
|
54
54
|
"dxt:package": "npm run dxt:clean && npm run dxt:build",
|
|
55
|
+
"dxt:package:official": "npm run build && npm run dxt:clean && cp dxt/manifest.json . && cp dxt/icon.png . && dxt pack . mcp-wordpress.dxt && rm manifest.json icon.png",
|
|
55
56
|
"dxt:validate": "echo '✅ DXT package validation - Basic validation performed during build'",
|
|
56
57
|
"fix:rest-auth": "bash scripts/fix-rest-api-auth.sh",
|
|
57
58
|
"format": "prettier --write *.md docs/**/*.md src/**/*.ts tests/**/*.ts",
|
|
@@ -116,7 +117,6 @@
|
|
|
116
117
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
117
118
|
"dotenv": "^16.3.1",
|
|
118
119
|
"form-data": "^4.0.0",
|
|
119
|
-
"node-fetch": "^3.3.2",
|
|
120
120
|
"zod": "^3.25.67"
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
|
@@ -132,6 +132,7 @@
|
|
|
132
132
|
"archiver": "^7.0.1",
|
|
133
133
|
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
134
134
|
"eslint": "^9.29.0",
|
|
135
|
+
"eslint-config-prettier": "^10.1.5",
|
|
135
136
|
"eslint-plugin-jest": "^29.0.1",
|
|
136
137
|
"eslint-plugin-node": "^11.1.0",
|
|
137
138
|
"fast-check": "^4.1.1",
|