myaidev-method 0.0.6 โ 0.0.8
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/.claude/CLAUDE.md +52 -0
- package/.claude/agents/content-writer.md +155 -0
- package/.claude/commands/myai-configure.md +44 -0
- package/.claude/commands/myai-content-writer.md +78 -0
- package/.claude/commands/myai-wordpress-publish.md +120 -0
- package/.claude/mcp/gutenberg-converter.js +447 -0
- package/.claude/mcp/mcp-config.json +101 -0
- package/.claude/mcp/wordpress-server-simple.js +182 -0
- package/.claude/mcp/wordpress-server.js +1277 -0
- package/.claude/settings.local.json +12 -0
- package/README.md +4 -4
- package/bin/cli.js +18 -15
- package/dist/mcp/gutenberg-converter.js +447 -0
- package/dist/mcp/mcp-config.json +101 -0
- package/dist/mcp/wordpress-server-simple.js +182 -0
- package/dist/mcp/wordpress-server.js +1277 -0
- package/package.json +22 -8
- package/src/mcp/health-check.js +190 -0
- package/src/mcp/mcp-launcher.js +237 -0
- package/src/scripts/configure-wordpress-mcp.js +176 -0
- package/src/templates/claude/agents/wordpress-admin.md +259 -218
- package/src/templates/claude/commands/myai-configure.md +9 -0
- package/src/templates/claude/commands/myai-wordpress-publish.md +16 -8
- package/src/templates/scripts/configure-wordpress-mcp.js +181 -0
package/package.json
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myaidev-method",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "AI CLI tools package with custom subagents and MCP integrations for Claude Code, Gemini CLI, and more",
|
|
5
|
+
"mcpName": "io.github.myaione/myaidev-method",
|
|
5
6
|
"main": "src/index.js",
|
|
6
7
|
"bin": {
|
|
7
|
-
"myaidev-method": "./bin/cli.js"
|
|
8
|
+
"myaidev-method": "./bin/cli.js",
|
|
9
|
+
"myaidev-mcp-server": "./.claude/mcp/wordpress-server.js",
|
|
10
|
+
"myaidev-mcp-launcher": "./src/mcp/mcp-launcher.js"
|
|
8
11
|
},
|
|
9
12
|
"scripts": {
|
|
10
13
|
"test": "node test/run-tests.js",
|
|
11
14
|
"test:gutenberg": "node test/test-gutenberg-converter.js",
|
|
12
15
|
"test:install": "node test/test-installation.js",
|
|
13
|
-
"
|
|
16
|
+
"test:mcp": "node test/test-enhanced-mcp-server.js",
|
|
17
|
+
"test:mcp:simple": "node test/test-simple-mcp.js",
|
|
18
|
+
"mcp:start": "node src/mcp/mcp-launcher.js start",
|
|
19
|
+
"mcp:start:direct": "node .claude/mcp/wordpress-server.js",
|
|
20
|
+
"mcp:start:simple": "node .claude/mcp/wordpress-server-simple.js",
|
|
21
|
+
"mcp:status": "node src/mcp/mcp-launcher.js status",
|
|
22
|
+
"mcp:health": "node src/mcp/mcp-launcher.js health",
|
|
23
|
+
"build:mcp": "mkdir -p dist/mcp && cp .claude/mcp/*.js .claude/mcp/*.json dist/mcp/",
|
|
24
|
+
"prepublishOnly": "npm install && npm test && npm run build:mcp",
|
|
14
25
|
"postinstall": "echo \"MyAIDev Method installed successfully! Run 'npx myaidev-method init --claude' to get started.\"",
|
|
15
26
|
"wordpress:troubleshoot": "node src/templates/docs/wordpress-troubleshoot.js"
|
|
16
27
|
},
|
|
@@ -31,16 +42,17 @@
|
|
|
31
42
|
"license": "MIT",
|
|
32
43
|
"type": "module",
|
|
33
44
|
"dependencies": {
|
|
34
|
-
"
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
35
46
|
"chalk": "^5.3.0",
|
|
47
|
+
"commander": "^12.0.0",
|
|
48
|
+
"dotenv": "^16.4.1",
|
|
36
49
|
"fs-extra": "^11.2.0",
|
|
37
50
|
"inquirer": "^9.2.15",
|
|
38
|
-
"ora": "^8.0.1",
|
|
39
51
|
"node-fetch": "^3.3.2",
|
|
40
|
-
"
|
|
41
|
-
"ssh2": "^1.15.0"
|
|
52
|
+
"ora": "^8.0.1",
|
|
53
|
+
"ssh2": "^1.15.0",
|
|
54
|
+
"zod": "^3.23.8"
|
|
42
55
|
},
|
|
43
|
-
"devDependencies": {},
|
|
44
56
|
"repository": {
|
|
45
57
|
"type": "git",
|
|
46
58
|
"url": "git+https://github.com/myaione/myaidev-method.git"
|
|
@@ -52,6 +64,8 @@
|
|
|
52
64
|
"files": [
|
|
53
65
|
"bin/",
|
|
54
66
|
"src/",
|
|
67
|
+
".claude/",
|
|
68
|
+
"dist/",
|
|
55
69
|
"README.md",
|
|
56
70
|
"USER_GUIDE.md",
|
|
57
71
|
"LICENSE",
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP Server Health Check Script
|
|
5
|
+
* Validates MCP server configuration and connectivity
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { promises as fs } from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
|
|
15
|
+
export default async function healthCheck() {
|
|
16
|
+
console.log('๐ MyAIDev Method MCP Server Health Check');
|
|
17
|
+
console.log('==========================================\n');
|
|
18
|
+
|
|
19
|
+
const checks = [];
|
|
20
|
+
|
|
21
|
+
// Check 1: Environment variables
|
|
22
|
+
console.log('๐ Checking environment configuration...');
|
|
23
|
+
const envChecks = {
|
|
24
|
+
'WORDPRESS_URL': process.env.WORDPRESS_URL,
|
|
25
|
+
'WORDPRESS_USERNAME': process.env.WORDPRESS_USERNAME,
|
|
26
|
+
'WORDPRESS_APP_PASSWORD': process.env.WORDPRESS_APP_PASSWORD
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
let envConfigured = true;
|
|
30
|
+
Object.entries(envChecks).forEach(([key, value]) => {
|
|
31
|
+
if (value) {
|
|
32
|
+
console.log(` โ
${key}: configured`);
|
|
33
|
+
} else {
|
|
34
|
+
console.log(` โ ${key}: missing`);
|
|
35
|
+
envConfigured = false;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
checks.push({
|
|
40
|
+
name: 'Environment Configuration',
|
|
41
|
+
status: envConfigured ? 'passed' : 'failed'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Check 2: MCP server files
|
|
45
|
+
console.log('\n๐ Checking MCP server files...');
|
|
46
|
+
const mcpServerPath = path.resolve(__dirname, '../../.claude/mcp/wordpress-server.js');
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
await fs.access(mcpServerPath);
|
|
50
|
+
console.log(' โ
WordPress MCP server file exists');
|
|
51
|
+
checks.push({
|
|
52
|
+
name: 'MCP Server Files',
|
|
53
|
+
status: 'passed'
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.log(' โ WordPress MCP server file missing');
|
|
57
|
+
checks.push({
|
|
58
|
+
name: 'MCP Server Files',
|
|
59
|
+
status: 'failed'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Check 3: Dependencies
|
|
64
|
+
console.log('\n๐ฆ Checking dependencies...');
|
|
65
|
+
const requiredDeps = [
|
|
66
|
+
{ name: '@modelcontextprotocol/sdk', path: '@modelcontextprotocol/sdk/server/mcp.js' },
|
|
67
|
+
{ name: 'node-fetch', path: 'node-fetch' },
|
|
68
|
+
{ name: 'dotenv', path: 'dotenv' },
|
|
69
|
+
{ name: 'zod', path: 'zod' }
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
let depsInstalled = true;
|
|
73
|
+
for (const dep of requiredDeps) {
|
|
74
|
+
try {
|
|
75
|
+
await import(dep.path);
|
|
76
|
+
console.log(` โ
${dep.name}: installed`);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.log(` โ ${dep.name}: missing or failed to import`);
|
|
79
|
+
depsInstalled = false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
checks.push({
|
|
84
|
+
name: 'Dependencies',
|
|
85
|
+
status: depsInstalled ? 'passed' : 'failed'
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Check 4: MCP server startup test
|
|
89
|
+
if (envConfigured && depsInstalled) {
|
|
90
|
+
console.log('\n๐ Testing MCP server startup...');
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const startupTest = await testServerStartup(mcpServerPath);
|
|
94
|
+
console.log(` โ
MCP server starts successfully`);
|
|
95
|
+
checks.push({
|
|
96
|
+
name: 'MCP Server Startup',
|
|
97
|
+
status: 'passed'
|
|
98
|
+
});
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.log(` โ MCP server startup failed: ${error.message}`);
|
|
101
|
+
checks.push({
|
|
102
|
+
name: 'MCP Server Startup',
|
|
103
|
+
status: 'failed'
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
console.log('\nโญ๏ธ Skipping MCP server startup test (dependencies not met)');
|
|
108
|
+
checks.push({
|
|
109
|
+
name: 'MCP Server Startup',
|
|
110
|
+
status: 'skipped'
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Summary
|
|
115
|
+
console.log('\n๐ Health Check Summary:');
|
|
116
|
+
const passed = checks.filter(c => c.status === 'passed').length;
|
|
117
|
+
const failed = checks.filter(c => c.status === 'failed').length;
|
|
118
|
+
const skipped = checks.filter(c => c.status === 'skipped').length;
|
|
119
|
+
|
|
120
|
+
checks.forEach(check => {
|
|
121
|
+
const icon = check.status === 'passed' ? 'โ
' :
|
|
122
|
+
check.status === 'failed' ? 'โ' : 'โญ๏ธ';
|
|
123
|
+
console.log(` ${icon} ${check.name}: ${check.status}`);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
console.log(`\nResult: ${passed} passed, ${failed} failed, ${skipped} skipped`);
|
|
127
|
+
|
|
128
|
+
if (failed === 0) {
|
|
129
|
+
console.log('\n๐ All checks passed! MCP server is ready to use.');
|
|
130
|
+
console.log('\n๐ก Next steps:');
|
|
131
|
+
console.log(' โข Run: npm run mcp:start');
|
|
132
|
+
console.log(' โข Or use: /myai-wordpress-publish "your-file.md"');
|
|
133
|
+
} else {
|
|
134
|
+
console.log('\nโ ๏ธ Some checks failed. Please address the issues above.');
|
|
135
|
+
console.log('\n๐ก Common solutions:');
|
|
136
|
+
console.log(' โข Set environment variables: /myai-configure wordpress');
|
|
137
|
+
console.log(' โข Install dependencies: npm install');
|
|
138
|
+
console.log(' โข Check file permissions and paths');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
passed,
|
|
143
|
+
failed,
|
|
144
|
+
skipped,
|
|
145
|
+
checks,
|
|
146
|
+
overall: failed === 0 ? 'healthy' : 'unhealthy'
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function testServerStartup(serverPath) {
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
const serverProcess = spawn('node', [serverPath], {
|
|
153
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
154
|
+
env: process.env
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
let startupOutput = '';
|
|
158
|
+
const timeout = setTimeout(() => {
|
|
159
|
+
serverProcess.kill();
|
|
160
|
+
reject(new Error('Server startup timeout'));
|
|
161
|
+
}, 5000);
|
|
162
|
+
|
|
163
|
+
serverProcess.stderr.on('data', (data) => {
|
|
164
|
+
startupOutput += data.toString();
|
|
165
|
+
if (startupOutput.includes('Enhanced WordPress MCP Server') ||
|
|
166
|
+
startupOutput.includes('running')) {
|
|
167
|
+
clearTimeout(timeout);
|
|
168
|
+
serverProcess.kill();
|
|
169
|
+
resolve(true);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
serverProcess.on('error', (error) => {
|
|
174
|
+
clearTimeout(timeout);
|
|
175
|
+
reject(error);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
serverProcess.on('exit', (code) => {
|
|
179
|
+
clearTimeout(timeout);
|
|
180
|
+
if (code !== 0 && code !== null) {
|
|
181
|
+
reject(new Error(`Server exited with code ${code}`));
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Run if called directly
|
|
188
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
189
|
+
healthCheck().catch(console.error);
|
|
190
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP Server Launcher Script
|
|
5
|
+
* Manages MCP server lifecycle with proper error handling and configuration
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { promises as fs } from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
|
|
15
|
+
class MCPLauncher {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.serverProcess = null;
|
|
18
|
+
this.serverPath = path.resolve(__dirname, '../../.claude/mcp/wordpress-server.js');
|
|
19
|
+
this.isShuttingDown = false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
log(message, level = 'info') {
|
|
23
|
+
const timestamp = new Date().toISOString();
|
|
24
|
+
const prefix = {
|
|
25
|
+
info: '๐ง',
|
|
26
|
+
success: 'โ
',
|
|
27
|
+
error: 'โ',
|
|
28
|
+
warn: 'โ ๏ธ'
|
|
29
|
+
}[level] || 'โน๏ธ';
|
|
30
|
+
|
|
31
|
+
console.log(`[${timestamp}] ${prefix} ${message}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async validateEnvironment() {
|
|
35
|
+
this.log('Validating environment configuration...');
|
|
36
|
+
|
|
37
|
+
const required = ['WORDPRESS_URL', 'WORDPRESS_USERNAME', 'WORDPRESS_APP_PASSWORD'];
|
|
38
|
+
const missing = required.filter(key => !process.env[key]);
|
|
39
|
+
|
|
40
|
+
if (missing.length > 0) {
|
|
41
|
+
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.log('Environment validation passed', 'success');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async validateServerFile() {
|
|
48
|
+
this.log('Checking MCP server file...');
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
await fs.access(this.serverPath);
|
|
52
|
+
this.log('MCP server file found', 'success');
|
|
53
|
+
} catch (error) {
|
|
54
|
+
throw new Error(`MCP server file not found: ${this.serverPath}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async startServer() {
|
|
59
|
+
if (this.serverProcess) {
|
|
60
|
+
this.log('Server is already running', 'warn');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.log('Starting Enhanced WordPress MCP Server...');
|
|
65
|
+
|
|
66
|
+
this.serverProcess = spawn('node', [this.serverPath], {
|
|
67
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
68
|
+
env: process.env
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Handle server output
|
|
72
|
+
this.serverProcess.stdout.on('data', (data) => {
|
|
73
|
+
const output = data.toString().trim();
|
|
74
|
+
if (output) {
|
|
75
|
+
console.log(`[SERVER] ${output}`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
this.serverProcess.stderr.on('data', (data) => {
|
|
80
|
+
const output = data.toString().trim();
|
|
81
|
+
if (output) {
|
|
82
|
+
if (output.includes('Enhanced WordPress MCP Server') && output.includes('running')) {
|
|
83
|
+
this.log('MCP Server started successfully', 'success');
|
|
84
|
+
this.log(`Server PID: ${this.serverProcess.pid}`);
|
|
85
|
+
this.log('MCP Server is ready to accept connections');
|
|
86
|
+
} else if (output.includes('ERROR') || output.includes('Error')) {
|
|
87
|
+
this.log(`Server error: ${output}`, 'error');
|
|
88
|
+
} else {
|
|
89
|
+
console.log(`[SERVER] ${output}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Handle server exit
|
|
95
|
+
this.serverProcess.on('exit', (code, signal) => {
|
|
96
|
+
if (!this.isShuttingDown) {
|
|
97
|
+
if (code === 0) {
|
|
98
|
+
this.log('Server exited gracefully');
|
|
99
|
+
} else {
|
|
100
|
+
this.log(`Server exited with code ${code} (signal: ${signal})`, 'error');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.serverProcess = null;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this.serverProcess.on('error', (error) => {
|
|
107
|
+
this.log(`Server startup error: ${error.message}`, 'error');
|
|
108
|
+
this.serverProcess = null;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Setup graceful shutdown
|
|
112
|
+
this.setupShutdownHandlers();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
setupShutdownHandlers() {
|
|
116
|
+
const shutdown = async (signal) => {
|
|
117
|
+
if (this.isShuttingDown) return;
|
|
118
|
+
|
|
119
|
+
this.isShuttingDown = true;
|
|
120
|
+
this.log(`Received ${signal}, shutting down gracefully...`);
|
|
121
|
+
|
|
122
|
+
if (this.serverProcess) {
|
|
123
|
+
this.log('Stopping MCP server...');
|
|
124
|
+
this.serverProcess.kill('SIGTERM');
|
|
125
|
+
|
|
126
|
+
// Force kill after 10 seconds
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
if (this.serverProcess) {
|
|
129
|
+
this.log('Force killing server...', 'warn');
|
|
130
|
+
this.serverProcess.kill('SIGKILL');
|
|
131
|
+
}
|
|
132
|
+
}, 10000);
|
|
133
|
+
|
|
134
|
+
// Wait for server to exit
|
|
135
|
+
await new Promise((resolve) => {
|
|
136
|
+
if (!this.serverProcess) {
|
|
137
|
+
resolve();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
this.serverProcess.on('exit', () => {
|
|
142
|
+
resolve();
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.log('Shutdown complete');
|
|
148
|
+
process.exit(0);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
152
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
153
|
+
process.on('SIGHUP', () => shutdown('SIGHUP'));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async launch() {
|
|
157
|
+
try {
|
|
158
|
+
this.log('๐ MyAIDev Method MCP Server Launcher');
|
|
159
|
+
this.log('=====================================');
|
|
160
|
+
|
|
161
|
+
await this.validateEnvironment();
|
|
162
|
+
await this.validateServerFile();
|
|
163
|
+
await this.startServer();
|
|
164
|
+
|
|
165
|
+
// Keep the launcher running
|
|
166
|
+
this.log('Launcher is monitoring server...');
|
|
167
|
+
|
|
168
|
+
} catch (error) {
|
|
169
|
+
this.log(`Launch failed: ${error.message}`, 'error');
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async status() {
|
|
175
|
+
this.log('MCP Server Status Check');
|
|
176
|
+
this.log('======================');
|
|
177
|
+
|
|
178
|
+
if (this.serverProcess) {
|
|
179
|
+
this.log(`Server is running (PID: ${this.serverProcess.pid})`, 'success');
|
|
180
|
+
this.log(`Server path: ${this.serverPath}`);
|
|
181
|
+
} else {
|
|
182
|
+
this.log('Server is not running', 'warn');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Environment status
|
|
186
|
+
const envVars = ['WORDPRESS_URL', 'WORDPRESS_USERNAME', 'WORDPRESS_APP_PASSWORD'];
|
|
187
|
+
this.log('\nEnvironment variables:');
|
|
188
|
+
envVars.forEach(key => {
|
|
189
|
+
const status = process.env[key] ? 'โ
' : 'โ';
|
|
190
|
+
const value = process.env[key] ? 'configured' : 'missing';
|
|
191
|
+
console.log(` ${status} ${key}: ${value}`);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
running: !!this.serverProcess,
|
|
196
|
+
pid: this.serverProcess?.pid,
|
|
197
|
+
serverPath: this.serverPath
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// CLI interface
|
|
203
|
+
async function main() {
|
|
204
|
+
const launcher = new MCPLauncher();
|
|
205
|
+
const command = process.argv[2] || 'start';
|
|
206
|
+
|
|
207
|
+
switch (command) {
|
|
208
|
+
case 'start':
|
|
209
|
+
await launcher.launch();
|
|
210
|
+
break;
|
|
211
|
+
|
|
212
|
+
case 'status':
|
|
213
|
+
await launcher.status();
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case 'health':
|
|
217
|
+
const { default: healthCheck } = await import('./health-check.js');
|
|
218
|
+
await healthCheck();
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
default:
|
|
222
|
+
console.log('Usage: node mcp-launcher.js [start|status|health]');
|
|
223
|
+
console.log('');
|
|
224
|
+
console.log('Commands:');
|
|
225
|
+
console.log(' start - Start the MCP server (default)');
|
|
226
|
+
console.log(' status - Show server status');
|
|
227
|
+
console.log(' health - Run health check');
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export { MCPLauncher };
|
|
233
|
+
|
|
234
|
+
// Run if called directly
|
|
235
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
236
|
+
main().catch(console.error);
|
|
237
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import dotenv from 'dotenv';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Configure WordPress MCP integration for Claude Code
|
|
13
|
+
* This script creates the .mcp.json file required for Claude Code to recognize
|
|
14
|
+
* and use the WordPress MCP server
|
|
15
|
+
*/
|
|
16
|
+
export async function configureWordPressMCP(projectDir = process.cwd()) {
|
|
17
|
+
try {
|
|
18
|
+
console.log('๐ง Configuring WordPress MCP integration...');
|
|
19
|
+
|
|
20
|
+
// Load environment variables from .env file
|
|
21
|
+
const envPath = path.join(projectDir, '.env');
|
|
22
|
+
if (!fs.existsSync(envPath)) {
|
|
23
|
+
throw new Error('.env file not found. Please run WordPress configuration first.');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
dotenv.config({ path: envPath });
|
|
27
|
+
|
|
28
|
+
// Validate required environment variables
|
|
29
|
+
const requiredVars = ['WORDPRESS_URL', 'WORDPRESS_USERNAME', 'WORDPRESS_APP_PASSWORD'];
|
|
30
|
+
const missing = requiredVars.filter(varName => !process.env[varName]);
|
|
31
|
+
|
|
32
|
+
if (missing.length > 0) {
|
|
33
|
+
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Check if MCP server files exist
|
|
37
|
+
const mcpServerPath = path.join(projectDir, '.claude/mcp/wordpress-server.js');
|
|
38
|
+
const gutenbergConverterPath = path.join(projectDir, '.claude/mcp/gutenberg-converter.js');
|
|
39
|
+
|
|
40
|
+
if (!fs.existsSync(mcpServerPath)) {
|
|
41
|
+
throw new Error(`WordPress MCP server not found at: ${mcpServerPath}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!fs.existsSync(gutenbergConverterPath)) {
|
|
45
|
+
throw new Error(`Gutenberg converter not found at: ${gutenbergConverterPath}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Create MCP configuration
|
|
49
|
+
const mcpConfigPath = path.join(projectDir, '.mcp.json');
|
|
50
|
+
const mcpConfig = {
|
|
51
|
+
mcpServers: {
|
|
52
|
+
wordpress: {
|
|
53
|
+
command: "node",
|
|
54
|
+
args: [path.resolve(projectDir, ".claude/mcp/wordpress-server.js")],
|
|
55
|
+
env: {
|
|
56
|
+
WORDPRESS_URL: process.env.WORDPRESS_URL,
|
|
57
|
+
WORDPRESS_USERNAME: process.env.WORDPRESS_USERNAME,
|
|
58
|
+
WORDPRESS_APP_PASSWORD: process.env.WORDPRESS_APP_PASSWORD,
|
|
59
|
+
WORDPRESS_USE_GUTENBERG: process.env.WORDPRESS_USE_GUTENBERG || "false"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// If .mcp.json already exists, merge with existing configuration
|
|
66
|
+
let existingConfig = {};
|
|
67
|
+
if (fs.existsSync(mcpConfigPath)) {
|
|
68
|
+
try {
|
|
69
|
+
existingConfig = JSON.parse(fs.readFileSync(mcpConfigPath, 'utf8'));
|
|
70
|
+
console.log('๐ Found existing .mcp.json file, merging configuration...');
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.warn('โ ๏ธ Existing .mcp.json file is invalid, creating new one...');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Merge configurations
|
|
77
|
+
const finalConfig = {
|
|
78
|
+
...existingConfig,
|
|
79
|
+
mcpServers: {
|
|
80
|
+
...existingConfig.mcpServers,
|
|
81
|
+
...mcpConfig.mcpServers
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Write MCP configuration file
|
|
86
|
+
fs.writeFileSync(mcpConfigPath, JSON.stringify(finalConfig, null, 2));
|
|
87
|
+
console.log('โ
Created .mcp.json configuration file');
|
|
88
|
+
|
|
89
|
+
// Set executable permissions on MCP server
|
|
90
|
+
try {
|
|
91
|
+
fs.chmodSync(mcpServerPath, 0o755);
|
|
92
|
+
console.log('โ
Set executable permissions on WordPress MCP server');
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.warn('โ ๏ธ Could not set executable permissions:', error.message);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Test MCP server startup
|
|
98
|
+
console.log('๐งช Testing MCP server startup...');
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const { spawn } = await import('child_process');
|
|
102
|
+
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const testProcess = spawn('node', [mcpServerPath], {
|
|
105
|
+
env: { ...process.env, ...mcpConfig.mcpServers.wordpress.env },
|
|
106
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
let stderr = '';
|
|
110
|
+
testProcess.stderr.on('data', (data) => {
|
|
111
|
+
stderr += data.toString();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Give the server 3 seconds to start up
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
testProcess.kill('SIGTERM');
|
|
117
|
+
|
|
118
|
+
if (stderr.includes('WordPress MCP Server running') || stderr.includes('Server running')) {
|
|
119
|
+
console.log('โ
MCP server startup test successful');
|
|
120
|
+
resolve(true);
|
|
121
|
+
} else if (stderr.includes('Error') || stderr.includes('Missing required environment')) {
|
|
122
|
+
console.error('โ MCP server startup failed:', stderr);
|
|
123
|
+
reject(new Error('MCP server failed to start'));
|
|
124
|
+
} else {
|
|
125
|
+
console.log('โ
MCP server appears to be working');
|
|
126
|
+
resolve(true);
|
|
127
|
+
}
|
|
128
|
+
}, 3000);
|
|
129
|
+
|
|
130
|
+
testProcess.on('error', (error) => {
|
|
131
|
+
reject(new Error(`Failed to start MCP server: ${error.message}`));
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
} catch (testError) {
|
|
135
|
+
console.warn('โ ๏ธ Could not test MCP server startup:', testError.message);
|
|
136
|
+
console.log(' MCP configuration created, but please test manually if needed');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
console.log('\n๐ WordPress MCP integration configured successfully!');
|
|
140
|
+
console.log('\n๐ Configuration Summary:');
|
|
141
|
+
console.log(` โข WordPress URL: ${process.env.WORDPRESS_URL}`);
|
|
142
|
+
console.log(` โข Username: ${process.env.WORDPRESS_USERNAME}`);
|
|
143
|
+
console.log(` โข Gutenberg mode: ${process.env.WORDPRESS_USE_GUTENBERG || 'false'}`);
|
|
144
|
+
console.log(` โข MCP config: ${mcpConfigPath}`);
|
|
145
|
+
console.log(` โข MCP server: ${mcpServerPath}`);
|
|
146
|
+
|
|
147
|
+
console.log('\n๐ Next steps:');
|
|
148
|
+
console.log(' 1. Restart Claude Code to load the new MCP configuration');
|
|
149
|
+
console.log(' 2. Use WordPress MCP tools in your agents and commands');
|
|
150
|
+
console.log(' 3. Test with: /myai-wordpress-admin or /myai-wordpress-publish');
|
|
151
|
+
|
|
152
|
+
return true;
|
|
153
|
+
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error('โ WordPress MCP configuration failed:', error.message);
|
|
156
|
+
console.log('\n๐ ๏ธ Troubleshooting:');
|
|
157
|
+
console.log(' โข Ensure WordPress credentials are configured in .env');
|
|
158
|
+
console.log(' โข Check that .claude/mcp/wordpress-server.js exists');
|
|
159
|
+
console.log(' โข Verify Node.js version is 18+ (required for MCP SDK)');
|
|
160
|
+
console.log(' โข Run: npm install to ensure dependencies are installed');
|
|
161
|
+
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Allow running as standalone script
|
|
167
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
168
|
+
configureWordPressMCP()
|
|
169
|
+
.then((success) => {
|
|
170
|
+
process.exit(success ? 0 : 1);
|
|
171
|
+
})
|
|
172
|
+
.catch((error) => {
|
|
173
|
+
console.error('Configuration script error:', error);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
});
|
|
176
|
+
}
|