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.
- package/README.md +8 -8
- package/bin/mcp-wordpress.js +1 -1
- package/dist/client/api.d.ts +10 -10
- package/dist/client/api.js +157 -157
- package/dist/client/api.js.map +1 -1
- package/dist/client/auth.d.ts +2 -2
- package/dist/client/auth.d.ts.map +1 -1
- package/dist/client/auth.js +72 -72
- package/dist/client/auth.js.map +1 -1
- package/dist/client/managers/AuthenticationManager.d.ts +2 -2
- package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
- package/dist/client/managers/AuthenticationManager.js +50 -46
- package/dist/client/managers/AuthenticationManager.js.map +1 -1
- package/dist/client/managers/BaseManager.d.ts +1 -1
- package/dist/client/managers/BaseManager.d.ts.map +1 -1
- package/dist/client/managers/BaseManager.js +9 -9
- package/dist/client/managers/BaseManager.js.map +1 -1
- package/dist/client/managers/RequestManager.d.ts +2 -2
- package/dist/client/managers/RequestManager.js +15 -15
- package/dist/client/managers/index.d.ts +3 -3
- package/dist/client/managers/index.js +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -61
- package/dist/index.js.map +1 -1
- package/dist/tools/auth.d.ts +2 -2
- package/dist/tools/auth.js +31 -31
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/comments.d.ts +2 -2
- package/dist/tools/comments.js +79 -79
- package/dist/tools/media.d.ts +2 -2
- package/dist/tools/media.d.ts.map +1 -1
- package/dist/tools/media.js +80 -80
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/pages.d.ts +2 -2
- package/dist/tools/pages.js +75 -75
- package/dist/tools/posts.d.ts +2 -2
- package/dist/tools/posts.js +94 -94
- package/dist/tools/site.d.ts +2 -2
- package/dist/tools/site.js +60 -60
- package/dist/tools/site.js.map +1 -1
- package/dist/tools/taxonomies.d.ts +2 -2
- package/dist/tools/taxonomies.js +89 -89
- package/dist/tools/users.d.ts +2 -2
- package/dist/tools/users.js +68 -68
- package/dist/tools/users.js.map +1 -1
- package/dist/types/mcp.d.ts +1 -1
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist/utils/debug.js +10 -6
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/toolWrapper.js +3 -3
- package/docs/developer/GITHUB_ACTIONS_SETUP.md +208 -0
- package/docs/developer/MAINTENANCE.md +307 -0
- package/docs/developer/MIGRATION_GUIDE.md +172 -0
- package/docs/developer/NPM_AUTH_SETUP.md +142 -0
- package/docs/developer/REFACTORING.md +196 -0
- package/docs/releases/COMMUNITY_ANNOUNCEMENT_v1.1.2.md +126 -0
- package/docs/releases/RELEASE_NOTES_v1.1.2.md +173 -0
- package/docs/user-guides/CLAUDE_DESKTOP_SETUP.md +187 -0
- package/package.json +4 -3
- package/src/client/api.ts +229 -229
- package/src/client/auth.ts +135 -136
- package/src/client/managers/AuthenticationManager.ts +148 -105
- package/src/client/managers/BaseManager.ts +15 -12
- package/src/client/managers/RequestManager.ts +17 -17
- package/src/client/managers/index.ts +3 -3
- package/src/index.ts +141 -114
- package/src/server.ts +1 -1
- package/src/tools/auth.ts +36 -36
- package/src/tools/comments.ts +90 -90
- package/src/tools/media.ts +89 -91
- package/src/tools/pages.ts +86 -86
- package/src/tools/posts.ts +106 -106
- package/src/tools/site.ts +71 -71
- package/src/tools/taxonomies.ts +102 -102
- package/src/tools/users.ts +77 -77
- package/src/types/client.ts +1 -1
- package/src/types/index.ts +1 -1
- package/src/types/mcp.ts +36 -16
- package/src/types/wordpress.ts +1 -1
- package/src/utils/debug.ts +63 -39
- package/src/utils/error.ts +1 -1
- package/src/utils/toolWrapper.ts +4 -4
- package/dist/client/WordPressClient.d.ts +0 -81
- package/dist/client/WordPressClient.d.ts.map +0 -1
- package/dist/client/WordPressClient.js +0 -354
- package/dist/client/WordPressClient.js.map +0 -1
- package/dist/tools/base.d.ts +0 -37
- package/dist/tools/base.d.ts.map +0 -1
- package/dist/tools/base.js +0 -60
- package/dist/tools/base.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { McpServer } from
|
|
2
|
-
import { StdioServerTransport } from
|
|
3
|
-
import dotenv from
|
|
4
|
-
import * as fs from
|
|
5
|
-
import * as path from
|
|
6
|
-
import { fileURLToPath } from
|
|
7
|
-
import { WordPressClient } from
|
|
8
|
-
import { AuthMethod, WordPressClientConfig } from
|
|
9
|
-
import * as Tools from
|
|
10
|
-
import { getErrorMessage } from
|
|
11
|
-
import { z } from
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { WordPressClient } from './client/api.js';
|
|
8
|
+
import { AuthMethod, WordPressClientConfig } from './types/client.js';
|
|
9
|
+
import * as Tools from './tools/index.js';
|
|
10
|
+
import { getErrorMessage } from './utils/error.js';
|
|
11
|
+
import { z } from 'zod';
|
|
12
12
|
|
|
13
13
|
// --- Constants ---
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = path.dirname(__filename);
|
|
16
|
-
const rootDir = path.resolve(__dirname,
|
|
17
|
-
const envPath = path.resolve(rootDir,
|
|
16
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
17
|
+
const envPath = path.resolve(rootDir, '.env');
|
|
18
18
|
dotenv.config({ path: envPath });
|
|
19
19
|
|
|
20
|
-
const SERVER_VERSION =
|
|
20
|
+
const SERVER_VERSION = '1.1.7'; // Docker containerization and automated publishing
|
|
21
21
|
|
|
22
22
|
// --- Main Server Class ---
|
|
23
23
|
class MCPWordPressServer {
|
|
@@ -33,38 +33,42 @@ class MCPWordPressServer {
|
|
|
33
33
|
|
|
34
34
|
if (this.wordpressClients.size === 0) {
|
|
35
35
|
console.error(
|
|
36
|
-
|
|
36
|
+
'No WordPress sites were configured. Please create mcp-wordpress.config.json or set environment variables.'
|
|
37
37
|
);
|
|
38
38
|
process.exit(1);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
this.server = new McpServer({
|
|
42
|
-
name:
|
|
43
|
-
version: SERVER_VERSION
|
|
42
|
+
name: 'mcp-wordpress',
|
|
43
|
+
version: SERVER_VERSION
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
this.setupTools();
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
private loadConfiguration(mcpConfig?: any) {
|
|
50
|
-
const configPath = path.resolve(rootDir,
|
|
50
|
+
const configPath = path.resolve(rootDir, 'mcp-wordpress.config.json');
|
|
51
51
|
|
|
52
52
|
if (fs.existsSync(configPath)) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
54
|
+
console.error(
|
|
55
|
+
'INFO: Found mcp-wordpress.config.json, loading multi-site configuration.'
|
|
56
|
+
);
|
|
57
|
+
}
|
|
56
58
|
this.loadMultiSiteConfig(configPath);
|
|
57
59
|
} else {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
61
|
+
console.error(
|
|
62
|
+
'INFO: mcp-wordpress.config.json not found, falling back to environment variables for single-site mode.'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
61
65
|
this.loadSingleSiteFromEnv(mcpConfig);
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
private loadMultiSiteConfig(configPath: string) {
|
|
66
70
|
try {
|
|
67
|
-
const configFile = fs.readFileSync(configPath,
|
|
71
|
+
const configFile = fs.readFileSync(configPath, 'utf-8');
|
|
68
72
|
const config = JSON.parse(configFile);
|
|
69
73
|
|
|
70
74
|
if (!config.sites || !Array.isArray(config.sites)) {
|
|
@@ -79,26 +83,28 @@ class MCPWordPressServer {
|
|
|
79
83
|
auth: {
|
|
80
84
|
method:
|
|
81
85
|
(site.config.WORDPRESS_AUTH_METHOD as AuthMethod) ||
|
|
82
|
-
|
|
86
|
+
'app-password',
|
|
83
87
|
username: site.config.WORDPRESS_USERNAME,
|
|
84
|
-
appPassword: site.config.WORDPRESS_APP_PASSWORD
|
|
85
|
-
}
|
|
88
|
+
appPassword: site.config.WORDPRESS_APP_PASSWORD
|
|
89
|
+
}
|
|
86
90
|
};
|
|
87
91
|
const client = new WordPressClient(clientConfig);
|
|
88
92
|
this.wordpressClients.set(site.id, client);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
94
|
+
console.error(
|
|
95
|
+
`INFO: Initialized client for site: ${site.name} (ID: ${site.id})`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
92
98
|
} else {
|
|
93
99
|
console.warn(
|
|
94
|
-
|
|
95
|
-
site
|
|
100
|
+
'WARN: Skipping invalid site entry in config. Must have id, name, and config.',
|
|
101
|
+
site
|
|
96
102
|
);
|
|
97
103
|
}
|
|
98
104
|
}
|
|
99
105
|
} catch (error) {
|
|
100
106
|
console.error(
|
|
101
|
-
`FATAL: Error reading or parsing mcp-wordpress.config.json: ${getErrorMessage(error)}
|
|
107
|
+
`FATAL: Error reading or parsing mcp-wordpress.config.json: ${getErrorMessage(error)}`
|
|
102
108
|
);
|
|
103
109
|
process.exit(1);
|
|
104
110
|
}
|
|
@@ -113,31 +119,31 @@ class MCPWordPressServer {
|
|
|
113
119
|
mcpConfig?.wordpressAppPassword || process.env.WORDPRESS_APP_PASSWORD;
|
|
114
120
|
const authMethod = (mcpConfig?.wordpressAuthMethod ||
|
|
115
121
|
process.env.WORDPRESS_AUTH_METHOD ||
|
|
116
|
-
|
|
122
|
+
'app-password') as AuthMethod;
|
|
117
123
|
|
|
118
124
|
if (!siteUrl || !username || !password) {
|
|
119
125
|
console.error(
|
|
120
|
-
|
|
126
|
+
'ERROR: Missing required credentials for single-site mode.'
|
|
121
127
|
);
|
|
122
128
|
console.error(
|
|
123
|
-
|
|
129
|
+
'Please set WORDPRESS_SITE_URL, WORDPRESS_USERNAME, and WORDPRESS_APP_PASSWORD environment variables.'
|
|
124
130
|
);
|
|
125
131
|
return;
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
const singleSiteConfig: WordPressClientConfig = {
|
|
129
135
|
baseUrl: siteUrl,
|
|
130
|
-
auth: { method: authMethod, username, appPassword: password }
|
|
136
|
+
auth: { method: authMethod, username, appPassword: password }
|
|
131
137
|
};
|
|
132
138
|
const client = new WordPressClient(singleSiteConfig);
|
|
133
|
-
this.wordpressClients.set(
|
|
139
|
+
this.wordpressClients.set('default', client);
|
|
134
140
|
this.siteConfigs.push({
|
|
135
|
-
id:
|
|
136
|
-
name:
|
|
137
|
-
config: singleSiteConfig
|
|
141
|
+
id: 'default',
|
|
142
|
+
name: 'Default Site',
|
|
143
|
+
config: singleSiteConfig
|
|
138
144
|
});
|
|
139
145
|
console.error(
|
|
140
|
-
|
|
146
|
+
'INFO: Initialized client for default site in single-site mode.'
|
|
141
147
|
);
|
|
142
148
|
}
|
|
143
149
|
|
|
@@ -146,7 +152,7 @@ class MCPWordPressServer {
|
|
|
146
152
|
Object.values(Tools).forEach((ToolClass) => {
|
|
147
153
|
const toolInstance = new ToolClass();
|
|
148
154
|
const tools = toolInstance.getTools();
|
|
149
|
-
|
|
155
|
+
|
|
150
156
|
tools.forEach((tool) => {
|
|
151
157
|
this.registerTool(tool);
|
|
152
158
|
});
|
|
@@ -156,50 +162,59 @@ class MCPWordPressServer {
|
|
|
156
162
|
private registerTool(tool: any) {
|
|
157
163
|
// Create base parameter schema with site parameter
|
|
158
164
|
const baseSchema = {
|
|
159
|
-
site: z
|
|
165
|
+
site: z
|
|
166
|
+
.string()
|
|
160
167
|
.optional()
|
|
161
|
-
.describe(
|
|
168
|
+
.describe(
|
|
169
|
+
'The ID of the WordPress site to target (from mcp-wordpress.config.json). Required if multiple sites are configured.'
|
|
170
|
+
)
|
|
162
171
|
};
|
|
163
172
|
|
|
164
173
|
// Merge with tool-specific parameters
|
|
165
|
-
const parameterSchema =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
174
|
+
const parameterSchema =
|
|
175
|
+
tool.parameters?.reduce(
|
|
176
|
+
(schema: any, param: any) => {
|
|
177
|
+
let zodType;
|
|
178
|
+
|
|
179
|
+
switch (param.type) {
|
|
180
|
+
case 'string':
|
|
181
|
+
zodType = z.string();
|
|
182
|
+
break;
|
|
183
|
+
case 'number':
|
|
184
|
+
zodType = z.number();
|
|
185
|
+
break;
|
|
186
|
+
case 'boolean':
|
|
187
|
+
zodType = z.boolean();
|
|
188
|
+
break;
|
|
189
|
+
case 'array':
|
|
190
|
+
zodType = z.array(z.string());
|
|
191
|
+
break;
|
|
192
|
+
case 'object':
|
|
193
|
+
zodType = z.record(z.any());
|
|
194
|
+
break;
|
|
195
|
+
default:
|
|
196
|
+
zodType = z.string();
|
|
197
|
+
}
|
|
187
198
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
199
|
+
if (param.description) {
|
|
200
|
+
zodType = zodType.describe(param.description);
|
|
201
|
+
}
|
|
191
202
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
203
|
+
if (!param.required) {
|
|
204
|
+
zodType = zodType.optional();
|
|
205
|
+
}
|
|
195
206
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
207
|
+
schema[param.name] = zodType;
|
|
208
|
+
return schema;
|
|
209
|
+
},
|
|
210
|
+
{ ...baseSchema }
|
|
211
|
+
) || baseSchema;
|
|
199
212
|
|
|
200
213
|
// Make site parameter required if multiple sites are configured
|
|
201
214
|
if (this.wordpressClients.size > 1) {
|
|
202
|
-
parameterSchema.site = parameterSchema.site.describe(
|
|
215
|
+
parameterSchema.site = parameterSchema.site.describe(
|
|
216
|
+
'The ID of the WordPress site to target (from mcp-wordpress.config.json). Required when multiple sites are configured.'
|
|
217
|
+
);
|
|
203
218
|
}
|
|
204
219
|
|
|
205
220
|
this.server.tool(
|
|
@@ -208,46 +223,58 @@ class MCPWordPressServer {
|
|
|
208
223
|
parameterSchema,
|
|
209
224
|
async (args: any) => {
|
|
210
225
|
try {
|
|
211
|
-
const siteId = args.site ||
|
|
226
|
+
const siteId = args.site || 'default';
|
|
212
227
|
const client = this.wordpressClients.get(siteId);
|
|
213
228
|
|
|
214
229
|
if (!client) {
|
|
215
|
-
const availableSites = Array.from(
|
|
230
|
+
const availableSites = Array.from(
|
|
231
|
+
this.wordpressClients.keys()
|
|
232
|
+
).join(', ');
|
|
216
233
|
return {
|
|
217
|
-
content: [
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
234
|
+
content: [
|
|
235
|
+
{
|
|
236
|
+
type: 'text' as const,
|
|
237
|
+
text: `Error: Site with ID '${siteId}' not found. Available sites: ${availableSites}`
|
|
238
|
+
}
|
|
239
|
+
],
|
|
221
240
|
isError: true
|
|
222
241
|
};
|
|
223
242
|
}
|
|
224
243
|
|
|
225
244
|
// Call the tool handler with the client and parameters
|
|
226
245
|
const result = await tool.handler(client, args);
|
|
227
|
-
|
|
246
|
+
|
|
228
247
|
return {
|
|
229
|
-
content: [
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
248
|
+
content: [
|
|
249
|
+
{
|
|
250
|
+
type: 'text' as const,
|
|
251
|
+
text:
|
|
252
|
+
typeof result === 'string'
|
|
253
|
+
? result
|
|
254
|
+
: JSON.stringify(result, null, 2)
|
|
255
|
+
}
|
|
256
|
+
]
|
|
233
257
|
};
|
|
234
|
-
|
|
235
258
|
} catch (error) {
|
|
236
259
|
if (this.isAuthenticationError(error)) {
|
|
237
260
|
return {
|
|
238
|
-
content: [
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
261
|
+
content: [
|
|
262
|
+
{
|
|
263
|
+
type: 'text' as const,
|
|
264
|
+
text: `Authentication failed for site '${args.site || 'default'}'. Please check your credentials.`
|
|
265
|
+
}
|
|
266
|
+
],
|
|
242
267
|
isError: true
|
|
243
268
|
};
|
|
244
269
|
}
|
|
245
|
-
|
|
270
|
+
|
|
246
271
|
return {
|
|
247
|
-
content: [
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
272
|
+
content: [
|
|
273
|
+
{
|
|
274
|
+
type: 'text' as const,
|
|
275
|
+
text: `Error: ${getErrorMessage(error)}`
|
|
276
|
+
}
|
|
277
|
+
],
|
|
251
278
|
isError: true
|
|
252
279
|
};
|
|
253
280
|
}
|
|
@@ -257,7 +284,7 @@ class MCPWordPressServer {
|
|
|
257
284
|
|
|
258
285
|
private async testClientConnections(): Promise<void> {
|
|
259
286
|
console.error(
|
|
260
|
-
|
|
287
|
+
'INFO: Testing connections to all configured WordPress sites...'
|
|
261
288
|
);
|
|
262
289
|
const connectionPromises = Array.from(this.wordpressClients.entries()).map(
|
|
263
290
|
async ([siteId, client]) => {
|
|
@@ -266,47 +293,47 @@ class MCPWordPressServer {
|
|
|
266
293
|
console.error(`SUCCESS: Connection to site '${siteId}' successful.`);
|
|
267
294
|
} catch (error) {
|
|
268
295
|
console.error(
|
|
269
|
-
`ERROR: Failed to connect to site '${siteId}': ${getErrorMessage(error)}
|
|
296
|
+
`ERROR: Failed to connect to site '${siteId}': ${getErrorMessage(error)}`
|
|
270
297
|
);
|
|
271
298
|
if (this.isAuthenticationError(error)) {
|
|
272
299
|
console.error(
|
|
273
|
-
`Authentication may have failed for site '${siteId}'. Please check credentials
|
|
300
|
+
`Authentication may have failed for site '${siteId}'. Please check credentials.`
|
|
274
301
|
);
|
|
275
302
|
}
|
|
276
303
|
}
|
|
277
|
-
}
|
|
304
|
+
}
|
|
278
305
|
);
|
|
279
306
|
await Promise.all(connectionPromises);
|
|
280
307
|
this.initialized = true;
|
|
281
|
-
console.error(
|
|
308
|
+
console.error('INFO: Connection tests complete.');
|
|
282
309
|
}
|
|
283
310
|
|
|
284
311
|
private isAuthenticationError(error: any): boolean {
|
|
285
312
|
if (error?.response?.status && [401, 403].includes(error.response.status)) {
|
|
286
313
|
return true;
|
|
287
314
|
}
|
|
288
|
-
return error?.code ===
|
|
315
|
+
return error?.code === 'WORDPRESS_AUTH_ERROR';
|
|
289
316
|
}
|
|
290
317
|
|
|
291
318
|
async run() {
|
|
292
319
|
if (!this.initialized) {
|
|
293
320
|
await this.testClientConnections();
|
|
294
321
|
}
|
|
295
|
-
console.error(
|
|
296
|
-
|
|
322
|
+
console.error('INFO: Starting MCP WordPress Server...');
|
|
323
|
+
|
|
297
324
|
// Connect to stdio transport
|
|
298
325
|
const transport = new StdioServerTransport();
|
|
299
326
|
await this.server.connect(transport);
|
|
300
|
-
|
|
327
|
+
|
|
301
328
|
console.error(
|
|
302
|
-
`INFO: Server started and connected. Tools available for ${this.wordpressClients.size} site(s)
|
|
329
|
+
`INFO: Server started and connected. Tools available for ${this.wordpressClients.size} site(s).`
|
|
303
330
|
);
|
|
304
331
|
}
|
|
305
332
|
|
|
306
333
|
async shutdown() {
|
|
307
|
-
console.error(
|
|
334
|
+
console.error('INFO: Shutting down MCP WordPress Server...');
|
|
308
335
|
await this.server.close();
|
|
309
|
-
console.error(
|
|
336
|
+
console.error('INFO: Server stopped.');
|
|
310
337
|
}
|
|
311
338
|
}
|
|
312
339
|
|
|
@@ -321,8 +348,8 @@ async function main() {
|
|
|
321
348
|
process.exit(0);
|
|
322
349
|
};
|
|
323
350
|
|
|
324
|
-
process.on(
|
|
325
|
-
process.on(
|
|
351
|
+
process.on('SIGINT', shutdown);
|
|
352
|
+
process.on('SIGTERM', shutdown);
|
|
326
353
|
} catch (error) {
|
|
327
354
|
console.error(`FATAL: Failed to start server: ${getErrorMessage(error)}`);
|
|
328
355
|
process.exit(1);
|
|
@@ -334,4 +361,4 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
|
334
361
|
}
|
|
335
362
|
|
|
336
363
|
export default MCPWordPressServer;
|
|
337
|
-
export { MCPWordPressServer };
|
|
364
|
+
export { MCPWordPressServer };
|
package/src/server.ts
CHANGED
package/src/tools/auth.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { WordPressClient } from
|
|
2
|
-
import { AuthMethod } from
|
|
3
|
-
import { getErrorMessage } from
|
|
1
|
+
import { WordPressClient } from '../client/api.js';
|
|
2
|
+
import { AuthMethod } from '../types/client.js';
|
|
3
|
+
import { getErrorMessage } from '../utils/error.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Provides authentication-related tools for WordPress sites.
|
|
@@ -14,51 +14,51 @@ export class AuthTools {
|
|
|
14
14
|
public getTools(): any[] {
|
|
15
15
|
return [
|
|
16
16
|
{
|
|
17
|
-
name:
|
|
17
|
+
name: 'wp_test_auth',
|
|
18
18
|
description:
|
|
19
|
-
|
|
19
|
+
'Tests the authentication and connectivity for a configured WordPress site.',
|
|
20
20
|
parameters: [], // The 'site' parameter is added dynamically by the server
|
|
21
|
-
handler: this.handleTestAuth.bind(this)
|
|
21
|
+
handler: this.handleTestAuth.bind(this)
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
name:
|
|
24
|
+
name: 'wp_get_auth_status',
|
|
25
25
|
description:
|
|
26
|
-
|
|
26
|
+
'Gets the current authentication status for a configured WordPress site.',
|
|
27
27
|
parameters: [],
|
|
28
|
-
handler: this.handleGetAuthStatus.bind(this)
|
|
28
|
+
handler: this.handleGetAuthStatus.bind(this)
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
|
-
name:
|
|
31
|
+
name: 'wp_switch_auth_method',
|
|
32
32
|
description:
|
|
33
|
-
|
|
33
|
+
'Switches the authentication method for a site for the current session.',
|
|
34
34
|
parameters: [
|
|
35
35
|
{
|
|
36
|
-
name:
|
|
37
|
-
type:
|
|
36
|
+
name: 'method',
|
|
37
|
+
type: 'string',
|
|
38
38
|
required: true,
|
|
39
|
-
description:
|
|
40
|
-
enum: [
|
|
39
|
+
description: 'The new authentication method to use.',
|
|
40
|
+
enum: ['app-password', 'jwt', 'basic', 'api-key', 'cookie']
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
|
-
name:
|
|
44
|
-
type:
|
|
43
|
+
name: 'username',
|
|
44
|
+
type: 'string',
|
|
45
45
|
description:
|
|
46
|
-
|
|
46
|
+
'The username for \'app-password\' or \'basic\' authentication.'
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
|
-
name:
|
|
50
|
-
type:
|
|
49
|
+
name: 'password',
|
|
50
|
+
type: 'string',
|
|
51
51
|
description:
|
|
52
|
-
|
|
52
|
+
'The Application Password for \'app-password\' or password for \'basic\' auth.'
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
|
-
name:
|
|
56
|
-
type:
|
|
57
|
-
description:
|
|
58
|
-
}
|
|
55
|
+
name: 'jwt_token',
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'The token for \'jwt\' authentication.'
|
|
58
|
+
}
|
|
59
59
|
],
|
|
60
|
-
handler: this.handleSwitchAuthMethod.bind(this)
|
|
61
|
-
}
|
|
60
|
+
handler: this.handleSwitchAuthMethod.bind(this)
|
|
61
|
+
}
|
|
62
62
|
];
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -71,7 +71,7 @@ export class AuthTools {
|
|
|
71
71
|
*/
|
|
72
72
|
public async handleTestAuth(
|
|
73
73
|
client: WordPressClient,
|
|
74
|
-
params: any
|
|
74
|
+
params: any
|
|
75
75
|
): Promise<any> {
|
|
76
76
|
try {
|
|
77
77
|
await client.ping();
|
|
@@ -79,12 +79,12 @@ export class AuthTools {
|
|
|
79
79
|
const siteConfig = client.config;
|
|
80
80
|
|
|
81
81
|
const content =
|
|
82
|
-
|
|
82
|
+
'✅ **Authentication successful!**\n\n' +
|
|
83
83
|
`**Site:** ${siteConfig.baseUrl}\n` +
|
|
84
84
|
`**Method:** ${siteConfig.auth.method}\n` +
|
|
85
85
|
`**User:** ${user.name} (@${user.slug})\n` +
|
|
86
|
-
`**Roles:** ${user.roles?.join(
|
|
87
|
-
|
|
86
|
+
`**Roles:** ${user.roles?.join(', ') || 'N/A'}\n\n` +
|
|
87
|
+
'Your WordPress connection is working properly.';
|
|
88
88
|
|
|
89
89
|
return content;
|
|
90
90
|
} catch (error) {
|
|
@@ -101,21 +101,21 @@ export class AuthTools {
|
|
|
101
101
|
*/
|
|
102
102
|
public async handleGetAuthStatus(
|
|
103
103
|
client: WordPressClient,
|
|
104
|
-
params: any
|
|
104
|
+
params: any
|
|
105
105
|
): Promise<any> {
|
|
106
106
|
try {
|
|
107
107
|
const isAuthenticated = client.isAuthenticated;
|
|
108
108
|
const config = client.config;
|
|
109
109
|
let content =
|
|
110
110
|
`**Authentication Status for ${config.baseUrl}**\n\n` +
|
|
111
|
-
`**Authenticated:** ${isAuthenticated ?
|
|
111
|
+
`**Authenticated:** ${isAuthenticated ? '✅ Yes' : '❌ No'}\n` +
|
|
112
112
|
`**Method:** ${config.auth.method}\n`;
|
|
113
113
|
|
|
114
114
|
if (isAuthenticated) {
|
|
115
115
|
const user = await client.getCurrentUser();
|
|
116
116
|
content += `**User:** ${user.name} (@${user.slug})\n`;
|
|
117
117
|
} else {
|
|
118
|
-
content +=
|
|
118
|
+
content += '**Status:** Not connected. Use \'wp_test_auth\' to connect and verify credentials.';
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
return content;
|
|
@@ -138,12 +138,12 @@ export class AuthTools {
|
|
|
138
138
|
username?: string;
|
|
139
139
|
password?: string;
|
|
140
140
|
jwt_token?: string;
|
|
141
|
-
}
|
|
141
|
+
}
|
|
142
142
|
): Promise<any> {
|
|
143
143
|
try {
|
|
144
144
|
// This functionality is not currently supported as the client
|
|
145
145
|
// doesn't have an updateAuthConfig method
|
|
146
|
-
throw new Error(
|
|
146
|
+
throw new Error('Dynamic authentication method switching is not currently supported. Please update your configuration file and restart the server.');
|
|
147
147
|
} catch (error) {
|
|
148
148
|
throw new Error(`Failed to switch auth method: ${getErrorMessage(error)}`);
|
|
149
149
|
}
|