myaidev-method 0.0.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.
@@ -0,0 +1,397 @@
1
+ import fetch from 'node-fetch';
2
+ import { WordPressMCP } from './wordpress-integration.js';
3
+
4
+ export class WordPressAdminMCP extends WordPressMCP {
5
+ constructor(config) {
6
+ super(config);
7
+ this.adminCapabilities = {
8
+ security: true,
9
+ performance: true,
10
+ health: true,
11
+ administration: true
12
+ };
13
+ }
14
+
15
+ // Security Operations
16
+ async securityScan() {
17
+ try {
18
+ const results = {
19
+ wordpress_version: await this.getWordPressVersion(),
20
+ plugins: await this.getPluginSecurityStatus(),
21
+ themes: await this.getThemeSecurityStatus(),
22
+ users: await this.getUserSecurityAudit(),
23
+ files: await this.getFilePermissionsScan(),
24
+ ssl: await this.getSSLStatus(),
25
+ security_headers: await this.getSecurityHeaders()
26
+ };
27
+
28
+ return {
29
+ success: true,
30
+ scan_type: 'comprehensive_security',
31
+ timestamp: new Date().toISOString(),
32
+ findings: this.analyzeSecurity(results),
33
+ recommendations: this.getSecurityRecommendations(results),
34
+ priority_issues: this.getPrioritySecurityIssues(results)
35
+ };
36
+ } catch (error) {
37
+ return {
38
+ success: false,
39
+ error: error.message,
40
+ scan_type: 'security_scan_failed'
41
+ };
42
+ }
43
+ }
44
+
45
+ async malwareCheck() {
46
+ try {
47
+ const suspiciousPatterns = [
48
+ 'eval\\(', 'base64_decode\\(', 'shell_exec\\(',
49
+ 'system\\(', 'exec\\(', 'passthru\\(',
50
+ '\\.php\\?[a-zA-Z0-9]+=\\w+', 'c99shell',
51
+ 'r57shell', 'wso\\.php'
52
+ ];
53
+
54
+ const results = await Promise.all([
55
+ this.scanPluginsForMalware(suspiciousPatterns),
56
+ this.scanThemesForMalware(suspiciousPatterns),
57
+ this.scanUploadsForMalware(suspiciousPatterns),
58
+ this.checkDatabaseForMalware()
59
+ ]);
60
+
61
+ return {
62
+ success: true,
63
+ scan_type: 'malware_detection',
64
+ timestamp: new Date().toISOString(),
65
+ threats_found: results.filter(r => r.threats.length > 0),
66
+ clean_areas: results.filter(r => r.threats.length === 0),
67
+ recommendations: this.getMalwareRecommendations(results)
68
+ };
69
+ } catch (error) {
70
+ return {
71
+ success: false,
72
+ error: error.message
73
+ };
74
+ }
75
+ }
76
+
77
+ async userSecurityAudit() {
78
+ try {
79
+ const users = await this.request('/users?per_page=100&context=edit');
80
+
81
+ const audit = users.map(user => ({
82
+ id: user.id,
83
+ username: user.username,
84
+ email: user.email,
85
+ roles: user.roles,
86
+ capabilities: user.capabilities,
87
+ last_login: user.meta?.last_login || 'unknown',
88
+ registration_date: user.registered_date,
89
+ security_flags: this.analyzeUserSecurity(user)
90
+ }));
91
+
92
+ return {
93
+ success: true,
94
+ audit_type: 'user_security',
95
+ timestamp: new Date().toISOString(),
96
+ total_users: users.length,
97
+ admin_users: audit.filter(u => u.roles.includes('administrator')),
98
+ suspicious_users: audit.filter(u => u.security_flags.length > 0),
99
+ recommendations: this.getUserSecurityRecommendations(audit)
100
+ };
101
+ } catch (error) {
102
+ return {
103
+ success: false,
104
+ error: error.message
105
+ };
106
+ }
107
+ }
108
+
109
+ // Performance Operations
110
+ async performanceAnalysis() {
111
+ try {
112
+ const metrics = await Promise.all([
113
+ this.analyzePageSpeed(),
114
+ this.analyzeDatabasePerformance(),
115
+ this.analyzePluginPerformance(),
116
+ this.analyzeMediaOptimization(),
117
+ this.analyzeCachingStatus()
118
+ ]);
119
+
120
+ return {
121
+ success: true,
122
+ analysis_type: 'performance_comprehensive',
123
+ timestamp: new Date().toISOString(),
124
+ overall_score: this.calculatePerformanceScore(metrics),
125
+ metrics: metrics,
126
+ recommendations: this.getPerformanceRecommendations(metrics),
127
+ priority_actions: this.getPerformancePriorityActions(metrics)
128
+ };
129
+ } catch (error) {
130
+ return {
131
+ success: false,
132
+ error: error.message
133
+ };
134
+ }
135
+ }
136
+
137
+ async databaseOptimization() {
138
+ try {
139
+ const operations = [];
140
+
141
+ // Get database statistics
142
+ const stats = await this.getDatabaseStats();
143
+
144
+ // Cleanup operations
145
+ const cleanupResults = await Promise.all([
146
+ this.cleanupRevisions(),
147
+ this.cleanupSpam(),
148
+ this.cleanupTrash(),
149
+ this.cleanupExpiredTransients(),
150
+ this.optimizeDatabaseTables()
151
+ ]);
152
+
153
+ return {
154
+ success: true,
155
+ operation: 'database_optimization',
156
+ timestamp: new Date().toISOString(),
157
+ before_stats: stats.before,
158
+ after_stats: await this.getDatabaseStats(),
159
+ operations_performed: cleanupResults,
160
+ space_saved: this.calculateSpaceSaved(stats),
161
+ recommendations: this.getDatabaseRecommendations()
162
+ };
163
+ } catch (error) {
164
+ return {
165
+ success: false,
166
+ error: error.message
167
+ };
168
+ }
169
+ }
170
+
171
+ // Health Operations
172
+ async healthCheck() {
173
+ try {
174
+ const healthChecks = await Promise.all([
175
+ this.checkWordPressUpdates(),
176
+ this.checkPluginUpdates(),
177
+ this.checkThemeUpdates(),
178
+ this.checkFilePermissions(),
179
+ this.checkDiskSpace(),
180
+ this.checkMemoryUsage(),
181
+ this.checkDatabaseHealth(),
182
+ this.checkCronJobs(),
183
+ this.checkErrorLogs()
184
+ ]);
185
+
186
+ const overallHealth = this.calculateHealthScore(healthChecks);
187
+
188
+ return {
189
+ success: true,
190
+ check_type: 'comprehensive_health',
191
+ timestamp: new Date().toISOString(),
192
+ overall_health: overallHealth,
193
+ checks: healthChecks,
194
+ critical_issues: healthChecks.filter(c => c.status === 'critical'),
195
+ warnings: healthChecks.filter(c => c.status === 'warning'),
196
+ recommendations: this.getHealthRecommendations(healthChecks)
197
+ };
198
+ } catch (error) {
199
+ return {
200
+ success: false,
201
+ error: error.message
202
+ };
203
+ }
204
+ }
205
+
206
+ async errorLogAnalysis() {
207
+ try {
208
+ // This would require server-level access or plugin integration
209
+ const errorSources = [
210
+ 'php_errors',
211
+ 'wordpress_debug',
212
+ 'plugin_errors',
213
+ 'theme_errors',
214
+ 'database_errors'
215
+ ];
216
+
217
+ const errorAnalysis = await Promise.all(
218
+ errorSources.map(source => this.analyzeErrorSource(source))
219
+ );
220
+
221
+ return {
222
+ success: true,
223
+ analysis_type: 'error_log',
224
+ timestamp: new Date().toISOString(),
225
+ error_summary: this.summarizeErrors(errorAnalysis),
226
+ critical_errors: errorAnalysis.filter(e => e.severity === 'critical'),
227
+ frequent_errors: this.getFrequentErrors(errorAnalysis),
228
+ recommendations: this.getErrorRecommendations(errorAnalysis)
229
+ };
230
+ } catch (error) {
231
+ return {
232
+ success: false,
233
+ error: error.message
234
+ };
235
+ }
236
+ }
237
+
238
+ // Admin Operations
239
+ async pluginManagement(operation, pluginSlug = null) {
240
+ try {
241
+ switch (operation) {
242
+ case 'list':
243
+ return await this.getInstalledPlugins();
244
+
245
+ case 'security_check':
246
+ return await this.checkPluginsSecurity();
247
+
248
+ case 'update_available':
249
+ return await this.getPluginUpdates();
250
+
251
+ case 'activate':
252
+ return await this.activatePlugin(pluginSlug);
253
+
254
+ case 'deactivate':
255
+ return await this.deactivatePlugin(pluginSlug);
256
+
257
+ case 'delete':
258
+ return await this.deletePlugin(pluginSlug);
259
+
260
+ default:
261
+ throw new Error(`Unknown plugin operation: ${operation}`);
262
+ }
263
+ } catch (error) {
264
+ return {
265
+ success: false,
266
+ error: error.message
267
+ };
268
+ }
269
+ }
270
+
271
+ async contentCleanup() {
272
+ try {
273
+ const cleanup = await Promise.all([
274
+ this.cleanupSpamComments(),
275
+ this.cleanupDraftPosts(),
276
+ this.cleanupUnusedMedia(),
277
+ this.cleanupOrphanedMetadata(),
278
+ this.cleanupExpiredTransients()
279
+ ]);
280
+
281
+ return {
282
+ success: true,
283
+ operation: 'content_cleanup',
284
+ timestamp: new Date().toISOString(),
285
+ cleanup_results: cleanup,
286
+ total_items_cleaned: cleanup.reduce((sum, result) => sum + result.items_cleaned, 0),
287
+ space_freed: cleanup.reduce((sum, result) => sum + result.space_freed, 0)
288
+ };
289
+ } catch (error) {
290
+ return {
291
+ success: false,
292
+ error: error.message
293
+ };
294
+ }
295
+ }
296
+
297
+ // Helper methods for analysis
298
+ analyzeSecurity(results) {
299
+ const findings = {
300
+ critical: [],
301
+ warnings: [],
302
+ passed: []
303
+ };
304
+
305
+ // Analyze WordPress version
306
+ if (results.wordpress_version.outdated) {
307
+ findings.critical.push('WordPress version is outdated');
308
+ }
309
+
310
+ // Analyze plugins
311
+ results.plugins.vulnerable.forEach(plugin => {
312
+ findings.critical.push(`Vulnerable plugin detected: ${plugin.name}`);
313
+ });
314
+
315
+ // Analyze users
316
+ results.users.admin_accounts.forEach(user => {
317
+ if (user.weak_password) {
318
+ findings.warnings.push(`Weak password for admin user: ${user.username}`);
319
+ }
320
+ });
321
+
322
+ return findings;
323
+ }
324
+
325
+ getSecurityRecommendations(results) {
326
+ const recommendations = [];
327
+
328
+ if (results.wordpress_version.outdated) {
329
+ recommendations.push({
330
+ priority: 'high',
331
+ action: 'Update WordPress to latest version',
332
+ impact: 'Critical security patches'
333
+ });
334
+ }
335
+
336
+ return recommendations;
337
+ }
338
+
339
+ calculateHealthScore(checks) {
340
+ const totalChecks = checks.length;
341
+ const passedChecks = checks.filter(c => c.status === 'passed').length;
342
+ const warningChecks = checks.filter(c => c.status === 'warning').length;
343
+
344
+ // Weighted scoring: passed = 1, warning = 0.5, critical = 0
345
+ const score = ((passedChecks * 1) + (warningChecks * 0.5)) / totalChecks * 100;
346
+
347
+ return {
348
+ score: Math.round(score),
349
+ grade: this.getHealthGrade(score),
350
+ total_checks: totalChecks,
351
+ passed: passedChecks,
352
+ warnings: warningChecks,
353
+ critical: checks.filter(c => c.status === 'critical').length
354
+ };
355
+ }
356
+
357
+ getHealthGrade(score) {
358
+ if (score >= 90) return 'A';
359
+ if (score >= 80) return 'B';
360
+ if (score >= 70) return 'C';
361
+ if (score >= 60) return 'D';
362
+ return 'F';
363
+ }
364
+
365
+ // Placeholder methods (would need actual implementation based on access level)
366
+ async getWordPressVersion() {
367
+ // Implementation would check WP version against latest
368
+ return { current: '6.3.1', latest: '6.4.0', outdated: true };
369
+ }
370
+
371
+ async getPluginSecurityStatus() {
372
+ // Implementation would check plugins against vulnerability databases
373
+ return { total: 15, vulnerable: [], outdated: [] };
374
+ }
375
+
376
+ async scanPluginsForMalware(patterns) {
377
+ // Implementation would scan plugin files for suspicious patterns
378
+ return { location: 'plugins', threats: [], files_scanned: 0 };
379
+ }
380
+
381
+ async checkDatabaseForMalware() {
382
+ // Implementation would scan database for malicious content
383
+ return { location: 'database', threats: [], tables_scanned: 0 };
384
+ }
385
+
386
+ async analyzePageSpeed() {
387
+ // Implementation would use external APIs like PageSpeed Insights
388
+ return { score: 85, metrics: {} };
389
+ }
390
+
391
+ async getDatabaseStats() {
392
+ // Implementation would query database size and optimization stats
393
+ return { size_mb: 125, tables: 50, optimized: false };
394
+ }
395
+ }
396
+
397
+ export default WordPressAdminMCP;
@@ -0,0 +1,218 @@
1
+ import fetch from 'node-fetch';
2
+
3
+ export class WordPressMCP {
4
+ constructor(config) {
5
+ this.baseUrl = config.endpoint.url;
6
+ this.apiPath = `/wp-json/${config.endpoint.api_version}`;
7
+ this.auth = Buffer.from(`${config.endpoint.authentication.username}:${config.endpoint.authentication.password}`).toString('base64');
8
+ this.defaults = config.defaults;
9
+ }
10
+
11
+ async request(endpoint, method = 'GET', data = null) {
12
+ const options = {
13
+ method,
14
+ headers: {
15
+ 'Authorization': `Basic ${this.auth}`,
16
+ 'Content-Type': 'application/json'
17
+ }
18
+ };
19
+
20
+ if (data && method !== 'GET') {
21
+ options.body = JSON.stringify(data);
22
+ }
23
+
24
+ const response = await fetch(`${this.baseUrl}${this.apiPath}${endpoint}`, options);
25
+
26
+ if (!response.ok) {
27
+ const error = await response.text();
28
+ throw new Error(`WordPress API Error: ${response.status} - ${error}`);
29
+ }
30
+
31
+ return response.json();
32
+ }
33
+
34
+ async createPost(params) {
35
+ const postData = {
36
+ title: params.title,
37
+ content: params.content,
38
+ status: params.status || this.defaults.post_status,
39
+ categories: params.categories || [],
40
+ tags: params.tags || [],
41
+ format: params.format || this.defaults.format,
42
+ comment_status: params.comment_status || this.defaults.comment_status,
43
+ ping_status: params.ping_status || this.defaults.ping_status
44
+ };
45
+
46
+ if (params.excerpt) {
47
+ postData.excerpt = params.excerpt;
48
+ }
49
+
50
+ if (params.featured_media) {
51
+ postData.featured_media = params.featured_media;
52
+ }
53
+
54
+ if (params.meta) {
55
+ postData.meta = params.meta;
56
+ }
57
+
58
+ if (params.slug) {
59
+ postData.slug = params.slug;
60
+ }
61
+
62
+ return this.request('/posts', 'POST', postData);
63
+ }
64
+
65
+ async updatePost(id, params) {
66
+ const updateData = {};
67
+
68
+ if (params.title) updateData.title = params.title;
69
+ if (params.content) updateData.content = params.content;
70
+ if (params.status) updateData.status = params.status;
71
+ if (params.categories) updateData.categories = params.categories;
72
+ if (params.tags) updateData.tags = params.tags;
73
+ if (params.excerpt) updateData.excerpt = params.excerpt;
74
+ if (params.featured_media) updateData.featured_media = params.featured_media;
75
+ if (params.slug) updateData.slug = params.slug;
76
+
77
+ return this.request(`/posts/${id}`, 'POST', updateData);
78
+ }
79
+
80
+ async getPost(id, context = 'view') {
81
+ return this.request(`/posts/${id}?context=${context}`);
82
+ }
83
+
84
+ async listPosts(params = {}) {
85
+ const queryParams = new URLSearchParams();
86
+
87
+ if (params.per_page) queryParams.append('per_page', params.per_page);
88
+ if (params.page) queryParams.append('page', params.page);
89
+ if (params.status) queryParams.append('status', params.status);
90
+ if (params.search) queryParams.append('search', params.search);
91
+ if (params.categories) queryParams.append('categories', params.categories.join(','));
92
+ if (params.tags) queryParams.append('tags', params.tags.join(','));
93
+
94
+ const query = queryParams.toString();
95
+ return this.request(`/posts${query ? `?${query}` : ''}`);
96
+ }
97
+
98
+ async uploadMedia(file, metadata = {}) {
99
+ const formData = new FormData();
100
+ formData.append('file', file);
101
+
102
+ if (metadata.title) formData.append('title', metadata.title);
103
+ if (metadata.alt_text) formData.append('alt_text', metadata.alt_text);
104
+ if (metadata.caption) formData.append('caption', metadata.caption);
105
+ if (metadata.description) formData.append('description', metadata.description);
106
+
107
+ const response = await fetch(`${this.baseUrl}${this.apiPath}/media`, {
108
+ method: 'POST',
109
+ headers: {
110
+ 'Authorization': `Basic ${this.auth}`
111
+ },
112
+ body: formData
113
+ });
114
+
115
+ if (!response.ok) {
116
+ const error = await response.text();
117
+ throw new Error(`Media Upload Error: ${response.status} - ${error}`);
118
+ }
119
+
120
+ return response.json();
121
+ }
122
+
123
+ async createCategory(params) {
124
+ const categoryData = {
125
+ name: params.name,
126
+ slug: params.slug || params.name.toLowerCase().replace(/\s+/g, '-'),
127
+ description: params.description || ''
128
+ };
129
+
130
+ if (params.parent) {
131
+ categoryData.parent = params.parent;
132
+ }
133
+
134
+ return this.request('/categories', 'POST', categoryData);
135
+ }
136
+
137
+ async createTag(params) {
138
+ const tagData = {
139
+ name: params.name,
140
+ slug: params.slug || params.name.toLowerCase().replace(/\s+/g, '-'),
141
+ description: params.description || ''
142
+ };
143
+
144
+ return this.request('/tags', 'POST', tagData);
145
+ }
146
+
147
+ async getCategories() {
148
+ return this.request('/categories');
149
+ }
150
+
151
+ async getTags() {
152
+ return this.request('/tags');
153
+ }
154
+
155
+ // Helper method to publish content from content-writer agent
156
+ async publishContent(contentData) {
157
+ try {
158
+ // Create tags if they don't exist
159
+ const tags = [];
160
+ if (contentData.tags && contentData.tags.length > 0) {
161
+ for (const tagName of contentData.tags) {
162
+ try {
163
+ const tag = await this.createTag({ name: tagName });
164
+ tags.push(tag.id);
165
+ } catch (error) {
166
+ // Tag might already exist, try to find it
167
+ const existingTags = await this.getTags();
168
+ const found = existingTags.find(t => t.name.toLowerCase() === tagName.toLowerCase());
169
+ if (found) tags.push(found.id);
170
+ }
171
+ }
172
+ }
173
+
174
+ // Create category if it doesn't exist
175
+ let categoryId = null;
176
+ if (contentData.category) {
177
+ try {
178
+ const category = await this.createCategory({ name: contentData.category });
179
+ categoryId = category.id;
180
+ } catch (error) {
181
+ // Category might already exist
182
+ const existingCategories = await this.getCategories();
183
+ const found = existingCategories.find(c => c.name.toLowerCase() === contentData.category.toLowerCase());
184
+ if (found) categoryId = found.id;
185
+ }
186
+ }
187
+
188
+ // Prepare post data
189
+ const postParams = {
190
+ title: contentData.title,
191
+ content: contentData.content,
192
+ excerpt: contentData.meta_description,
193
+ slug: contentData.slug,
194
+ status: 'draft', // Always create as draft for review
195
+ tags: tags,
196
+ categories: categoryId ? [categoryId] : []
197
+ };
198
+
199
+ // Create the post
200
+ const post = await this.createPost(postParams);
201
+
202
+ return {
203
+ success: true,
204
+ post_id: post.id,
205
+ post_url: post.link,
206
+ edit_url: `${this.baseUrl}/wp-admin/post.php?post=${post.id}&action=edit`,
207
+ message: `Draft post created successfully. ID: ${post.id}`
208
+ };
209
+ } catch (error) {
210
+ return {
211
+ success: false,
212
+ error: error.message
213
+ };
214
+ }
215
+ }
216
+ }
217
+
218
+ export default WordPressMCP;