mcp-wordpress 1.1.2 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +8 -8
  2. package/bin/mcp-wordpress.js +1 -1
  3. package/dist/client/api.d.ts +10 -10
  4. package/dist/client/api.js +157 -157
  5. package/dist/client/api.js.map +1 -1
  6. package/dist/client/auth.d.ts +2 -2
  7. package/dist/client/auth.d.ts.map +1 -1
  8. package/dist/client/auth.js +72 -72
  9. package/dist/client/auth.js.map +1 -1
  10. package/dist/client/managers/AuthenticationManager.d.ts +2 -2
  11. package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
  12. package/dist/client/managers/AuthenticationManager.js +50 -46
  13. package/dist/client/managers/AuthenticationManager.js.map +1 -1
  14. package/dist/client/managers/BaseManager.d.ts +1 -1
  15. package/dist/client/managers/BaseManager.d.ts.map +1 -1
  16. package/dist/client/managers/BaseManager.js +9 -9
  17. package/dist/client/managers/BaseManager.js.map +1 -1
  18. package/dist/client/managers/RequestManager.d.ts +2 -2
  19. package/dist/client/managers/RequestManager.js +15 -15
  20. package/dist/client/managers/index.d.ts +3 -3
  21. package/dist/client/managers/index.js +3 -3
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +78 -61
  24. package/dist/index.js.map +1 -1
  25. package/dist/tools/auth.d.ts +2 -2
  26. package/dist/tools/auth.js +31 -31
  27. package/dist/tools/auth.js.map +1 -1
  28. package/dist/tools/comments.d.ts +2 -2
  29. package/dist/tools/comments.js +79 -79
  30. package/dist/tools/media.d.ts +2 -2
  31. package/dist/tools/media.d.ts.map +1 -1
  32. package/dist/tools/media.js +80 -80
  33. package/dist/tools/media.js.map +1 -1
  34. package/dist/tools/pages.d.ts +2 -2
  35. package/dist/tools/pages.js +75 -75
  36. package/dist/tools/posts.d.ts +2 -2
  37. package/dist/tools/posts.js +94 -94
  38. package/dist/tools/site.d.ts +2 -2
  39. package/dist/tools/site.js +60 -60
  40. package/dist/tools/site.js.map +1 -1
  41. package/dist/tools/taxonomies.d.ts +2 -2
  42. package/dist/tools/taxonomies.js +89 -89
  43. package/dist/tools/users.d.ts +2 -2
  44. package/dist/tools/users.js +68 -68
  45. package/dist/tools/users.js.map +1 -1
  46. package/dist/types/mcp.d.ts +1 -1
  47. package/dist/types/mcp.d.ts.map +1 -1
  48. package/dist/utils/debug.d.ts.map +1 -1
  49. package/dist/utils/debug.js +10 -6
  50. package/dist/utils/debug.js.map +1 -1
  51. package/dist/utils/toolWrapper.js +3 -3
  52. package/docs/developer/GITHUB_ACTIONS_SETUP.md +208 -0
  53. package/docs/developer/MAINTENANCE.md +307 -0
  54. package/docs/developer/MIGRATION_GUIDE.md +172 -0
  55. package/docs/developer/NPM_AUTH_SETUP.md +142 -0
  56. package/docs/developer/REFACTORING.md +196 -0
  57. package/docs/releases/COMMUNITY_ANNOUNCEMENT_v1.1.2.md +126 -0
  58. package/docs/releases/RELEASE_NOTES_v1.1.2.md +173 -0
  59. package/docs/user-guides/CLAUDE_DESKTOP_SETUP.md +187 -0
  60. package/package.json +4 -3
  61. package/src/client/api.ts +229 -229
  62. package/src/client/auth.ts +135 -136
  63. package/src/client/managers/AuthenticationManager.ts +148 -105
  64. package/src/client/managers/BaseManager.ts +15 -12
  65. package/src/client/managers/RequestManager.ts +17 -17
  66. package/src/client/managers/index.ts +3 -3
  67. package/src/index.ts +141 -114
  68. package/src/server.ts +1 -1
  69. package/src/tools/auth.ts +36 -36
  70. package/src/tools/comments.ts +90 -90
  71. package/src/tools/media.ts +89 -91
  72. package/src/tools/pages.ts +86 -86
  73. package/src/tools/posts.ts +106 -106
  74. package/src/tools/site.ts +71 -71
  75. package/src/tools/taxonomies.ts +102 -102
  76. package/src/tools/users.ts +77 -77
  77. package/src/types/client.ts +1 -1
  78. package/src/types/index.ts +1 -1
  79. package/src/types/mcp.ts +36 -16
  80. package/src/types/wordpress.ts +1 -1
  81. package/src/utils/debug.ts +63 -39
  82. package/src/utils/error.ts +1 -1
  83. package/src/utils/toolWrapper.ts +4 -4
  84. package/dist/client/WordPressClient.d.ts +0 -81
  85. package/dist/client/WordPressClient.d.ts.map +0 -1
  86. package/dist/client/WordPressClient.js +0 -354
  87. package/dist/client/WordPressClient.js.map +0 -1
  88. package/dist/tools/base.d.ts +0 -37
  89. package/dist/tools/base.d.ts.map +0 -1
  90. package/dist/tools/base.js +0 -60
  91. package/dist/tools/base.js.map +0 -1
