@wplaunchify/ml-mcp-server 2.6.0 → 2.6.2

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/build/server.js CHANGED
@@ -91,16 +91,16 @@ console.error(`✅ Registered ${registeredCount} of ${allTools.length} tools`);
91
91
  async function main() {
92
92
  const { logToFile } = await import('./wordpress.js');
93
93
  logToFile('Starting WordPress MCP server...');
94
- // Environment variables are passed by MCP client (Claude Desktop, Cursor, etc.)
95
- // Don't exit here - let initWordPress() handle the validation
94
+ // CRITICAL: DO NOT call initWordPress() during startup
95
+ // It will be called lazily on first tool execution
96
+ // This prevents blocking when multiple servers start simultaneously
96
97
  if (!process.env.WORDPRESS_API_URL) {
97
- logToFile('Warning: WORDPRESS_API_URL not set. Will fail on first tool call if not provided by MCP client.');
98
+ logToFile('Warning: WORDPRESS_API_URL not set. Will be initialized on first tool call.');
99
+ }
100
+ else {
101
+ logToFile('WORDPRESS_API_URL is set. Client will be initialized on first tool call.');
98
102
  }
99
103
  try {
100
- logToFile('Initializing WordPress client...');
101
- const { initWordPress } = await import('./wordpress.js');
102
- await initWordPress();
103
- logToFile('WordPress client initialized successfully.');
104
104
  logToFile('Setting up server transport...');
105
105
  const transport = new StdioServerTransport();
106
106
  await server.connect(transport);
@@ -108,7 +108,6 @@ async function main() {
108
108
  }
109
109
  catch (error) {
110
110
  logToFile(`Failed to initialize server: ${error}`);
111
- // Don't exit immediately - let the MCP client handle the error
112
111
  throw error;
113
112
  }
114
113
  }
@@ -16,14 +16,6 @@ export declare function makeWordPressRequest(method: string, endpoint: string, d
16
16
  isFormData?: boolean;
17
17
  rawResponse?: boolean;
18
18
  }): Promise<any>;
19
- /**
20
- * Detect which plugins are installed and active
21
- * Returns a set of plugin slugs that are active
22
- *
23
- * IMPORTANT: This function makes an HTTP request and should NOT block server startup.
24
- * It has a timeout and fails gracefully to prevent Claude Desktop crashes.
25
- */
26
- export declare function detectInstalledPlugins(): Promise<Set<string>>;
27
19
  /**
28
20
  * Make a request to the WordPress.org Plugin Repository API
29
21
  * @param searchQuery Search query string
@@ -42,10 +42,11 @@ export async function initWordPress() {
42
42
  };
43
43
  }
44
44
  wpClient = axios.create(config);
45
- // Optionally verify connection to WordPress API (don't crash if it fails)
46
- // This prevents startup crashes when multiple servers start simultaneously
47
- const skipInitCheck = process.env.SKIP_INIT_CHECK === 'true';
48
- if (!skipInitCheck) {
45
+ // CRITICAL: NO HTTP requests during startup to prevent Claude Desktop hangs
46
+ // Connection will be verified on first tool call instead
47
+ // Set VERIFY_CONNECTION_ON_STARTUP=true to enable startup verification (NOT recommended)
48
+ const verifyOnStartup = process.env.VERIFY_CONNECTION_ON_STARTUP === 'true';
49
+ if (verifyOnStartup) {
49
50
  try {
50
51
  await wpClient.get('');
51
52
  logToFile('Successfully connected to WordPress API');
@@ -57,7 +58,8 @@ export async function initWordPress() {
57
58
  }
58
59
  }
59
60
  else {
60
- logToFile('Skipping WordPress API connection verification (SKIP_INIT_CHECK=true)');
61
+ logToFile('Skipping WordPress API connection verification during startup (prevents Claude Desktop hangs)');
62
+ logToFile('Connection will be verified on first tool call.');
61
63
  }
62
64
  }
63
65
  // Configure logging
@@ -82,8 +84,10 @@ export function logToFile(message) {
82
84
  * @returns Response data
83
85
  */
84
86
  export async function makeWordPressRequest(method, endpoint, data, options) {
87
+ // Lazy initialization - initialize on first request if not already done
85
88
  if (!wpClient) {
86
- throw new Error('WordPress client not initialized');
89
+ logToFile('WordPress client not initialized, initializing now...');
90
+ await initWordPress();
87
91
  }
88
92
  // Log data (skip for FormData which can't be stringified)
89
93
  if (!options?.isFormData) {
@@ -145,52 +149,6 @@ Data: ${JSON.stringify(error.response?.data || {}, null, 2)}
145
149
  throw error;
146
150
  }
147
151
  }
148
- /**
149
- * Detect which plugins are installed and active
150
- * Returns a set of plugin slugs that are active
151
- *
152
- * IMPORTANT: This function makes an HTTP request and should NOT block server startup.
153
- * It has a timeout and fails gracefully to prevent Claude Desktop crashes.
154
- */
155
- export async function detectInstalledPlugins() {
156
- const installedPlugins = new Set();
157
- // Check if plugin detection should be skipped
158
- const skipDetection = process.env.SKIP_PLUGIN_DETECTION === 'true';
159
- if (skipDetection) {
160
- logToFile('Plugin detection skipped (SKIP_PLUGIN_DETECTION=true)');
161
- return installedPlugins; // Return empty set - will load all tools
162
- }
163
- try {
164
- // Add timeout to prevent blocking server startup
165
- const timeoutMs = 3000; // 3 seconds max
166
- const timeoutPromise = new Promise((_, reject) => {
167
- setTimeout(() => reject(new Error('Plugin detection timeout')), timeoutMs);
168
- });
169
- const detectionPromise = (async () => {
170
- // Get list of active plugins
171
- const response = await makeWordPressRequest('GET', 'wp/v2/plugins', { status: 'active' });
172
- if (Array.isArray(response)) {
173
- response.forEach((plugin) => {
174
- // Extract plugin slug from plugin path (e.g., "fluent-crm/fluent-crm.php" -> "fluent-crm")
175
- const slug = plugin.plugin?.split('/')[0] || plugin.slug;
176
- if (slug) {
177
- installedPlugins.add(slug);
178
- }
179
- });
180
- }
181
- return installedPlugins;
182
- })();
183
- // Race between detection and timeout
184
- await Promise.race([detectionPromise, timeoutPromise]);
185
- logToFile(`✓ Detected active plugins: ${Array.from(installedPlugins).join(', ')}`);
186
- }
187
- catch (error) {
188
- // Silently fail - if we can't detect plugins, we'll load all tools
189
- // This prevents server crashes when WordPress is slow or endpoint requires auth
190
- logToFile(`Plugin detection failed (will load all tools): ${error.message}`);
191
- }
192
- return installedPlugins;
193
- }
194
152
  /**
195
153
  * Make a request to the WordPress.org Plugin Repository API
196
154
  * @param searchQuery Search query string
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wplaunchify/ml-mcp-server",
3
- "version": "2.6.0",
3
+ "version": "2.6.2",
4
4
  "description": "Universal MCP Server for WordPress + Fluent Suite (Community, CRM, Cart) + FluentMCP Pro. Comprehensive tools for AI-powered WordPress management via Claude, Cursor, and other MCP clients.",
5
5
  "type": "module",
6
6
  "main": "./build/server.js",