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.
@@ -0,0 +1,12 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm version:*)",
5
+ "Bash(node:*)",
6
+ "mcp__sequential-thinking__sequentialthinking",
7
+ "WebFetch(domain:github.com)"
8
+ ],
9
+ "deny": [],
10
+ "ask": []
11
+ }
12
+ }
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # MyAIDev Method
2
2
 
3
- > **🚀 The easiest way to supercharge your AI CLI with professional agents and WordPress integration**
3
+ > **🚀 The easiest way to supercharge your AI CLI with professional agents and get real work done!**
4
4
 
5
- A comprehensive package for AI CLI tools (Claude Code, Gemini CLI, Codex CLI) that provides custom subagents and MCP integrations for enhanced development workflows. **Zero setup required** - just run one command and start creating professional content!
5
+ A comprehensive package for AI CLI tools (Claude Code, Gemini CLI, Codex CLI) that provides custom subagents and MCP integrations for enhanced development workflows. **Zero code required** - just run one command and start creating professional content!
6
6
 
7
7
  **✨ What makes this special:**
8
8
  - **Instant setup**: One `npx` command and you're ready
9
9
  - **Professional agents**: Content writer and WordPress admin out-of-the-box
10
- - **Claude Code native**: Follows official standards for maximum compatibility
11
- - **No dependencies**: Works standalone, WordPress integration is optional
10
+ - **Claude Code native**: Follows official standards for maximum compatibility, with Gemini and OpenAI Codex CLI too.
11
+ - **No dependencies**: Works standalone, leverages MCPs for WordPress, Notion, Google Workspace integration is optional
12
12
 
13
13
  ## 📋 Table of Contents
14
14
 
package/bin/cli.js CHANGED
@@ -99,10 +99,12 @@ async function setupClaude(projectDir) {
99
99
  const claudeDir = path.join(projectDir, '.claude');
100
100
  const commandsDir = path.join(claudeDir, 'commands');
101
101
  const agentsDir = path.join(claudeDir, 'agents');
102
+ const mcpDir = path.join(claudeDir, 'mcp');
102
103
 
103
104
  // Ensure directories exist
104
105
  await fs.ensureDir(commandsDir);
105
106
  await fs.ensureDir(agentsDir);
107
+ await fs.ensureDir(mcpDir);
106
108
 
107
109
  // Copy command markdown files
108
110
  const templateCommandsDir = path.join(__dirname, '..', 'src', 'templates', 'claude', 'commands');
@@ -132,6 +134,20 @@ async function setupClaude(projectDir) {
132
134
  }
133
135
  }
134
136
 
137
+ // Copy MCP server files
138
+ const templateMcpDir = path.join(__dirname, '..', '.claude', 'mcp');
139
+ if (await fs.pathExists(templateMcpDir)) {
140
+ const mcpFiles = await fs.readdir(templateMcpDir);
141
+ for (const file of mcpFiles) {
142
+ if (file.endsWith('.js') || file.endsWith('.json')) {
143
+ await fs.copy(
144
+ path.join(templateMcpDir, file),
145
+ path.join(mcpDir, file)
146
+ );
147
+ }
148
+ }
149
+ }
150
+
135
151
  // Create CLAUDE.md configuration file