@@ -3,10 +3,10 @@
3
3
  * Handles all authentication methods and token management
4
4
  */
5
5
 
6
- import type { AuthConfig, AuthMethod } from "../../types/client.js";
7
- import { AuthenticationError } from "../../types/client.js";
8
- import { BaseManager } from "./BaseManager.js";
9
- import { debug } from "../../utils/debug.js";
6
+ import type { AuthConfig, AuthMethod } from '../../types/client.js';
7
+ import { AuthenticationError } from '../../types/client.js';
8
+ import { BaseManager } from './BaseManager.js';
9
+ import { debug } from '../../utils/debug.js';
10
10
 
11
11
  export class AuthenticationManager extends BaseManager {
12
12
  private jwtToken: string | null = null;
@@ -16,40 +16,46 @@ 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 =
20
+ (process.env.WORDPRESS_AUTH_METHOD as AuthMethod) || 'app-password';
21
21
 
22
22
  switch (method) {
23
- case "app-password":
24
- return {
25
- method: "app-password",
26
- username: process.env.WORDPRESS_USERNAME || "",
27
- appPassword: process.env.WORDPRESS_APP_PASSWORD || "",
28
- };
29
-
30
- case "jwt":
31
- return {
32
- method: "jwt",
33
- username: process.env.WORDPRESS_USERNAME || "",
34
- password: process.env.WORDPRESS_JWT_PASSWORD || process.env.WORDPRESS_PASSWORD || "",
35
- secret: process.env.WORDPRESS_JWT_SECRET || "",
36
- };
37
-
38
- case "basic":
39
- return {
40
- method: "basic",
41
- username: process.env.WORDPRESS_USERNAME || "",
42
- password: process.env.WORDPRESS_PASSWORD || "",
43
- };
44
-
45
- case "api-key":
46
- return {
47
- method: "api-key",
48
- apiKey: process.env.WORDPRESS_API_KEY || "",
49
- };
50
-
51
- default:
52
- throw new AuthenticationError(`Unsupported authentication method: ${method}`, method);
23
+ case 'app-password':
24
+ return {
25
+ method: 'app-password',
26
+ username: process.env.WORDPRESS_USERNAME || '',
27
+ appPassword: process.env.WORDPRESS_APP_PASSWORD || ''
28
+ };
29
+
30
+ case 'jwt':
31
+ return {
32
+ method: 'jwt',
33
+ username: process.env.WORDPRESS_USERNAME || '',
34
+ password:
35
+ process.env.WORDPRESS_JWT_PASSWORD ||
36
+ process.env.WORDPRESS_PASSWORD ||
37
+ '',
38
+ secret: process.env.WORDPRESS_JWT_SECRET || ''
39
+ };
40
+
41
+ case 'basic':
42
+ return {
43
+ method: 'basic',
44
+ username: process.env.WORDPRESS_USERNAME || '',
45
+ password: process.env.WORDPRESS_PASSWORD || ''
46
+ };
47
+
48
+ case 'api-key':
49
+ return {
50
+ method: 'api-key',
51
+ apiKey: process.env.WORDPRESS_API_KEY || ''
52
+ };
53
+
54
+ default:
55
+ throw new AuthenticationError(
56
+ `Unsupported authentication method: ${method}`,
57
+ method
58
+ );
53
59
  }
54
60
  }
