@rishibhushan/jenkins-mcp-server 1.0.4 → 1.0.6

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.
Files changed (2) hide show
  1. package/bin/jenkins-mcp.js +81 -70
  2. package/package.json +2 -1
@@ -30,9 +30,10 @@ const colors = {
30
30
  };
31
31
 
32
32
  function log(message, color = 'reset') {
33
- const colorCode = process.stdout.isTTY ? colors[color] : '';
34
- const resetCode = process.stdout.isTTY ? colors.reset : '';
35
- console.log(`${colorCode}${message}${resetCode}`);
33
+ const colorCode = process.stderr.isTTY ? colors[color] : '';
34
+ const resetCode = process.stderr.isTTY ? colors.reset : '';
35
+ // CRITICAL: Use stderr for all output, stdout is for JSON-RPC only
36
+ console.error(`${colorCode}${message}${resetCode}`);
36
37
  }
37
38
 
38
39
  function error(message) {
@@ -161,81 +162,75 @@ function dependenciesInstalled(pipPath) {
161
162
  */
162
163
  function installDependencies(venvPath) {
163
164
  const { pip } = getVenvPaths(venvPath);
165
+ const wheelsPath = path.join(projectRoot, 'wheels');
164
166
  const requirementsPath = path.join(projectRoot, 'requirements.txt');
165
167
 
166
- if (!fs.existsSync(requirementsPath)) {
167
- error('requirements.txt not found');
168
- console.error(`Expected at: ${requirementsPath}`);
169
- process.exit(1);
170
- }
171
-
172
- log('Installing Python dependencies...', 'yellow');
173
- log('This may take a minute...', 'blue');
174
-
175
- // Build pip install command with proxy-friendly options
176
- const pipArgs = ['install', '-r', requirementsPath];
177
-
178
- // Add proxy-friendly options to handle corporate networks
179
- const proxyFriendlyArgs = [
180
- '--trusted-host', 'pypi.org',
181
- '--trusted-host', 'pypi.python.org',
182
- '--trusted-host', 'files.pythonhosted.org'
183
- ];
184
-
185
- // Add proxy if environment variable is set
186
- const proxy = process.env.HTTP_PROXY || process.env.http_proxy ||
187
- process.env.HTTPS_PROXY || process.env.https_proxy;
188
-
189
- if (proxy) {
190
- log(`Using proxy: ${proxy}`, 'blue');
191
- pipArgs.push('--proxy', proxy);
192
- }
168
+ console.error('Installing Python dependencies...');
169
+
170
+ // Check if wheels directory exists (pre-packaged wheels)
171
+ if (fs.existsSync(wheelsPath)) {
172
+ console.error('Using pre-packaged wheels (no internet required)...');
173
+
174
+ // Install from local wheels (fast, no network needed)
175
+ const installReqs = spawnSync(pip, [
176
+ 'install',
177
+ '--no-index', // Don't use PyPI
178
+ '--find-links', wheelsPath, // Use local wheels
179
+ '-r', requirementsPath
180
+ ], {
181
+ cwd: projectRoot,
182
+ stdio: 'inherit'
183
+ });
193
184
 
194
- // Add all proxy-friendly args
195
- pipArgs.push(...proxyFriendlyArgs);
185
+ if (installReqs.status !== 0) {
186
+ error('Failed to install from wheels');
187
+ process.exit(1);
188
+ }
189
+ } else {
190
+ // Fallback to normal install with proxy support
191
+ console.error('Downloading from PyPI...');
192
+ const pipArgs = ['install', '-r', requirementsPath];
193
+
194
+ const proxyFriendlyArgs = [
195
+ '--trusted-host', 'pypi.org',
196
+ '--trusted-host', 'pypi.python.org',
197
+ '--trusted-host', 'files.pythonhosted.org'
198
+ ];
199
+
200
+ const proxy = process.env.HTTP_PROXY || process.env.http_proxy;
201
+ if (proxy) {
202
+ pipArgs.push('--proxy', proxy);
203
+ }
204
+ pipArgs.push(...proxyFriendlyArgs);
196
205
 
197
- // Install requirements
198
- const installReqs = spawnSync(pip, pipArgs, {
199
- cwd: projectRoot,
200
- stdio: 'inherit'
201
- });
206
+ const installReqs = spawnSync(pip, pipArgs, {
207
+ cwd: projectRoot,
208
+ stdio: 'inherit'
209
+ });
202
210
 
203
- if (installReqs.status !== 0) {
204
- error('Failed to install dependencies from requirements.txt');
205
- console.error('\nTroubleshooting:');
206
- console.error(' 1. Check your internet connection');
207
- console.error(' 2. If behind a proxy, set HTTP_PROXY/HTTPS_PROXY env vars');
208
- console.error(' 3. Try manually: .venv/bin/pip install -r requirements.txt');
209
- process.exit(1);
211
+ if (installReqs.status !== 0) {
212
+ error('Failed to install dependencies');
213
+ process.exit(1);
214
+ }
210
215
  }
211
216
 
212
- log('✓ Requirements installed', 'green');
213
-
214
- // Install the package itself in editable mode
215
- log('Installing jenkins-mcp-server package...', 'yellow');
217
+ console.error('✓ Requirements installed');
216
218
 
219
+ // Install package itself
220
+ console.error('Installing jenkins-mcp-server package...');
217
221
  const packageArgs = ['install', '-e', '.'];
218
222
 
219
- // Add same proxy-friendly options
220
- if (proxy) {
221
- packageArgs.push('--proxy', proxy);
222
- }
223
- packageArgs.push(...proxyFriendlyArgs);
224
-
225
223
  const installPkg = spawnSync(pip, packageArgs, {
226
224
  cwd: projectRoot,
227
225
  stdio: 'inherit'
228
226
  });
229
227
 
230
228
  if (installPkg.status !== 0) {
231
- error('Failed to install jenkins-mcp-server package');
232
- console.error('\nTroubleshooting:');
233
- console.error(' 1. Ensure pyproject.toml or setup.py exists');
234
- console.error(' 2. Try manually: .venv/bin/pip install -e .');
229
+ error('Failed to install package');
235
230
  process.exit(1);
236
231
  }
237
232
 
238
- log('✓ Package installed', 'green');
233
+ console.error('✓ Package installed');
239
234
  }
240
235
 
241
236
  /**
@@ -288,27 +283,43 @@ function runServer(venvPath) {
288
283
  const env = {
289
284
  ...process.env,
290
285
  PYTHONPATH: path.join(projectRoot, 'src'),
291
- PYTHONUNBUFFERED: '1' // Ensure output is not buffered
286
+ PYTHONUNBUFFERED: '1'
292
287
  };
293
288
 
294
289
  const serverArgs = [...entryPoint.args, ...args];
295
290
 
291
+ // All logging to stderr (stdout reserved for JSON-RPC)
292
+ console.error('=== NODE WRAPPER DEBUG ===');
293
+ console.error('Project root:', projectRoot);
294
+ console.error('Python path:', python);
295
+ console.error('Entry point:', entryPoint);
296
+ console.error('Server args:', serverArgs);
297
+ console.error('PYTHONPATH:', env.PYTHONPATH);
298
+ console.error('=== ATTEMPTING TO START PYTHON ===');
299
+
296
300
  log('Starting Jenkins MCP Server...', 'green');
297
301
  log(`Command: ${python} ${serverArgs.join(' ')}`, 'blue');
298
302
 
303
+ // CRITICAL: stdin=pipe, stdout=inherit (for JSON-RPC), stderr=inherit (for logs)
299
304
  const server = spawn(python, serverArgs, {
300
305
  cwd: projectRoot,
301
- stdio: 'inherit',
306
+ stdio: ['pipe', 'inherit', 'inherit'],
302
307
  env: env,
303
308
  shell: isWindows
304
309
  });
305
310
 
306
311
  server.on('error', (err) => {
312
+ console.error('=== SPAWN ERROR ===', err);
307
313
  error(`Failed to start server: ${err.message}`);
308
314
  process.exit(1);
309
315
  });
310
316
 
311
- server.on('close', (code) => {
317
+ server.on('spawn', () => {
318
+ console.error('=== PYTHON PROCESS SPAWNED ===');
319
+ });
320
+
321
+ server.on('close', (code, signal) => {
322
+ console.error(`=== PYTHON PROCESS CLOSED: code=${code}, signal=${signal} ===`);
312
323
  if (code !== 0 && code !== null) {
313
324
  log(`Server exited with code ${code}`, 'yellow');
314
325
  }
@@ -337,14 +348,14 @@ function main() {
337
348
  try {
338
349
  // Check for help flag
339
350
  if (args.includes('--help') || args.includes('-h')) {
340
- console.log('Jenkins MCP Server - Node.js Wrapper');
341
- console.log('\nUsage: jenkins-mcp-server [options]');
342
- console.log('\nOptions:');
343
- console.log(' --env-file PATH Path to custom .env file');
344
- console.log(' --verbose, -v Enable verbose logging');
345
- console.log(' --no-vscode Skip loading VS Code settings');
346
- console.log(' --version Show version');
347
- console.log(' --help, -h Show this help message');
351
+ console.error('Jenkins MCP Server - Node.js Wrapper');
352
+ console.error('\nUsage: jenkins-mcp-server [options]');
353
+ console.error('\nOptions:');
354
+ console.error(' --env-file PATH Path to custom .env file');
355
+ console.error(' --verbose, -v Enable verbose logging');
356
+ console.error(' --no-vscode Skip loading VS Code settings');
357
+ console.error(' --version Show version');
358
+ console.error(' --help, -h Show this help message');
348
359
  process.exit(0);
349
360
  }
350
361
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rishibhushan/jenkins-mcp-server",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "AI-enabled Jenkins automation via Model Context Protocol (MCP)",
5
5
  "main": "bin/jenkins-mcp.js",
6
6
  "bin": {
@@ -15,6 +15,7 @@
15
15
  "bin/",
16
16
  "src/",
17
17
  "requirements.txt",
18
+ "wheels/",
18
19
  "README.md",
19
20
  "LICENSE"
20
21
  ],