@ebowwa/workspace-mcp 1.0.0

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/src/index.js ADDED
@@ -0,0 +1,920 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ var __generator = (this && this.__generator) || function (thisArg, body) {
13
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
14
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
15
+ function verb(n) { return function (v) { return step([n, v]); }; }
16
+ function step(op) {
17
+ if (f) throw new TypeError("Generator is already executing.");
18
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
19
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
20
+ if (y = 0, t) op = [op[0] & 2, t.value];
21
+ switch (op[0]) {
22
+ case 0: case 1: t = op; break;
23
+ case 4: _.label++; return { value: op[1], done: false };
24
+ case 5: _.label++; y = op[1]; op = [0]; continue;
25
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
26
+ default:
27
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
28
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
29
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
30
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
31
+ if (t[2]) _.ops.pop();
32
+ _.trys.pop(); continue;
33
+ }
34
+ op = body.call(thisArg, _);
35
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
36
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
37
+ }
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ var index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
41
+ var stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
42
+ var types_js_1 = require("@modelcontextprotocol/sdk/types.js");
43
+ var child_process_1 = require("child_process");
44
+ var util_1 = require("util");
45
+ var promises_1 = require("fs/promises");
46
+ var path_1 = require("path");
47
+ var psList = require("ps-list");
48
+ var execAsync = (0, util_1.promisify)(child_process_1.exec);
49
+ var WorkspaceMCPServer = /** @class */ (function () {
50
+ function WorkspaceMCPServer() {
51
+ this.server = new index_js_1.Server({
52
+ name: "workspace-mcp",
53
+ version: "1.0.0",
54
+ }, {
55
+ capabilities: {
56
+ tools: {},
57
+ },
58
+ });
59
+ this.setupTools();
60
+ this.setupErrorHandling();
61
+ }
62
+ WorkspaceMCPServer.prototype.setupErrorHandling = function () {
63
+ var _this = this;
64
+ this.server.onerror = function (error) { return console.error("[MCP Error]", error); };
65
+ process.on("SIGINT", function () { return __awaiter(_this, void 0, void 0, function () {
66
+ return __generator(this, function (_a) {
67
+ switch (_a.label) {
68
+ case 0: return [4 /*yield*/, this.server.close()];
69
+ case 1:
70
+ _a.sent();
71
+ process.exit(0);
72
+ return [2 /*return*/];
73
+ }
74
+ });
75
+ }); });
76
+ };
77
+ WorkspaceMCPServer.prototype.setupTools = function () {
78
+ var _this = this;
79
+ this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, function () { return __awaiter(_this, void 0, void 0, function () {
80
+ return __generator(this, function (_a) {
81
+ return [2 /*return*/, ({
82
+ tools: [
83
+ {
84
+ name: "workspace_dirs_list",
85
+ description: "List all directories in the workspace root",
86
+ inputSchema: {
87
+ type: "object",
88
+ properties: {
89
+ includeProcesses: {
90
+ type: "boolean",
91
+ description: "Include running processes for each directory",
92
+ default: false,
93
+ },
94
+ },
95
+ },
96
+ },
97
+ {
98
+ name: "workspace_dirs_get_info",
99
+ description: "Get detailed information about a specific workspace directory",
100
+ inputSchema: {
101
+ type: "object",
102
+ properties: {
103
+ dirPath: {
104
+ type: "string",
105
+ description: "Path to the directory",
106
+ },
107
+ },
108
+ required: ["dirPath"],
109
+ },
110
+ },
111
+ {
112
+ name: "workspace_dirs_run_command",
113
+ description: "Run a command in a specific workspace directory",
114
+ inputSchema: {
115
+ type: "object",
116
+ properties: {
117
+ dirPath: {
118
+ type: "string",
119
+ description: "Path to the directory",
120
+ },
121
+ command: {
122
+ type: "string",
123
+ description: "Command to run (e.g., 'npm install', 'npm run dev')",
124
+ },
125
+ timeout: {
126
+ type: "number",
127
+ description: "Timeout in milliseconds (default: 30000)",
128
+ default: 30000,
129
+ },
130
+ },
131
+ required: ["dirPath", "command"],
132
+ },
133
+ },
134
+ {
135
+ name: "workspace_services_list",
136
+ description: "List all running development services and their status",
137
+ inputSchema: {
138
+ type: "object",
139
+ properties: {
140
+ filter: {
141
+ type: "string",
142
+ description: "Filter services by name or type",
143
+ },
144
+ },
145
+ },
146
+ },
147
+ {
148
+ name: "workspace_services_manage",
149
+ description: "Start, stop, or restart a development service",
150
+ inputSchema: {
151
+ type: "object",
152
+ properties: {
153
+ serviceName: {
154
+ type: "string",
155
+ description: "Name of the service to manage",
156
+ },
157
+ action: {
158
+ type: "string",
159
+ enum: ["start", "stop", "restart", "status"],
160
+ description: "Action to perform on the service",
161
+ },
162
+ dirPath: {
163
+ type: "string",
164
+ description: "Path to the directory (if applicable)",
165
+ },
166
+ },
167
+ required: ["serviceName", "action"],
168
+ },
169
+ },
170
+ {
171
+ name: "workspace_files_read",
172
+ description: "Read a file from a workspace directory",
173
+ inputSchema: {
174
+ type: "object",
175
+ properties: {
176
+ filePath: {
177
+ type: "string",
178
+ description: "Path to the file to read",
179
+ },
180
+ encoding: {
181
+ type: "string",
182
+ description: "File encoding (default: utf8)",
183
+ default: "utf8",
184
+ },
185
+ },
186
+ required: ["filePath"],
187
+ },
188
+ },
189
+ {
190
+ name: "check_integrations",
191
+ description: "Check the health of all integrations (GitHub CLI, Doppler, Node, etc.)",
192
+ inputSchema: {
193
+ type: "object",
194
+ properties: {
195
+ verbose: {
196
+ type: "boolean",
197
+ description: "Include detailed diagnostic information",
198
+ default: false,
199
+ },
200
+ },
201
+ },
202
+ },
203
+ ],
204
+ })];
205
+ });
206
+ }); });
207
+ this.server.setRequestHandler(types_js_1.CallToolRequestSchema, function (request) { return __awaiter(_this, void 0, void 0, function () {
208
+ var _a, name, args, _b, error_1;
209
+ return __generator(this, function (_c) {
210
+ switch (_c.label) {
211
+ case 0:
212
+ _a = request.params, name = _a.name, args = _a.arguments;
213
+ _c.label = 1;
214
+ case 1:
215
+ _c.trys.push([1, 18, , 19]);
216
+ _b = name;
217
+ switch (_b) {
218
+ case "workspace_dirs_list": return [3 /*break*/, 2];
219
+ case "workspace_dirs_get_info": return [3 /*break*/, 4];
220
+ case "workspace_dirs_run_command": return [3 /*break*/, 6];
221
+ case "workspace_services_list": return [3 /*break*/, 8];
222
+ case "workspace_services_manage": return [3 /*break*/, 10];
223
+ case "workspace_files_read": return [3 /*break*/, 12];
224
+ case "check_integrations": return [3 /*break*/, 14];
225
+ }
226
+ return [3 /*break*/, 16];
227
+ case 2: return [4 /*yield*/, this.listProjects(args === null || args === void 0 ? void 0 : args.includeProcesses)];
228
+ case 3: return [2 /*return*/, _c.sent()];
229
+ case 4: return [4 /*yield*/, this.getProjectInfo(args === null || args === void 0 ? void 0 : args.dirPath)];
230
+ case 5: return [2 /*return*/, _c.sent()];
231
+ case 6: return [4 /*yield*/, this.runProjectCommand(args === null || args === void 0 ? void 0 : args.dirPath, args === null || args === void 0 ? void 0 : args.command, args === null || args === void 0 ? void 0 : args.timeout)];
232
+ case 7: return [2 /*return*/, _c.sent()];
233
+ case 8: return [4 /*yield*/, this.listServices(args === null || args === void 0 ? void 0 : args.filter)];
234
+ case 9: return [2 /*return*/, _c.sent()];
235
+ case 10: return [4 /*yield*/, this.manageService(args === null || args === void 0 ? void 0 : args.serviceName, args === null || args === void 0 ? void 0 : args.action, args === null || args === void 0 ? void 0 : args.dirPath)];
236
+ case 11: return [2 /*return*/, _c.sent()];
237
+ case 12: return [4 /*yield*/, this.readProjectFile(args === null || args === void 0 ? void 0 : args.filePath, args === null || args === void 0 ? void 0 : args.encoding)];
238
+ case 13: return [2 /*return*/, _c.sent()];
239
+ case 14: return [4 /*yield*/, this.checkIntegrations(args === null || args === void 0 ? void 0 : args.verbose)];
240
+ case 15: return [2 /*return*/, _c.sent()];
241
+ case 16: throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, "Unknown tool: ".concat(name));
242
+ case 17: return [3 /*break*/, 19];
243
+ case 18:
244
+ error_1 = _c.sent();
245
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, "Tool execution failed: ".concat(error_1 instanceof Error ? error_1.message : String(error_1)));
246
+ case 19: return [2 /*return*/];
247
+ }
248
+ });
249
+ }); });
250
+ };
251
+ WorkspaceMCPServer.prototype.listProjects = function () {
252
+ return __awaiter(this, arguments, void 0, function (includeProcesses) {
253
+ var rootDir, entries, projects, _i, entries_1, entry, projectPath, projectStat, hasPackageJson, isGitRepo, projectType, _a, project, _b, error_2;
254
+ if (includeProcesses === void 0) { includeProcesses = false; }
255
+ return __generator(this, function (_c) {
256
+ switch (_c.label) {
257
+ case 0:
258
+ _c.trys.push([0, 17, , 18]);
259
+ rootDir = "/root";
260
+ return [4 /*yield*/, (0, promises_1.readdir)(rootDir, { withFileTypes: true })];
261
+ case 1:
262
+ entries = _c.sent();
263
+ projects = [];
264
+ _i = 0, entries_1 = entries;
265
+ _c.label = 2;
266
+ case 2:
267
+ if (!(_i < entries_1.length)) return [3 /*break*/, 16];
268
+ entry = entries_1[_i];
269
+ if (!entry.isDirectory())
270
+ return [3 /*break*/, 15];
271
+ projectPath = (0, path_1.join)(rootDir, entry.name);
272
+ return [4 /*yield*/, (0, promises_1.stat)(projectPath)];
273
+ case 3:
274
+ projectStat = _c.sent();
275
+ // Skip hidden directories and common system dirs
276
+ if (entry.name.startsWith('.') ||
277
+ ['node_modules', '.git', '.npm', '.cache', '.local'].includes(entry.name)) {
278
+ return [3 /*break*/, 15];
279
+ }
280
+ return [4 /*yield*/, this.checkFileExists((0, path_1.join)(projectPath, "package.json"))];
281
+ case 4:
282
+ hasPackageJson = _c.sent();
283
+ return [4 /*yield*/, this.checkFileExists((0, path_1.join)(projectPath, ".git"))];
284
+ case 5:
285
+ isGitRepo = _c.sent();
286
+ projectType = "unknown";
287
+ if (!hasPackageJson) return [3 /*break*/, 6];
288
+ projectType = "node";
289
+ return [3 /*break*/, 12];
290
+ case 6: return [4 /*yield*/, this.checkFileExists((0, path_1.join)(projectPath, "go.mod"))];
291
+ case 7:
292
+ if (!_c.sent()) return [3 /*break*/, 8];
293
+ projectType = "go";
294
+ return [3 /*break*/, 12];
295
+ case 8: return [4 /*yield*/, this.checkFileExists((0, path_1.join)(projectPath, "requirements.txt"))];
296
+ case 9:
297
+ _a = (_c.sent());
298
+ if (_a) return [3 /*break*/, 11];
299
+ return [4 /*yield*/, this.checkFileExists((0, path_1.join)(projectPath, "pyproject.toml"))];
300
+ case 10:
301
+ _a = (_c.sent());
302
+ _c.label = 11;
303
+ case 11:
304
+ if (_a)
305
+ projectType = "python";
306
+ else if (entry.name.includes("mcp-"))
307
+ projectType = "mcp-server";
308
+ _c.label = 12;
309
+ case 12:
310
+ project = {
311
+ name: entry.name,
312
+ path: projectPath,
313
+ type: projectType,
314
+ lastModified: projectStat.mtime,
315
+ hasPackageJson: hasPackageJson,
316
+ };
317
+ if (!includeProcesses) return [3 /*break*/, 14];
318
+ _b = project;
319
+ return [4 /*yield*/, this.getProjectProcesses(projectPath)];
320
+ case 13:
321
+ _b.processes = _c.sent();
322
+ _c.label = 14;
323
+ case 14:
324
+ projects.push(project);
325
+ _c.label = 15;
326
+ case 15:
327
+ _i++;
328
+ return [3 /*break*/, 2];
329
+ case 16: return [2 /*return*/, {
330
+ content: [
331
+ {
332
+ type: "text",
333
+ text: JSON.stringify({
334
+ projects: projects.sort(function (a, b) { return b.lastModified.getTime() - a.lastModified.getTime(); }),
335
+ count: projects.length,
336
+ }, null, 2),
337
+ },
338
+ ],
339
+ }];
340
+ case 17:
341
+ error_2 = _c.sent();
342
+ throw new Error("Failed to list projects: ".concat(error_2));
343
+ case 18: return [2 /*return*/];
344
+ }
345
+ });
346
+ });
347
+ };
348
+ WorkspaceMCPServer.prototype.getProjectInfo = function (dirPath) {
349
+ return __awaiter(this, void 0, void 0, function () {
350
+ var projectStat, hasPackageJson, isGitRepo, packageInfo, packageContent, e_1, gitStatus, stdout, e_2, processes, error_3;
351
+ return __generator(this, function (_a) {
352
+ switch (_a.label) {
353
+ case 0:
354
+ _a.trys.push([0, 13, , 14]);
355
+ return [4 /*yield*/, (0, promises_1.stat)(dirPath)];
356
+ case 1:
357
+ projectStat = _a.sent();
358
+ return [4 /*yield*/, this.checkFileExists((0, path_1.join)(dirPath, "package.json"))];
359
+ case 2:
360
+ hasPackageJson = _a.sent();
361
+ return [4 /*yield*/, this.checkFileExists((0, path_1.join)(dirPath, ".git"))];
362
+ case 3:
363
+ isGitRepo = _a.sent();
364
+ packageInfo = null;
365
+ if (!hasPackageJson) return [3 /*break*/, 7];
366
+ _a.label = 4;
367
+ case 4:
368
+ _a.trys.push([4, 6, , 7]);
369
+ return [4 /*yield*/, (0, promises_1.readFile)((0, path_1.join)(dirPath, "package.json"), "utf8")];
370
+ case 5:
371
+ packageContent = _a.sent();
372
+ packageInfo = JSON.parse(packageContent);
373
+ return [3 /*break*/, 7];
374
+ case 6:
375
+ e_1 = _a.sent();
376
+ return [3 /*break*/, 7];
377
+ case 7:
378
+ gitStatus = null;
379
+ if (!isGitRepo) return [3 /*break*/, 11];
380
+ _a.label = 8;
381
+ case 8:
382
+ _a.trys.push([8, 10, , 11]);
383
+ return [4 /*yield*/, execAsync("cd \"".concat(dirPath, "\" && git status --porcelain"))];
384
+ case 9:
385
+ stdout = (_a.sent()).stdout;
386
+ gitStatus = {
387
+ clean: stdout.trim() === "",
388
+ changes: stdout.split('\n').filter(function (line) { return line.trim(); }).length,
389
+ };
390
+ return [3 /*break*/, 11];
391
+ case 10:
392
+ e_2 = _a.sent();
393
+ gitStatus = { error: "Failed to get git status" };
394
+ return [3 /*break*/, 11];
395
+ case 11: return [4 /*yield*/, this.getProjectProcesses(dirPath)];
396
+ case 12:
397
+ processes = _a.sent();
398
+ return [2 /*return*/, {
399
+ content: [
400
+ {
401
+ type: "text",
402
+ text: JSON.stringify({
403
+ path: dirPath,
404
+ lastModified: projectStat.mtime,
405
+ hasPackageJson: hasPackageJson,
406
+ isGitRepo: isGitRepo,
407
+ packageInfo: packageInfo,
408
+ gitStatus: gitStatus,
409
+ processes: processes,
410
+ }, null, 2),
411
+ },
412
+ ],
413
+ }];
414
+ case 13:
415
+ error_3 = _a.sent();
416
+ throw new Error("Failed to get project info: ".concat(error_3));
417
+ case 14: return [2 /*return*/];
418
+ }
419
+ });
420
+ });
421
+ };
422
+ WorkspaceMCPServer.prototype.runProjectCommand = function (dirPath_1, command_1) {
423
+ return __awaiter(this, arguments, void 0, function (dirPath, command, timeout) {
424
+ var _a, stdout, stderr, error_4;
425
+ if (timeout === void 0) { timeout = 30000; }
426
+ return __generator(this, function (_b) {
427
+ switch (_b.label) {
428
+ case 0:
429
+ _b.trys.push([0, 2, , 3]);
430
+ return [4 /*yield*/, execAsync("cd \"".concat(dirPath, "\" && ").concat(command), {
431
+ timeout: timeout,
432
+ maxBuffer: 1024 * 1024, // 1MB buffer
433
+ })];
434
+ case 1:
435
+ _a = _b.sent(), stdout = _a.stdout, stderr = _a.stderr;
436
+ return [2 /*return*/, {
437
+ content: [
438
+ {
439
+ type: "text",
440
+ text: JSON.stringify({
441
+ command: command,
442
+ dirPath: dirPath,
443
+ stdout: stdout,
444
+ stderr: stderr,
445
+ success: true,
446
+ }, null, 2),
447
+ },
448
+ ],
449
+ }];
450
+ case 2:
451
+ error_4 = _b.sent();
452
+ return [2 /*return*/, {
453
+ content: [
454
+ {
455
+ type: "text",
456
+ text: JSON.stringify({
457
+ command: command,
458
+ dirPath: dirPath,
459
+ error: error_4.message,
460
+ stdout: error_4.stdout || "",
461
+ stderr: error_4.stderr || "",
462
+ success: false,
463
+ }, null, 2),
464
+ },
465
+ ],
466
+ }];
467
+ case 3: return [2 /*return*/];
468
+ }
469
+ });
470
+ });
471
+ };
472
+ WorkspaceMCPServer.prototype.listServices = function (filter) {
473
+ return __awaiter(this, void 0, void 0, function () {
474
+ var processes, services, servicePatterns, _i, processes_1, process_1, _a, servicePatterns_1, service, serviceInfo, error_5;
475
+ return __generator(this, function (_b) {
476
+ switch (_b.label) {
477
+ case 0:
478
+ _b.trys.push([0, 2, , 3]);
479
+ return [4 /*yield*/, psList.default()];
480
+ case 1:
481
+ processes = _b.sent();
482
+ services = [];
483
+ servicePatterns = [
484
+ { name: "node", pattern: /node/ },
485
+ { name: "npm", pattern: /npm/ },
486
+ { name: "python", pattern: /python/ },
487
+ { name: "uvicorn", pattern: /uvicorn/ },
488
+ { name: "mcp-server", pattern: /mcp.*server/ },
489
+ { name: "next", pattern: /next/ },
490
+ { name: "vercel", pattern: /vercel/ },
491
+ ];
492
+ for (_i = 0, processes_1 = processes; _i < processes_1.length; _i++) {
493
+ process_1 = processes_1[_i];
494
+ if (!process_1.cmd)
495
+ continue;
496
+ for (_a = 0, servicePatterns_1 = servicePatterns; _a < servicePatterns_1.length; _a++) {
497
+ service = servicePatterns_1[_a];
498
+ if (service.pattern.test(process_1.cmd)) {
499
+ serviceInfo = {
500
+ name: service.name,
501
+ status: "running",
502
+ pid: process_1.pid,
503
+ cpu: process_1.cpu,
504
+ memory: process_1.memory,
505
+ command: process_1.cmd,
506
+ };
507
+ if (!filter || service.name.includes(filter) || process_1.cmd.includes(filter)) {
508
+ services.push(serviceInfo);
509
+ }
510
+ break;
511
+ }
512
+ }
513
+ }
514
+ return [2 /*return*/, {
515
+ content: [
516
+ {
517
+ type: "text",
518
+ text: JSON.stringify({
519
+ services: services,
520
+ count: services.length,
521
+ timestamp: new Date().toISOString(),
522
+ }, null, 2),
523
+ },
524
+ ],
525
+ }];
526
+ case 2:
527
+ error_5 = _b.sent();
528
+ throw new Error("Failed to list services: ".concat(error_5));
529
+ case 3: return [2 /*return*/];
530
+ }
531
+ });
532
+ });
533
+ };
534
+ WorkspaceMCPServer.prototype.manageService = function (serviceName, action, dirPath) {
535
+ return __awaiter(this, void 0, void 0, function () {
536
+ var command, cwd, _a, stdout, pids, _i, pids_1, pid, services, _b, stdout, stderr, error_6;
537
+ return __generator(this, function (_c) {
538
+ switch (_c.label) {
539
+ case 0:
540
+ _c.trys.push([0, 18, , 19]);
541
+ command = "";
542
+ cwd = dirPath || "/root";
543
+ _a = action;
544
+ switch (_a) {
545
+ case "start": return [3 /*break*/, 1];
546
+ case "stop": return [3 /*break*/, 2];
547
+ case "restart": return [3 /*break*/, 8];
548
+ case "status": return [3 /*break*/, 12];
549
+ }
550
+ return [3 /*break*/, 14];
551
+ case 1:
552
+ if (serviceName.includes("mcp")) {
553
+ command = "cd \"".concat(cwd, "\" && npm start");
554
+ }
555
+ else if (serviceName === "next") {
556
+ command = "cd \"".concat(cwd, "\" && npm run dev");
557
+ }
558
+ else {
559
+ throw new Error("Don't know how to start service: ".concat(serviceName));
560
+ }
561
+ return [3 /*break*/, 15];
562
+ case 2: return [4 /*yield*/, execAsync("ps aux | grep \"".concat(serviceName, "\" | grep -v grep | awk '{print $2}'"))];
563
+ case 3:
564
+ stdout = (_c.sent()).stdout;
565
+ if (!stdout.trim()) return [3 /*break*/, 7];
566
+ pids = stdout.trim().split('\n');
567
+ _i = 0, pids_1 = pids;
568
+ _c.label = 4;
569
+ case 4:
570
+ if (!(_i < pids_1.length)) return [3 /*break*/, 7];
571
+ pid = pids_1[_i];
572
+ return [4 /*yield*/, execAsync("kill ".concat(pid))];
573
+ case 5:
574
+ _c.sent();
575
+ _c.label = 6;
576
+ case 6:
577
+ _i++;
578
+ return [3 /*break*/, 4];
579
+ case 7: return [2 /*return*/, {
580
+ content: [
581
+ {
582
+ type: "text",
583
+ text: JSON.stringify({
584
+ action: "stopped",
585
+ serviceName: serviceName,
586
+ pids: stdout.trim().split('\n'),
587
+ success: true,
588
+ }, null, 2),
589
+ },
590
+ ],
591
+ }];
592
+ case 8:
593
+ // Stop then start
594
+ return [4 /*yield*/, this.manageService(serviceName, "stop", dirPath)];
595
+ case 9:
596
+ // Stop then start
597
+ _c.sent();
598
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })];
599
+ case 10:
600
+ _c.sent();
601
+ return [4 /*yield*/, this.manageService(serviceName, "start", dirPath)];
602
+ case 11: return [2 /*return*/, _c.sent()];
603
+ case 12: return [4 /*yield*/, this.listServices(serviceName)];
604
+ case 13:
605
+ services = _c.sent();
606
+ return [2 /*return*/, services];
607
+ case 14: throw new Error("Unknown action: ".concat(action));
608
+ case 15:
609
+ if (!command) return [3 /*break*/, 17];
610
+ return [4 /*yield*/, execAsync(command)];
611
+ case 16:
612
+ _b = _c.sent(), stdout = _b.stdout, stderr = _b.stderr;
613
+ return [2 /*return*/, {
614
+ content: [
615
+ {
616
+ type: "text",
617
+ text: JSON.stringify({
618
+ action: action,
619
+ serviceName: serviceName,
620
+ dirPath: cwd,
621
+ command: command,
622
+ stdout: stdout,
623
+ stderr: stderr,
624
+ success: true,
625
+ }, null, 2),
626
+ },
627
+ ],
628
+ }];
629
+ case 17: return [3 /*break*/, 19];
630
+ case 18:
631
+ error_6 = _c.sent();
632
+ throw new Error("Failed to manage service ".concat(serviceName, ": ").concat(error_6));
633
+ case 19: return [2 /*return*/];
634
+ }
635
+ });
636
+ });
637
+ };
638
+ WorkspaceMCPServer.prototype.readProjectFile = function (filePath_1) {
639
+ return __awaiter(this, arguments, void 0, function (filePath, encoding) {
640
+ var content, stats, error_7;
641
+ if (encoding === void 0) { encoding = "utf8"; }
642
+ return __generator(this, function (_a) {
643
+ switch (_a.label) {
644
+ case 0:
645
+ _a.trys.push([0, 3, , 4]);
646
+ return [4 /*yield*/, (0, promises_1.readFile)(filePath, encoding)];
647
+ case 1:
648
+ content = _a.sent();
649
+ return [4 /*yield*/, (0, promises_1.stat)(filePath)];
650
+ case 2:
651
+ stats = _a.sent();
652
+ return [2 /*return*/, {
653
+ content: [
654
+ {
655
+ type: "text",
656
+ text: JSON.stringify({
657
+ filePath: filePath,
658
+ content: content,
659
+ size: stats.size,
660
+ lastModified: stats.mtime,
661
+ encoding: encoding,
662
+ }, null, 2),
663
+ },
664
+ ],
665
+ }];
666
+ case 3:
667
+ error_7 = _a.sent();
668
+ throw new Error("Failed to read file ".concat(filePath, ": ").concat(error_7));
669
+ case 4: return [2 /*return*/];
670
+ }
671
+ });
672
+ });
673
+ };
674
+ WorkspaceMCPServer.prototype.checkFileExists = function (filePath) {
675
+ return __awaiter(this, void 0, void 0, function () {
676
+ var _a;
677
+ return __generator(this, function (_b) {
678
+ switch (_b.label) {
679
+ case 0:
680
+ _b.trys.push([0, 2, , 3]);
681
+ return [4 /*yield*/, (0, promises_1.stat)(filePath)];
682
+ case 1:
683
+ _b.sent();
684
+ return [2 /*return*/, true];
685
+ case 2:
686
+ _a = _b.sent();
687
+ return [2 /*return*/, false];
688
+ case 3: return [2 /*return*/];
689
+ }
690
+ });
691
+ });
692
+ };
693
+ WorkspaceMCPServer.prototype.getProjectProcesses = function (projectPath) {
694
+ return __awaiter(this, void 0, void 0, function () {
695
+ var processes, projectProcesses, _i, processes_2, process_2, _a;
696
+ return __generator(this, function (_b) {
697
+ switch (_b.label) {
698
+ case 0:
699
+ _b.trys.push([0, 2, , 3]);
700
+ return [4 /*yield*/, psList.default()];
701
+ case 1:
702
+ processes = _b.sent();
703
+ projectProcesses = [];
704
+ for (_i = 0, processes_2 = processes; _i < processes_2.length; _i++) {
705
+ process_2 = processes_2[_i];
706
+ if (process_2.cmd && process_2.cmd.includes(projectPath)) {
707
+ projectProcesses.push("".concat(process_2.name, " (PID: ").concat(process_2.pid, ")"));
708
+ }
709
+ }
710
+ return [2 /*return*/, projectProcesses];
711
+ case 2:
712
+ _a = _b.sent();
713
+ return [2 /*return*/, []];
714
+ case 3: return [2 /*return*/];
715
+ }
716
+ });
717
+ });
718
+ };
719
+ WorkspaceMCPServer.prototype.checkIntegrations = function () {
720
+ return __awaiter(this, arguments, void 0, function (verbose) {
721
+ var results, nodeVersion, error_8, ghStatus, authStatus, testCall, testError_1, error_9, stdout, mcpRunning, error_10, dopplerVersion, error_11;
722
+ if (verbose === void 0) { verbose = false; }
723
+ return __generator(this, function (_a) {
724
+ switch (_a.label) {
725
+ case 0:
726
+ results = {
727
+ timestamp: new Date().toISOString(),
728
+ integrations: {},
729
+ summary: {
730
+ total: 0,
731
+ healthy: 0,
732
+ degraded: 0,
733
+ failed: 0
734
+ }
735
+ };
736
+ _a.label = 1;
737
+ case 1:
738
+ _a.trys.push([1, 3, , 4]);
739
+ return [4 /*yield*/, execAsync("node --version")];
740
+ case 2:
741
+ nodeVersion = (_a.sent()).stdout;
742
+ results.integrations.node = {
743
+ status: "healthy",
744
+ version: nodeVersion.trim(),
745
+ method: "cli"
746
+ };
747
+ results.summary.healthy++;
748
+ return [3 /*break*/, 4];
749
+ case 3:
750
+ error_8 = _a.sent();
751
+ results.integrations.node = {
752
+ status: "failed",
753
+ error: "Node.js not accessible: ".concat(error_8),
754
+ method: "cli"
755
+ };
756
+ results.summary.failed++;
757
+ return [3 /*break*/, 4];
758
+ case 4:
759
+ results.summary.total++;
760
+ _a.label = 5;
761
+ case 5:
762
+ _a.trys.push([5, 11, , 12]);
763
+ return [4 /*yield*/, execAsync("gh auth status --json 2>/dev/null || echo 'not_authenticated'", {
764
+ timeout: 5000
765
+ })];
766
+ case 6:
767
+ ghStatus = (_a.sent()).stdout;
768
+ authStatus = false;
769
+ if (!ghStatus.includes('"isAuthenticated": true')) return [3 /*break*/, 7];
770
+ authStatus = true;
771
+ return [3 /*break*/, 10];
772
+ case 7:
773
+ _a.trys.push([7, 9, , 10]);
774
+ return [4 /*yield*/, execAsync("gh api user --jq '.login' 2>/dev/null", { timeout: 3000 })];
775
+ case 8:
776
+ testCall = (_a.sent()).stdout;
777
+ authStatus = testCall.trim().length > 0;
778
+ return [3 /*break*/, 10];
779
+ case 9:
780
+ testError_1 = _a.sent();
781
+ authStatus = false;
782
+ return [3 /*break*/, 10];
783
+ case 10:
784
+ results.integrations.github_cli = {
785
+ status: authStatus ? "healthy" : "degraded",
786
+ authenticated: authStatus,
787
+ details: authStatus ? "GitHub CLI working" : "GitHub CLI not authenticated",
788
+ method: "cli"
789
+ };
790
+ if (authStatus) {
791
+ results.summary.healthy++;
792
+ }
793
+ else {
794
+ results.summary.degraded++;
795
+ }
796
+ return [3 /*break*/, 12];
797
+ case 11:
798
+ error_9 = _a.sent();
799
+ results.integrations.github_cli = {
800
+ status: "failed",
801
+ error: "GitHub CLI error: ".concat(error_9),
802
+ method: "cli"
803
+ };
804
+ results.summary.failed++;
805
+ return [3 /*break*/, 12];
806
+ case 12:
807
+ results.summary.total++;
808
+ _a.label = 13;
809
+ case 13:
810
+ _a.trys.push([13, 15, , 16]);
811
+ return [4 /*yield*/, execAsync("ps aux | grep -i 'github-mcp' | grep -v grep || echo 'not_running'", {
812
+ timeout: 3000
813
+ })];
814
+ case 14:
815
+ stdout = (_a.sent()).stdout;
816
+ mcpRunning = !stdout.includes('not_running') && stdout.trim().length > 0;
817
+ results.integrations.github_mcp = {
818
+ status: mcpRunning ? "healthy" : "degraded",
819
+ running: mcpRunning,
820
+ details: mcpRunning ? "GitHub MCP server detected" : "GitHub MCP server not detected",
821
+ method: "mcp"
822
+ };
823
+ if (mcpRunning) {
824
+ results.summary.healthy++;
825
+ }
826
+ else {
827
+ results.summary.degraded++;
828
+ }
829
+ return [3 /*break*/, 16];
830
+ case 15:
831
+ error_10 = _a.sent();
832
+ results.integrations.github_mcp = {
833
+ status: "failed",
834
+ error: "GitHub MCP check failed: ".concat(error_10),
835
+ method: "mcp"
836
+ };
837
+ results.summary.failed++;
838
+ return [3 /*break*/, 16];
839
+ case 16:
840
+ results.summary.total++;
841
+ _a.label = 17;
842
+ case 17:
843
+ _a.trys.push([17, 19, , 20]);
844
+ return [4 /*yield*/, execAsync("doppler --version", {
845
+ timeout: 5000
846
+ })];
847
+ case 18:
848
+ dopplerVersion = (_a.sent()).stdout;
849
+ results.integrations.doppler = {
850
+ status: "healthy",
851
+ version: dopplerVersion.trim(),
852
+ method: "cli"
853
+ };
854
+ results.summary.healthy++;
855
+ return [3 /*break*/, 20];
856
+ case 19:
857
+ error_11 = _a.sent();
858
+ results.integrations.doppler = {
859
+ status: "failed",
860
+ error: "Doppler CLI not accessible: ".concat(error_11),
861
+ method: "cli"
862
+ };
863
+ results.summary.failed++;
864
+ return [3 /*break*/, 20];
865
+ case 20:
866
+ results.summary.total++;
867
+ // Add verbose details if requested
868
+ if (verbose) {
869
+ results.integrations.system_info = {
870
+ platform: process.platform,
871
+ node_version: process.version,
872
+ environment_vars: {
873
+ GITHUB_TOKEN: process.env.GITHUB_TOKEN ? 'set' : 'not_set',
874
+ DOPPLER_TOKEN: process.env.DOPPLER_TOKEN ? 'set' : 'not_set'
875
+ }
876
+ };
877
+ }
878
+ return [2 /*return*/, {
879
+ content: [
880
+ {
881
+ type: "text",
882
+ text: JSON.stringify(results, null, verbose ? 2 : 0),
883
+ },
884
+ ],
885
+ }];
886
+ }
887
+ });
888
+ });
889
+ };
890
+ WorkspaceMCPServer.prototype.run = function () {
891
+ return __awaiter(this, void 0, void 0, function () {
892
+ var transport;
893
+ return __generator(this, function (_a) {
894
+ switch (_a.label) {
895
+ case 0:
896
+ transport = new stdio_js_1.StdioServerTransport();
897
+ return [4 /*yield*/, this.server.connect(transport)];
898
+ case 1:
899
+ _a.sent();
900
+ console.error("Workspace MCP server running on stdio");
901
+ // Keep the process alive and handle graceful shutdown
902
+ process.on('SIGINT', function () {
903
+ console.error('Received SIGINT, shutting down gracefully...');
904
+ process.exit(0);
905
+ });
906
+ process.on('SIGTERM', function () {
907
+ console.error('Received SIGTERM, shutting down gracefully...');
908
+ process.exit(0);
909
+ });
910
+ // Prevent the process from exiting
911
+ process.stdin.resume();
912
+ return [2 /*return*/];
913
+ }
914
+ });
915
+ });
916
+ };
917
+ return WorkspaceMCPServer;
918
+ }());
919
+ var server = new WorkspaceMCPServer();
920
+ server.run().catch(console.error);