55
61
 
@@ -60,36 +66,49 @@ export class AuthenticationManager extends BaseManager {
60
66
  const auth = this.config.auth;
61
67
 
62
68
  switch (auth.method) {
63
- case "app-password":
64
- if (!auth.username || !auth.appPassword) {
65
- throw new AuthenticationError("Username and app password are required", auth.method);
66
- }
67
-
68
- const credentials = Buffer.from(`${auth.username}:${auth.appPassword}`).toString("base64");
69
- return { Authorization: `Basic ${credentials}` };
70
-
71
- case "jwt":
72
- if (!this.jwtToken) {
73
- await this.authenticateJWT();
74
- }
75
- return { Authorization: `Bearer ${this.jwtToken}` };
76
-
77
- case "basic":
78
- if (!auth.username || !auth.password) {
79
- throw new AuthenticationError("Username and password are required", auth.method);
80
- }
81
-
82
- const basicCredentials = Buffer.from(`${auth.username}:${auth.password}`).toString("base64");
83
- return { Authorization: `Basic ${basicCredentials}` };
84
-
85
- case "api-key":
86
- if (!auth.apiKey) {
87
- throw new AuthenticationError("API key is required", auth.method);
88
- }
89
- return { "X-API-Key": auth.apiKey };
90
-
91
- default:
92
- throw new AuthenticationError(`Unsupported authentication method: ${auth.method}`, auth.method);
69
+ case 'app-password':
70
+ if (!auth.username || !auth.appPassword) {
71
+ throw new AuthenticationError(
72
+ 'Username and app password are required',
73
+ auth.method
74
+ );
75
+ }
76
+
77
+ const credentials = Buffer.from(
78
+ `${auth.username}:${auth.appPassword}`
79
+ ).toString('base64');
80
+ return { Authorization: `Basic ${credentials}` };
81
+
82
+ case 'jwt':
83
+ if (!this.jwtToken) {
84
+ await this.authenticateJWT();
85
+ }
86
+ return { Authorization: `Bearer ${this.jwtToken}` };
87
+
88
+ case 'basic':
89
+ if (!auth.username || !auth.password) {
90
+ throw new AuthenticationError(
91
+ 'Username and password are required',
92
+ auth.method
93
+ );
94
+ }
95
+
96
+ const basicCredentials = Buffer.from(
97
+ `${auth.username}:${auth.password}`
98
+ ).toString('base64');
99
+ return { Authorization: `Basic ${basicCredentials}` };
100
+
101
+ case 'api-key':
102
+ if (!auth.apiKey) {
103
+ throw new AuthenticationError('API key is required', auth.method);
104
+ }
105
+ return { 'X-API-Key': auth.apiKey };
106
+
107
+ default:
108
+ throw new AuthenticationError(
109
+ `Unsupported authentication method: ${auth.method}`,
110
+ auth.method
111
+ );
93
112
  }
94
113
  }
95
114
 