136
152
  const claudeMd = `# Claude Code Configuration
137
153
 
@@ -197,21 +213,8 @@ DEFAULT_TONE=professional
197
213
 
198
214
  await fs.writeFile(path.join(projectDir, '.env.example'), envExample);
199
215
 
200
- // Create WordPress MCP server file
201
- const mcpDir = path.join(claudeDir, 'mcp');
202
- await fs.ensureDir(mcpDir);
203
-
204
- const wordpressMcpServer = path.join(__dirname, '..', 'src', 'mcp', 'wordpress-integration.js');
205
- if (await fs.pathExists(wordpressMcpServer)) {
206
- await fs.copy(wordpressMcpServer, path.join(mcpDir, 'wordpress-server.js'));
207
- }
208
-
209
- // Copy Gutenberg converter
210
- const gutenbergConverter = path.join(__dirname, '..', 'src', 'mcp', 'gutenberg-converter.js');
211
- if (await fs.pathExists(gutenbergConverter)) {
212
- await fs.copy(gutenbergConverter, path.join(mcpDir, 'gutenberg-converter.js'));
213
- }
214
-
216
+ // Note: MCP integration disabled for now - using native tools for WordPress REST API
217
+
215
218
  // Copy USER_GUIDE.md - Essential for users to understand customization
216
219
  const userGuide = path.join(__dirname, '..', 'USER_GUIDE.md');
217
220
  if (await fs.pathExists(userGuide)) {
@@ -0,0 +1,447 @@
1
+ /**
2
+ * Gutenberg Block Converter
3
+ * Converts HTML/Markdown content to WordPress Gutenberg block format
4
+ * Following WordPress Block Editor Handbook specifications
5
+ */
6
+
7
+ export class GutenbergConverter {
8
+ /**
9
+ * Convert HTML content to Gutenberg blocks
10
+ * @param {string} html - HTML content to convert
11
+ * @returns {string} - Gutenberg block formatted content
12
+ */
13
+ static htmlToGutenberg(html) {
14
+ // Parse HTML and convert to blocks
15
+ let gutenbergContent = '';
16
+
17
+ // Split content into sections for processing
18
+ const sections = this.parseHTMLSections(html);
19
+
20
+ sections.forEach(section => {
21
+ const block = this.createBlock(section);
22
+ if (block) {
23
+ gutenbergContent += block + '\n\n';
24
+ }
25
+ });
26
+
27
+ return gutenbergContent.trim();
28
+ }
29
+
30
+ /**
31
+ * Parse HTML into sections for block conversion
32
+ */
33
+ static parseHTMLSections(html) {
34
+ const sections = [];
35
+
36
+ // Remove excess whitespace and normalize
37
+ const normalizedHtml = html.replace(/\n\s*\n/g, '\n').trim();
38
+
39
+ // Regular expressions for different HTML elements
40
+ const patterns = {
41
+ heading: /<h([1-6])(?:\s[^>]*)?>(.+?)<\/h\1>/gi,
42
+ paragraph: /<p(?:\s[^>]*)?>(.+?)<\/p>/gi,
43
+ list: /<(ul|ol)(?:\s[^>]*)?>(.+?)<\/\1>/gis,
44
+ blockquote: /<blockquote(?:\s[^>]*)?>(.+?)<\/blockquote>/gis,
45
+ pre: /<pre(?:\s[^>]*)?><code(?:\s[^>]*)?>(.+?)<\/code><\/pre>/gis,
46
+ image: /<img\s+([^>]+)>/gi,
47
+ hr: /<hr(?:\s[^>]*)?>/gi
48
+ };
49
+
50
+ // Process the HTML string sequentially
51
+ let lastIndex = 0;
52
+ const processedParts = [];
53
+
54
+ // Create a combined pattern to find all blocks
55
+ const combinedPattern = new RegExp(
56
+ '(' +
57
+ '<h[1-6](?:\\s[^>]*)?>.*?</h[1-6]>|' +
58
+ '<p(?:\\s[^>]*)?>.*?</p>|' +
59
+ '<(?:ul|ol)(?:\\s[^>]*)?>.*?</(?:ul|ol)>|' +
60
+ '<blockquote(?:\\s[^>]*)?>.*?</blockquote>|' +
61
+ '<pre(?:\\s[^>]*)?><code(?:\\s[^>]*)?>.*?</code></pre>|' +
62
+ '<img\\s+[^>]+>|' +
63
+ '<hr(?:\\s[^>]*)?>' +
64
+ ')',
65
+ 'gis'
66
+ );
67
+
68
+ let match;
69
+ while ((match = combinedPattern.exec(normalizedHtml)) !== null) {
70
+ // Add any text between matches as a paragraph
71
+ if (match.index > lastIndex) {
72
+ const text = normalizedHtml.substring(lastIndex, match.index).trim();
73
+ if (text && !text.match(/^\s*$/)) {
74
+ sections.push({ type: 'paragraph', content: this.stripTags(text) });
75
+ }
76
+ }
77
+
78
+ const fullMatch = match[0];
79
+
80
+ // Determine block type and extract content
81
+ if (fullMatch.match(/<h([1-6])/i)) {
82
+ const level = fullMatch.match(/<h([1-6])/i)[1];
83
+ const content = fullMatch.replace(/<\/?h[1-6](?:\s[^>]*)?>/gi, '');
84
+ sections.push({ type: 'heading', level: parseInt(level), content: this.stripTags(content) });
85
+ }
86
+ else if (fullMatch.match(/<p(?:\s|>)/i)) {
87
+ const content = fullMatch.replace(/<\/?p(?:\s[^>]*)?>/gi, '');
88
+ sections.push({ type: 'paragraph', content: this.stripTags(content) });
89
+ }
90
+ else if (fullMatch.match(/<(ul|ol)/i)) {
91
+ const listType = fullMatch.match(/<(ul|ol)/i)[1];
92
+ const items = this.parseListItems(fullMatch);
93
+ sections.push({ type: 'list', ordered: listType === 'ol', items });
94
+ }
95
+ else if (fullMatch.match(/<blockquote/i)) {
96
+ const content = fullMatch.replace(/<\/?blockquote(?:\s[^>]*)?>/gi, '');
97
+ sections.push({ type: 'quote', content: this.stripTags(content) });
98
+ }
99
+ else if (fullMatch.match(/<pre/i)) {
100
+ const content = fullMatch.replace(/<\/?(?:pre|code)(?:\s[^>]*)?>/gi, '');
101
+ sections.push({ type: 'code', content: this.decodeHtml(content) });
102
+ }
103
+ else if (fullMatch.match(/<img/i)) {
104
+ const attrs = this.parseImageAttributes(fullMatch);
105
+ sections.push({ type: 'image', ...attrs });
106
+ }
107
+ else if (fullMatch.match(/<hr/i)) {
108
+ sections.push({ type: 'separator' });
109
+ }
110
+
111
+ lastIndex = match.index + fullMatch.length;
112
+ }
113
+
114
+ // Add any remaining content
115
+ if (lastIndex < normalizedHtml.length) {
116
+ const text = normalizedHtml.substring(lastIndex).trim();
117
+ if (text && !text.match(/^\s*$/)) {
118
+ sections.push({ type: 'paragraph', content: this.stripTags(text) });
119
+ }
120
+ }
121
+
122
+ return sections;
123
+ }
124
+
125
+ /**
126
+ * Parse list items from HTML list
127
+ */
128
+ static parseListItems(listHtml) {
129
+ const items = [];
130
+ const itemPattern = /<li(?:\s[^>]*)?>(.+?)<\/li>/gis;
131
+ let match;
132
+
133
+ while ((match = itemPattern.exec(listHtml)) !== null) {
134
+ items.push(this.stripTags(match[1].trim()));
135
+ }
136
+
137
+ return items;
138
+ }
139
+
140
+ /**
141
+ * Parse image attributes from img tag
142
+ */
143
+ static parseImageAttributes(imgTag) {
144
+ const attrs = {};
145
+
146
+ // Extract src
147
+ const srcMatch = imgTag.match(/src=["']([^"']+)["']/i);
148
+ if (srcMatch) attrs.url = srcMatch[1];
149
+
150
+ // Extract alt text
151
+ const altMatch = imgTag.match(/alt=["']([^"']+)["']/i);
152
+ if (altMatch) attrs.alt = altMatch[1];
153
+
154
+ // Extract title
155
+ const titleMatch = imgTag.match(/title=["']([^"']+)["']/i);
156
+ if (titleMatch) attrs.caption = titleMatch[1];
157
+
158
+ return attrs;
159
+ }
160
+
161
+ /**
162
+ * Create a Gutenberg block from a section
163
+ */
164
+ static createBlock(section) {
165
+ switch (section.type) {
166
+ case 'heading':
167
+ return this.createHeadingBlock(section.level, section.content);
168
+
169
+ case 'paragraph':
170
+ return this.createParagraphBlock(section.content);
171
+
172
+ case 'list':
173
+ return this.createListBlock(section.items, section.ordered);
174
+
175
+ case 'quote':
176
+ return this.createQuoteBlock(section.content);
177
+
178
+ case 'code':
179
+ return this.createCodeBlock(section.content);
180
+
181
+ case 'image':
182
+ return this.createImageBlock(section.url, section.alt, section.caption);
183
+
184
+ case 'separator':
185
+ return this.createSeparatorBlock();
186
+
187
+ default:
188
+ return this.createParagraphBlock(section.content || '');
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Create heading block
194
+ */
195
+ static createHeadingBlock(level, content) {
196
+ return `<!-- wp:heading {"level":${level}} -->
197
+ <h${level} class="wp-block-heading">${this.escapeHtml(content)}</h${level}>
198
+ <!-- /wp:heading -->`;
199
+ }
200
+
201
+ /**
202
+ * Create paragraph block
203
+ */
204
+ static createParagraphBlock(content) {
205
+ // Handle empty paragraphs
206
+ if (!content || content.trim() === '') {
207
+ return '';
208
+ }
209
+
210
+ return `<!-- wp:paragraph -->
211
+ <p>${this.escapeHtml(content)}</p>
212
+ <!-- /wp:paragraph -->`;
213
+ }
214
+
215
+ /**
216
+ * Create list block
217
+ */
218
+ static createListBlock(items, ordered = false) {
219
+ const tag = ordered ? 'ol' : 'ul';
220
+ const blockName = ordered ? 'list' : 'list';
221
+ const listItems = items.map(item => `<li>${this.escapeHtml(item)}</li>`).join('\n');
222
+
223
+ const attributes = ordered ? ' {"ordered":true}' : '';
224
+
225
+ return `<!-- wp:list${attributes} -->
226
+ <${tag} class="wp-block-list">${listItems}</${tag}>
227
+ <!-- /wp:list -->`;
228
+ }
229
+
230
+ /**
231
+ * Create quote block
232
+ */
233
+ static createQuoteBlock(content) {
234
+ return `<!-- wp:quote -->
235
+ <blockquote class="wp-block-quote">
236
+ <p>${this.escapeHtml(content)}</p>
237
+ </blockquote>
238
+ <!-- /wp:quote -->`;
239
+ }
240
+
241
+ /**
242
+ * Create code block
243
+ */
244
+ static createCodeBlock(code) {
245
+ // Escape the code content for HTML
246
+ const escapedCode = this.escapeHtml(code);
247
+
248
+ return `<!-- wp:code -->
249
+ <pre class="wp-block-code"><code>${escapedCode}</code></pre>
250
+ <!-- /wp:code -->`;
251
+ }
252
+
253
+ /**
254
+ * Create image block
255
+ */
256
+ static createImageBlock(url, alt = '', caption = '') {
257
+ let attributes = {};
258
+ if (alt) attributes.alt = alt;
259
+
260
+ const attributesJson = Object.keys(attributes).length > 0
261
+ ? ' ' + JSON.stringify(attributes)
262
+ : '';
263
+
264
+ let imageHtml = `<!-- wp:image${attributesJson} -->
265
+ <figure class="wp-block-image"><img src="${url}"${alt ? ` alt="${this.escapeHtml(alt)}"` : ''}/>`;
266
+
267
+ if (caption) {
268
+ imageHtml += `<figcaption class="wp-element-caption">${this.escapeHtml(caption)}</figcaption>`;
269
+ }
270
+
271
+ imageHtml += `</figure>
272
+ <!-- /wp:image -->`;
273
+
274
+ return imageHtml;
275
+ }
276
+
277
+ /**
278
+ * Create separator block
279
+ */
280
+ static createSeparatorBlock() {
281
+ return `<!-- wp:separator -->
282
+ <hr class="wp-block-separator has-alpha-channel-opacity"/>
283
+ <!-- /wp:separator -->`;
284
+ }
285
+
286
+ /**
287
+ * Create columns block for advanced layouts
288
+ */
289
+ static createColumnsBlock(columns) {
290
+ const columnCount = columns.length;
291
+ let columnsHtml = `<!-- wp:columns {"columns":${columnCount}} -->\n<div class="wp-block-columns">`;
292
+
293
+ columns.forEach(column => {
294
+ columnsHtml += `\n<!-- wp:column -->\n<div class="wp-block-column">`;
295
+ columnsHtml += `\n${column}`;
296
+ columnsHtml += `\n</div>\n<!-- /wp:column -->`;
297
+ });
298
+
299
+ columnsHtml += `\n</div>\n<!-- /wp:columns -->`;
300
+ return columnsHtml;
301
+ }
302
+
303
+ /**
304
+ * Create button block
305
+ */
306
+ static createButtonBlock(text, url = '#', align = 'none') {
307
+ return `<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"${align}"}} -->
308
+ <div class="wp-block-buttons">
309
+ <!-- wp:button -->
310
+ <div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="${url}">${this.escapeHtml(text)}</a></div>
311
+ <!-- /wp:button -->
312
+ </div>
313
+ <!-- /wp:buttons -->`;
314
+ }
315
+
316
+ /**
317
+ * Create table block
318
+ */
319
+ static createTableBlock(headers, rows) {
320
+ let tableHtml = `<!-- wp:table -->
321
+ <figure class="wp-block-table"><table class="wp-block-table">`;
322
+
323
+ // Add headers
324
+ if (headers && headers.length > 0) {
325
+ tableHtml += '\n<thead>\n<tr>';
326
+ headers.forEach(header => {
327
+ tableHtml += `<th>${this.escapeHtml(header)}</th>`;
328
+ });
329
+ tableHtml += '</tr>\n</thead>';
330
+ }
331
+
332
+ // Add rows
333
+ tableHtml += '\n<tbody>';
334
+ rows.forEach(row => {
335
+ tableHtml += '\n<tr>';
336
+ row.forEach(cell => {
337
+ tableHtml += `<td>${this.escapeHtml(cell)}</td>`;
338
+ });
339
+ tableHtml += '</tr>';
340
+ });
341
+ tableHtml += '\n</tbody>';
342
+
343
+ tableHtml += `\n</table></figure>
344
+ <!-- /wp:table -->`;
345
+
346
+ return tableHtml;
347
+ }
348
+
349
+ /**
350
+ * Utility: Strip HTML tags from text
351
+ */
352
+ static stripTags(text) {
353
+ return text.replace(/<[^>]+>/g, '').trim();
354
+ }
355
+
356
+ /**
357
+ * Utility: Escape HTML special characters
358
+ */
359
+ static escapeHtml(text) {
360
+ const map = {
361
+ '&': '&amp;',
362
+ '<': '&lt;',
363
+ '>': '&gt;',
364
+ '"': '&quot;',
365
+ "'": '&#x27;',
366
+ "/": '&#x2F;'
367
+ };
368
+
369
+ return text.replace(/[&<>"'/]/g, char => map[char]);
370
+ }
371
+
372
+ /**
373
+ * Utility: Decode HTML entities
374
+ */
375
+ static decodeHtml(text) {
376
+ const entities = {
377
+ '&amp;': '&',
378
+ '&lt;': '<',
379
+ '&gt;': '>',
380
+ '&quot;': '"',
381
+ '&#x27;': "'",
382
+ '&#x2F;': '/',
383
+ '&#39;': "'",
384
+ '&nbsp;': ' '
385
+ };
386
+
387
+ return text.replace(/&[#a-z0-9]+;/gi, entity => entities[entity] || entity);
388
+ }
389
+
390
+ /**
391
+ * Convert markdown to Gutenberg blocks (bonus feature)
392
+ */
393
+ static markdownToGutenberg(markdown) {
394
+ // First convert markdown to HTML (simplified version)
395
+ let html = markdown
396
+ // Headers
397
+ .replace(/^### (.+)$/gm, '<h3>$1</h3>')
398
+ .replace(/^## (.+)$/gm, '<h2>$1</h2>')
399
+ .replace(/^# (.+)$/gm, '<h1>$1</h1>')
400
+ // Bold
401
+ .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
402
+ // Italic
403
+ .replace(/\*(.+?)\*/g, '<em>$1</em>')
404
+ // Code blocks
405
+ .replace(/```[\s\S]*?```/g, match => {
406
+ const code = match.slice(3, -3).trim();
407
+ return `<pre><code>${code}</code></pre>`;
408
+ })
409
+ // Inline code
410
+ .replace(/`(.+?)`/g, '<code>$1</code>')
411
+ // Blockquotes
412
+ .replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>')
413
+ // Horizontal rules
414
+ .replace(/^---$/gm, '<hr>')
415
+ // Lists (simplified)
416
+ .replace(/^- (.+)$/gm, '<li>$1</li>')
417
+ .replace(/^(\d+)\. (.+)$/gm, '<li>$2</li>');
418
+
419
+ // Wrap consecutive li elements in ul/ol
420
+ html = html.replace(/(<li>.*<\/li>\n?)+/g, match => {
421
+ return `<ul>${match}</ul>`;
422
+ });
423
+
424
+ // Convert paragraphs
425
+ const lines = html.split('\n');
426
+ const processedLines = [];
427
+ let inBlock = false;
428
+
429
+ lines.forEach(line => {
430
+ const trimmed = line.trim();
431
+ if (trimmed === '') {
432
+ inBlock = false;
433
+ } else if (!trimmed.startsWith('<')) {
434
+ processedLines.push(`<p>${trimmed}</p>`);
435
+ } else {
436
+ processedLines.push(trimmed);
437
+ }
438
+ });
439
+
440
+ html = processedLines.join('\n');
441
+
442
+ // Now convert HTML to Gutenberg
443
+ return this.htmlToGutenberg(html);
444
+ }
445
+ }
446
+
447
+ export default GutenbergConverter;
@@ -0,0 +1,101 @@
1
+ {
2
+ "server": {
3
+ "name": "myaidev-wordpress-mcp-server",
4
+ "version": "2.0.0",
5
+ "description": "Enhanced WordPress MCP Server with session management and memory persistence",
6
+ "mcpName": "io.github.myaione/myaidev-method",
7
+ "transport": "stdio"
8
+ },
9
+ "tools": [
10
+ {
11
+ "name": "wp_session_create",
12
+ "description": "Create a new session for tracking operations and maintaining context",
13
+ "category": "session_management"
14
+ },
15
+ {
16
+ "name": "wp_session_status",
17
+ "description": "Get current session information and operation history",
18
+ "category": "session_management"
19
+ },
20
+ {
21
+ "name": "wp_memory_store",
22
+ "description": "Store data in memory for persistence across operations",
23
+ "category": "memory_management"
24
+ },
25
+ {
26
+ "name": "wp_memory_retrieve",
27
+ "description": "Retrieve stored data from memory",
28
+ "category": "memory_management"
29
+ },
30
+ {
31
+ "name": "wp_memory_list",
32
+ "description": "List all stored data in a namespace",
33
+ "category": "memory_management"
34
+ },
35
+ {
36
+ "name": "wp_health_check",
37
+ "description": "Comprehensive health check of WordPress site and MCP server",
38
+ "category": "health_monitoring"
39
+ },
40
+ {
41
+ "name": "wp_get_site_info",
42
+ "description": "Get WordPress site statistics, version, and health information",
43
+ "category": "wordpress_operations"
44
+ },
45
+ {
46
+ "name": "wp_create_post",
47
+ "description": "Create a new WordPress post or page with enhanced tracking and validation",
48
+ "category": "wordpress_operations"
49
+ },
50
+ {
51
+ "name": "wp_update_post",
52
+ "description": "Update an existing WordPress post",
53
+ "category": "wordpress_operations"
54
+ },
55
+ {
56
+ "name": "wp_delete_post",
57
+ "description": "Delete a WordPress post (move to trash)",
58
+ "category": "wordpress_operations"
59
+ },
60
+ {
61
+ "name": "wp_list_posts",
62
+ "description": "Get posts with filtering options",
63
+ "category": "wordpress_operations"
64
+ },
65
+ {
66
+ "name": "wp_batch_publish",
67
+ "description": "Publish multiple posts from markdown files with enhanced tracking",
68
+ "category": "batch_operations"
69
+ }
70
+ ],
71
+ "capabilities": [
72
+ "session_management",
73
+ "memory_persistence",
74
+ "health_monitoring",
75
+ "wordpress_integration",
76
+ "batch_operations",
77
+ "gutenberg_support",
78
+ "error_tracking"
79
+ ],
80
+ "environment": {
81
+ "required": [
82
+ "WORDPRESS_URL",
83
+ "WORDPRESS_USERNAME",
84
+ "WORDPRESS_APP_PASSWORD"
85
+ ],
86
+ "optional": [
87
+ "WORDPRESS_USE_GUTENBERG"
88
+ ]
89
+ },
90
+ "installation": {
91
+ "command": "npm install myaidev-method",
92
+ "global_command": "npm install -g myaidev-method",
93
+ "setup_command": "npx myaidev-method init --claude"
94
+ },
95
+ "usage": {
96
+ "start_server": "npm run mcp:start",
97
+ "health_check": "npm run mcp:health",
98
+ "status_check": "npm run mcp:status",
99
+ "publish_command": "/myai-wordpress-publish \"your-file.md\" --status draft"
100
+ }
101
+ }