@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.
- package/bin/jenkins-mcp.js +81 -70
- package/package.json +2 -1
package/bin/jenkins-mcp.js
CHANGED
|
@@ -30,9 +30,10 @@ const colors = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
function log(message, color = 'reset') {
|
|
33
|
-
const colorCode = process.
|
|
34
|
-
const resetCode = process.
|
|
35
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
//
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
195
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
});
|
|
206
|
+
const installReqs = spawnSync(pip, pipArgs, {
|
|
207
|
+
cwd: projectRoot,
|
|
208
|
+
stdio: 'inherit'
|
|
209
|
+
});
|
|
202
210
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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'
|
|
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('
|
|
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.
|
|
341
|
-
console.
|
|
342
|
-
console.
|
|
343
|
-
console.
|
|
344
|
-
console.
|
|
345
|
-
console.
|
|
346
|
-
console.
|
|
347
|
-
console.
|
|
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.
|
|
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
|
],
|