@@ -98,18 +117,23 @@ export class AuthenticationManager extends BaseManager {
98
117
  */
99
118
  private async authenticateJWT(): Promise<void> {
100
119
  const auth = this.config.auth;
101
-
102
- if (auth.method !== "jwt" || !auth.username || !auth.password) {
103
- throw new AuthenticationError("JWT authentication requires username and password", "jwt");
120
+
121
+ if (auth.method !== 'jwt' || !auth.username || !auth.password) {
122
+ throw new AuthenticationError(
123
+ 'JWT authentication requires username and password',
124
+ 'jwt'
125
+ );
104
126
  }
105
127
 
106
128
  try {
107
129
  // This would need the RequestManager instance to make the request
108
130
  // For now, we'll throw an error indicating this needs to be implemented
109
- throw new AuthenticationError("JWT authentication requires RequestManager integration", "jwt");
110
-
131
+ throw new AuthenticationError(
132
+ 'JWT authentication requires RequestManager integration',
133
+ 'jwt'
134
+ );
111
135
  } catch (error) {
112
- this.handleError(error, "JWT authentication");
136
+ this.handleError(error, 'JWT authentication');
113
137
  }
114
138
  }
115
139
 
@@ -118,17 +142,18 @@ export class AuthenticationManager extends BaseManager {
118
142
  */
119
143
  async testAuthentication(): Promise<boolean> {
120
144
  try {
121
- const headers = await this.getAuthHeaders();
122
- debug.log("Authentication headers prepared", { method: this.config.auth.method });
123
-
145
+ const _headers = await this.getAuthHeaders();
146
+ debug.log('Authentication headers prepared', {
147
+ method: this.config.auth.method
148
+ });
149
+
124
150
  // This would need the RequestManager to actually test the connection
125
151
  // For now, we'll return true if headers can be generated
126
152
  this.authenticated = true;
127
153
  return true;
128
-
129
154
  } catch (error) {
130
155
  this.authenticated = false;
131
- debug.log("Authentication test failed", error);
156
+ debug.log('Authentication test failed', error);
132
157
  return false;
133
158
  }
134
159
  }
@@ -155,36 +180,54 @@ export class AuthenticationManager extends BaseManager {
155
180
  const auth = this.config.auth;
156
181
 
157
182
  if (!auth.method) {
158
- throw new AuthenticationError("Authentication method is required", "app-password");
183
+ throw new AuthenticationError(
184
+ 'Authentication method is required',
185
+ 'app-password'
186
+ );
159
187
  }
160
188
 
161
189
  switch (auth.method) {
162
- case "app-password":
163
- if (!auth.username || !auth.appPassword) {
164
- throw new AuthenticationError("App password authentication requires username and appPassword", "app-password");
165
- }
166
- break;
167
-
168
- case "jwt":
169
- if (!auth.username || !auth.password || !auth.secret) {
170
- throw new AuthenticationError("JWT authentication requires username, password, and secret", "jwt");
171
- }
172
- break;
173
-
174
- case "basic":
175
- if (!auth.username || !auth.password) {
176
- throw new AuthenticationError("Basic authentication requires username and password", "basic");
177
- }
178
- break;
179
-
180
- case "api-key":
181
- if (!auth.apiKey) {
182
- throw new AuthenticationError("API key authentication requires apiKey", "api-key");
183
- }
184
- break;
185
-
186
- default:
187
- throw new AuthenticationError(`Unsupported authentication method: ${auth.method}`, auth.method);
190
+ case 'app-password':
191
+ if (!auth.username || !auth.appPassword) {
192
+ throw new AuthenticationError(
193
+ 'App password authentication requires username and appPassword',
194
+ 'app-password'
195
+ );
196
+ }
197
+ break;
198
+
199
+ case 'jwt':
200
+ if (!auth.username || !auth.password || !auth.secret) {
201
+ throw new AuthenticationError(
202
+ 'JWT authentication requires username, password, and secret',
203
+ 'jwt'
204
+ );
205
+ }
206
+ break;
207
+
208
+ case 'basic':
209
+ if (!auth.username || !auth.password) {
210
+ throw new AuthenticationError(
211
+ 'Basic authentication requires username and password',
212
+ 'basic'
213
+ );
214
+ }
215
+ break;
216
+
217
+ case 'api-key':
218
+ if (!auth.apiKey) {
219
+ throw new AuthenticationError(
220
+ 'API key authentication requires apiKey',
221
+ 'api-key'
222
+ );
223
+ }
224
+ break;
225
+
226
+ default:
227
+ throw new AuthenticationError(
228
+ `Unsupported authentication method: ${auth.method}`,
229
+ auth.method
230
+ );
188
231
  }
189
232
  }
190
- }
233
+ }
@@ -3,10 +3,10 @@
3
3
  * Provides common functionality and error handling
4
4
  */
5
5
 
6
- import type { WordPressClientConfig, RequestOptions } from "../../types/client.js";
7
- import { WordPressAPIError, AuthenticationError, RateLimitError } from "../../types/client.js";
8
- import { debug, logError } from "../../utils/debug.js";
9
- import { getErrorMessage } from "../../utils/error.js";
6
+ import type { WordPressClientConfig } from '../../types/client.js';
7
+ import { WordPressAPIError } from '../../types/client.js';
8
+ import { debug, logError } from '../../utils/debug.js';
9
+ import { getErrorMessage } from '../../utils/error.js';
10
10
 
11
11
  export abstract class BaseManager {
12
12
  protected config: WordPressClientConfig;
@@ -25,19 +25,19 @@ export abstract class BaseManager {
25
25
  throw error;
26
26
  }
27
27
 
28
- if (error.name === "AbortError" || error.code === "ABORT_ERR") {
28
+ if (error.name === 'AbortError' || error.code === 'ABORT_ERR') {
29
29
  throw new WordPressAPIError(
30
30
  `Request timeout after ${this.config.timeout}ms`,
31
31
  408,
32
- "timeout"
32
+ 'timeout'
33
33
  );
34
34
  }
35
35
 
36
- if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
36
+ if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {
37
37
  throw new WordPressAPIError(
38
38
  `Cannot connect to WordPress site: ${this.config.baseUrl}`,
39
39
  503,
40
- "connection_failed"
40
+ 'connection_failed'
41
41
  );
42
42
  }
43
43
 
@@ -45,7 +45,7 @@ export abstract class BaseManager {
45
45
  throw new WordPressAPIError(
46
46
  `${operation} failed: ${message}`,
47
47
  500,
48
- "unknown_error"
48
+ 'unknown_error'
49
49
  );
50
50
  }
51
51
 
@@ -59,15 +59,18 @@ export abstract class BaseManager {
59
59
  /**
60
60
  * Validate required parameters
61
61
  */
62
- protected validateRequired(params: Record<string, any>, requiredFields: string[]): void {
62
+ protected validateRequired(
63
+ params: Record<string, any>,
64
+ requiredFields: string[]
65
+ ): void {
63
66
  for (const field of requiredFields) {
64
67
  if (params[field] === undefined || params[field] === null) {
65
68
  throw new WordPressAPIError(
66
69
  `Missing required parameter: ${field}`,
67
70
  400,
68
- "missing_parameter"
71
+ 'missing_parameter'
69
72
  );
70
73
  }
71
74
  }
72
75
  }
73
- }
76
+ }
@@ -3,16 +3,16 @@
3
3
  * Handles all HTTP operations, rate limiting, and retries
4
4
  */
5
5
 
6
- import fetch from "node-fetch";
6
+ import fetch from 'node-fetch';
7
7
  import type {
8
8
  HTTPMethod,
9
9
  RequestOptions,
10
10
  ClientStats,
11
11
  WordPressClientConfig
12
- } from "../../types/client.js";
13
- import { WordPressAPIError, RateLimitError } from "../../types/client.js";
14
- import { BaseManager } from "./BaseManager.js";
15
- import { debug, startTimer } from "../../utils/debug.js";
12
+ } from '../../types/client.js';
13
+ import { WordPressAPIError, RateLimitError } from '../../types/client.js';
14
+ import { BaseManager } from './BaseManager.js';
15
+ import { debug, startTimer } from '../../utils/debug.js';
16
16
 
17
17
  export class RequestManager extends BaseManager {
18
18
  private stats: ClientStats;
@@ -22,14 +22,14 @@ export class RequestManager extends BaseManager {
22
22
  constructor(config: WordPressClientConfig) {
23
23
  super(config);
24
24
 
25
- this.requestInterval = 60000 / parseInt(process.env.RATE_LIMIT || "60");
25
+ this.requestInterval = 60000 / parseInt(process.env.RATE_LIMIT || '60');
26
26
  this.stats = {
27
27
  totalRequests: 0,
28
28
  successfulRequests: 0,
29
29
  failedRequests: 0,
30
30
  averageResponseTime: 0,
31
31
  rateLimitHits: 0,
32
- authFailures: 0,
32
+ authFailures: 0
33
33
  };
34
34
  }
35
35
 
@@ -114,14 +114,14 @@ export class RequestManager extends BaseManager {
114
114
  const fetchOptions: any = {
115
115
  method,
116
116
  headers: {
117
- "Content-Type": "application/json",
118
- "User-Agent": "MCP-WordPress/1.1.1",
119
- ...options.headers,
117
+ 'Content-Type': 'application/json',
118
+ 'User-Agent': 'MCP-WordPress/1.1.1',
119
+ ...options.headers
120
120
  },
121
- signal: controller.signal,
121
+ signal: controller.signal
122
122
  };
123
123
 
124
- if (data && method !== "GET") {
124
+ if (data && method !== 'GET') {
125
125
  fetchOptions.body = JSON.stringify(data);
126
126
  }
127
127
 
@@ -154,7 +154,7 @@ export class RequestManager extends BaseManager {
154
154
  }
155
155
 
156
156
  const message = errorData.message || `HTTP ${response.status}: ${response.statusText}`;
157
- const code = errorData.code || "http_error";
157
+ const code = errorData.code || 'http_error';
158
158
 
159
159
  if (response.status === 429) {
160
160
  this.stats.rateLimitHits++;
@@ -172,9 +172,9 @@ export class RequestManager extends BaseManager {
172
172
  * Build full URL from endpoint
173
173
  */
174
174
  private buildUrl(endpoint: string): string {
175
- const baseUrl = this.config.baseUrl.replace(/\/$/, "");
176
- const apiBase = "/wp-json/wp/v2";
177
- const cleanEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
175
+ const baseUrl = this.config.baseUrl.replace(/\/$/, '');
176
+ const apiBase = '/wp-json/wp/v2';
177
+ const cleanEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
178
178
 
179
179
  return `${baseUrl}${apiBase}${cleanEndpoint}`;
180
180
  }
@@ -211,4 +211,4 @@ export class RequestManager extends BaseManager {
211
211
  getStats(): ClientStats {
212
212
  return { ...this.stats };
213
213
  }
214
- }
214
+ }
@@ -3,6 +3,6 @@
3
3
  * Exports all manager classes for the WordPress client
4
4
  */
5
5
 
6
- export { BaseManager } from "./BaseManager.js";
7
- export { AuthenticationManager } from "./AuthenticationManager.js";
8
- export { RequestManager } from "./RequestManager.js";
6
+ export { BaseManager } from './BaseManager.js';
7
+ export { AuthenticationManager } from './AuthenticationManager.js';
8
+ export { RequestManager } from './RequestManager.js';