mobbdev 1.0.183 → 1.0.185

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/dist/index.mjs +346 -116
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -12498,29 +12498,6 @@ var logWarn = (message, data) => logger.log(message, "warn", data);
12498
12498
  var logDebug = (message, data) => logger.log(message, "debug", data);
12499
12499
  var log = logger.log.bind(logger);
12500
12500
 
12501
- // src/mcp/services/ConfigStoreService.ts
12502
- init_configs();
12503
- import Configstore4 from "configstore";
12504
- function createConfigStore(defaultValues = { apiToken: "" }) {
12505
- const API_URL2 = process.env["API_URL"] || MCP_DEFAULT_API_URL;
12506
- let domain = "";
12507
- try {
12508
- const url = new URL(API_URL2);
12509
- domain = url.hostname;
12510
- } catch (e) {
12511
- domain = API_URL2.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:\d+$/, "");
12512
- }
12513
- const sanitizedDomain = domain.replace(/\./g, "_");
12514
- return new Configstore4(
12515
- `${packageJson.name}-${sanitizedDomain}`,
12516
- defaultValues
12517
- );
12518
- }
12519
- function getConfigStore() {
12520
- return createConfigStore();
12521
- }
12522
- var configStore = getConfigStore();
12523
-
12524
12501
  // src/mcp/services/McpGQLClient.ts
12525
12502
  import crypto3 from "crypto";
12526
12503
  import { GraphQLClient as GraphQLClient2 } from "graphql-request";
@@ -12653,6 +12630,29 @@ var GetLatestReportByRepoUrlResponseSchema = z31.object({
12653
12630
  expiredReport: z31.array(ExpiredReportSchema)
12654
12631
  });
12655
12632
 
12633
+ // src/mcp/services/ConfigStoreService.ts
12634
+ init_configs();
12635
+ import Configstore4 from "configstore";
12636
+ function createConfigStore(defaultValues = { apiToken: "" }) {
12637
+ const API_URL2 = process.env["API_URL"] || MCP_DEFAULT_API_URL;
12638
+ let domain = "";
12639
+ try {
12640
+ const url = new URL(API_URL2);
12641
+ domain = url.hostname;
12642
+ } catch (e) {
12643
+ domain = API_URL2.replace(/^https?:\/\//, "").replace(/\/.*$/, "").replace(/:\d+$/, "");
12644
+ }
12645
+ const sanitizedDomain = domain.replace(/\./g, "_");
12646
+ return new Configstore4(
12647
+ `${packageJson.name}-${sanitizedDomain}`,
12648
+ defaultValues
12649
+ );
12650
+ }
12651
+ function getConfigStore() {
12652
+ return createConfigStore();
12653
+ }
12654
+ var configStore = getConfigStore();
12655
+
12656
12656
  // src/mcp/services/McpAuthService.ts
12657
12657
  import crypto2 from "crypto";
12658
12658
  import os2 from "os";
@@ -13340,18 +13340,12 @@ async function createAuthenticatedMcpGQLClient({
13340
13340
  return new McpGQLClient({ apiKey: newApiToken, type: "apiKey" });
13341
13341
  }
13342
13342
 
13343
- // src/mcp/services/McpUsageService/McpUsageService.ts
13344
- init_configs();
13345
- import fetch5 from "node-fetch";
13346
- import os4 from "os";
13347
- import { v4 as uuidv43, v5 as uuidv5 } from "uuid";
13348
-
13349
13343
  // src/mcp/services/McpUsageService/host.ts
13350
13344
  import { execSync } from "child_process";
13351
13345
  import fs10 from "fs";
13352
13346
  import os3 from "os";
13353
13347
  import path11 from "path";
13354
- var IDEs = ["cursor", "windsurf", "webstorm", "vscode"];
13348
+ var IDEs = ["cursor", "windsurf", "webstorm", "vscode", "claude"];
13355
13349
  var runCommand = (cmd) => {
13356
13350
  try {
13357
13351
  return execSync(cmd, { encoding: "utf8" }).trim();
@@ -13363,33 +13357,119 @@ var gitInfo = {
13363
13357
  name: runCommand("git config user.name"),
13364
13358
  email: runCommand("git config user.email")
13365
13359
  };
13366
- var getMCPConfigPath = (hostName) => {
13360
+ var getClaudeWorkspacePaths = () => {
13361
+ const home = os3.homedir();
13362
+ const claudeIdePath = path11.join(home, ".claude", "ide");
13363
+ const workspacePaths = [];
13364
+ if (!fs10.existsSync(claudeIdePath)) {
13365
+ return workspacePaths;
13366
+ }
13367
+ try {
13368
+ const lockFiles = fs10.readdirSync(claudeIdePath).filter((file) => file.endsWith(".lock"));
13369
+ for (const lockFile of lockFiles) {
13370
+ const lockFilePath = path11.join(claudeIdePath, lockFile);
13371
+ try {
13372
+ const lockContent = JSON.parse(fs10.readFileSync(lockFilePath, "utf8"));
13373
+ if (lockContent.workspaceFolders && Array.isArray(lockContent.workspaceFolders)) {
13374
+ workspacePaths.push(...lockContent.workspaceFolders);
13375
+ }
13376
+ } catch (error) {
13377
+ logWarn(
13378
+ `[UsageService] Failed to read Claude lock file: ${lockFilePath}`
13379
+ );
13380
+ }
13381
+ }
13382
+ } catch (error) {
13383
+ logWarn(
13384
+ `[UsageService] Failed to read Claude IDE directory: ${claudeIdePath}`
13385
+ );
13386
+ }
13387
+ return workspacePaths;
13388
+ };
13389
+ var getMCPConfigPaths = (hostName) => {
13367
13390
  const home = os3.homedir();
13391
+ const currentDir = process.env["WORKSPACE_FOLDER_PATHS"] || process.env["PWD"] || process.cwd();
13368
13392
  switch (hostName.toLowerCase()) {
13369
13393
  case "cursor":
13370
- return path11.join(home, ".cursor", "mcp.json");
13394
+ return [
13395
+ path11.join(currentDir, ".cursor", "mcp.json"),
13396
+ // local first
13397
+ path11.join(home, ".cursor", "mcp.json")
13398
+ ];
13371
13399
  case "windsurf":
13372
- return path11.join(home, ".codeium", "windsurf", "mcp_config.json");
13400
+ return [
13401
+ path11.join(currentDir, ".codeium", "mcp_config.json"),
13402
+ // local first
13403
+ path11.join(home, ".codeium", "windsurf", "mcp_config.json")
13404
+ ];
13373
13405
  case "webstorm":
13374
- return "";
13406
+ return [];
13375
13407
  case "visualstudiocode":
13376
13408
  case "vscode":
13377
- return process.platform === "win32" ? path11.join(home, "AppData", "Roaming", "Code", "User", "mcp.json") : path11.join(
13378
- home,
13379
- "Library",
13380
- "Application Support",
13381
- "Code",
13382
- "User",
13383
- "mcp.json"
13384
- );
13409
+ return [
13410
+ path11.join(currentDir, ".vscode", "mcp.json"),
13411
+ // local first
13412
+ process.platform === "win32" ? path11.join(home, "AppData", "Roaming", "Code", "User", "mcp.json") : path11.join(
13413
+ home,
13414
+ "Library",
13415
+ "Application Support",
13416
+ "Code",
13417
+ "User",
13418
+ "mcp.json"
13419
+ )
13420
+ ];
13421
+ case "claude": {
13422
+ const claudePaths = [
13423
+ path11.join(currentDir, ".claude.json"),
13424
+ // local first
13425
+ path11.join(home, ".claude.json")
13426
+ ];
13427
+ const workspacePaths = getClaudeWorkspacePaths();
13428
+ for (const workspacePath of workspacePaths) {
13429
+ claudePaths.push(path11.join(workspacePath, ".mcp.json"));
13430
+ }
13431
+ return claudePaths;
13432
+ }
13385
13433
  default:
13386
13434
  throw new Error(`Unknown hostName: ${hostName}`);
13387
13435
  }
13388
13436
  };
13389
- var readMCPConfig = (hostName) => {
13390
- const filePath = getMCPConfigPath(hostName);
13437
+ var readConfigFile = (filePath) => {
13391
13438
  if (!fs10.existsSync(filePath)) return null;
13392
- return JSON.parse(fs10.readFileSync(filePath, "utf8"));
13439
+ try {
13440
+ return JSON.parse(fs10.readFileSync(filePath, "utf8"));
13441
+ } catch (error) {
13442
+ logWarn(`[UsageService] Failed to read MCP config: ${filePath}`);
13443
+ return null;
13444
+ }
13445
+ };
13446
+ var readMCPConfig = (hostName) => {
13447
+ const configPaths = getMCPConfigPaths(hostName);
13448
+ const mergedConfig = {};
13449
+ for (const configPath of configPaths) {
13450
+ const config4 = readConfigFile(configPath);
13451
+ if (hostName === "claude" && config4?.projects) {
13452
+ const allMcpServers = {};
13453
+ for (const projectPath in config4.projects) {
13454
+ const project = config4.projects[projectPath];
13455
+ if (project?.mcpServers) {
13456
+ Object.assign(allMcpServers, project.mcpServers);
13457
+ }
13458
+ }
13459
+ mergedConfig.mcpServers = { ...mergedConfig.mcpServers, ...allMcpServers };
13460
+ continue;
13461
+ }
13462
+ if (config4?.mcpServers) {
13463
+ mergedConfig.mcpServers = {
13464
+ ...mergedConfig.mcpServers,
13465
+ ...config4.mcpServers
13466
+ };
13467
+ }
13468
+ if (config4?.servers) {
13469
+ mergedConfig.servers = { ...mergedConfig.servers, ...config4.servers };
13470
+ }
13471
+ }
13472
+ return Object.keys(mergedConfig).length > 0 ? mergedConfig : null;
13393
13473
  };
13394
13474
  var getRunningProcesses = () => {
13395
13475
  try {
@@ -13398,11 +13478,29 @@ var getRunningProcesses = () => {
13398
13478
  return "";
13399
13479
  }
13400
13480
  };
13481
+ var checkUrlAccessibility = (url) => {
13482
+ try {
13483
+ execSync(`curl -s --connect-timeout 5 --max-time 3 "${url}"`, {
13484
+ encoding: "utf8",
13485
+ stdio: "ignore"
13486
+ });
13487
+ return true;
13488
+ } catch (error) {
13489
+ if (error && typeof error === "object" && "status" in error) {
13490
+ const exitCode = error.status;
13491
+ if (exitCode === 28) {
13492
+ return true;
13493
+ }
13494
+ }
13495
+ return false;
13496
+ }
13497
+ };
13401
13498
  var knownHosts = {
13402
13499
  webstorm: "WebStorm",
13403
13500
  cursor: "Cursor",
13404
13501
  windsurf: "Windsurf",
13405
- code: "Vscode"
13502
+ code: "Vscode",
13503
+ claude: "Claude"
13406
13504
  };
13407
13505
  var versionCommands = {
13408
13506
  WebStorm: {
@@ -13437,6 +13535,16 @@ var versionCommands = {
13437
13535
  win32: [
13438
13536
  `(Get-Item "$env:LOCALAPPDATA\\Programs\\Microsoft VS Code\\Code.exe").VersionInfo.ProductVersion`
13439
13537
  ]
13538
+ },
13539
+ Claude: {
13540
+ darwin: [
13541
+ "claude --version",
13542
+ `grep -A1 CFBundleVersion "/Applications/Claude.app/Contents/Info.plist" | grep '<string>' | sed -E 's/.*<string>(.*)<\\/string>.*/\\1/'`
13543
+ ],
13544
+ win32: [
13545
+ "claude --version",
13546
+ `(Get-Item "$env:LOCALAPPDATA\\Programs\\Claude\\Claude.exe").VersionInfo.ProductVersion`
13547
+ ]
13440
13548
  }
13441
13549
  };
13442
13550
  var getProcessInfo = (pid) => {
@@ -13481,50 +13589,46 @@ var getHostInfo = () => {
13481
13589
  for (const [name, server] of Object.entries(
13482
13590
  cfg.mcpServers || cfg.servers || {}
13483
13591
  )) {
13484
- servers.push({
13485
- ide,
13486
- name,
13487
- command: server.command || "",
13488
- isRunning: false
13489
- });
13592
+ if (server.command || server.url) {
13593
+ servers.push({
13594
+ ide,
13595
+ name,
13596
+ command: `${server.command} ${server.args ? server.args?.join(" ") : ""}`,
13597
+ isRunning: false,
13598
+ ...server.url && { url: server.url }
13599
+ });
13600
+ }
13490
13601
  }
13491
13602
  }
13492
13603
  const runningLines = runningProcesses.split("\n");
13493
13604
  for (const line of runningLines) {
13494
13605
  if (line.includes("mcp")) {
13495
13606
  const cmdLower = line.toLowerCase();
13607
+ let ideName = "Unknown";
13608
+ const pidMatch = line.trim().split(/\s+/)[1];
13609
+ const pid = parseInt(String(pidMatch), 10);
13610
+ if (!isNaN(pid)) {
13611
+ let currentPid = pid;
13612
+ while (currentPid && currentPid !== 0) {
13613
+ const proc = getProcessInfo(currentPid);
13614
+ if (!proc) break;
13615
+ const cmdProc = proc.cmd.toLowerCase();
13616
+ const found = Object.keys(knownHosts).find(
13617
+ (key) => cmdProc.includes(key)
13618
+ );
13619
+ if (found) {
13620
+ ideName = knownHosts[found] || "Unknown";
13621
+ break;
13622
+ }
13623
+ currentPid = parseInt(proc.ppid, 10);
13624
+ }
13625
+ }
13496
13626
  const existingServer = servers.find(
13497
- (s) => s.command && cmdLower.includes(s.command.toLowerCase())
13627
+ (s) => s.command && cmdLower.includes(s.command.toLowerCase()) && s.ide.toLowerCase() === ideName.toLowerCase()
13498
13628
  );
13499
13629
  if (existingServer) {
13500
13630
  existingServer.isRunning = true;
13501
13631
  } else {
13502
- let ideName = "Unknown";
13503
- const foundHostKey = Object.keys(knownHosts).find(
13504
- (key) => cmdLower.includes(key)
13505
- );
13506
- if (foundHostKey) {
13507
- ideName = knownHosts[foundHostKey] || "Unknown";
13508
- } else {
13509
- const pidMatch = line.trim().split(/\s+/)[1];
13510
- const pid = parseInt(String(pidMatch), 10);
13511
- if (!isNaN(pid)) {
13512
- let currentPid = pid;
13513
- while (currentPid && currentPid !== 0) {
13514
- const proc = getProcessInfo(currentPid);
13515
- if (!proc) break;
13516
- const cmdProc = proc.cmd.toLowerCase();
13517
- const found = Object.keys(knownHosts).find(
13518
- (key) => cmdProc.includes(key)
13519
- );
13520
- if (found) {
13521
- ideName = knownHosts[found] || "Unknown";
13522
- break;
13523
- }
13524
- currentPid = parseInt(proc.ppid, 10);
13525
- }
13526
- }
13527
- }
13528
13632
  servers.push({
13529
13633
  ide: ideName.toLowerCase(),
13530
13634
  name: "unknown",
@@ -13534,6 +13638,14 @@ var getHostInfo = () => {
13534
13638
  }
13535
13639
  }
13536
13640
  }
13641
+ for (const server of servers) {
13642
+ if (server.url && !server.isRunning) {
13643
+ const isUrlAccessible = checkUrlAccessibility(server.url);
13644
+ if (isUrlAccessible) {
13645
+ server.isRunning = true;
13646
+ }
13647
+ }
13648
+ }
13537
13649
  for (const { ide, name, command, isRunning } of servers) {
13538
13650
  const config4 = allConfigs[ide] || null;
13539
13651
  const ideName = ide.charAt(0).toUpperCase() + ide.slice(1) || "Unknown";
@@ -13570,11 +13682,17 @@ var getHostInfo = () => {
13570
13682
  };
13571
13683
 
13572
13684
  // src/mcp/services/McpUsageService/McpUsageService.ts
13685
+ init_configs();
13686
+ import fetch5 from "node-fetch";
13687
+ import os4 from "os";
13688
+ import { v4 as uuidv43, v5 as uuidv5 } from "uuid";
13573
13689
  var McpUsageService = class {
13574
- constructor() {
13690
+ constructor(govOrgId) {
13575
13691
  __publicField(this, "configKey", "mcpUsage");
13576
13692
  __publicField(this, "intervalId", null);
13577
13693
  __publicField(this, "REST_API_URL", MCP_DEFAULT_REST_API_URL);
13694
+ __publicField(this, "govOrgId");
13695
+ this.govOrgId = govOrgId;
13578
13696
  this.startPeriodicTracking();
13579
13697
  if (process.env["API_URL"]) {
13580
13698
  const url = new URL(process.env["API_URL"]);
@@ -13594,7 +13712,7 @@ var McpUsageService = class {
13594
13712
  logDebug(`[UsageService] Triggering periodic usage service`, {
13595
13713
  MCP_PERIODIC_TRACK_INTERVAL
13596
13714
  });
13597
- await mcpUsageService.trackServerStart();
13715
+ await this.trackServerStart();
13598
13716
  }, 1e4);
13599
13717
  }
13600
13718
  generateHostId() {
@@ -13614,18 +13732,16 @@ var McpUsageService = class {
13614
13732
  return hostId;
13615
13733
  }
13616
13734
  getOrganizationId() {
13617
- const organizationId = configStore.get("GOV-ORG-ID") || "";
13618
- if (organizationId) {
13619
- logDebug("[UsageService] Using stored organization ID", {
13620
- organizationId
13735
+ if (this.govOrgId) {
13736
+ logDebug("[UsageService] Using provided organization ID", {
13737
+ organizationId: this.govOrgId
13621
13738
  });
13622
- return organizationId;
13739
+ return this.govOrgId;
13623
13740
  }
13624
13741
  return "";
13625
13742
  }
13626
13743
  hasOrganizationId() {
13627
- const organizationId = configStore.get("GOV-ORG-ID") || "";
13628
- return !!organizationId;
13744
+ return !!this.govOrgId;
13629
13745
  }
13630
13746
  createUsageData(mcpHostId, organizationId, status) {
13631
13747
  const { user, mcps } = getHostInfo();
@@ -13711,12 +13827,12 @@ var McpUsageService = class {
13711
13827
  this.intervalId = null;
13712
13828
  }
13713
13829
  };
13714
- var mcpUsageService = new McpUsageService();
13715
13830
 
13716
13831
  // src/mcp/tools/toolNames.ts
13717
13832
  var MCP_TOOL_CHECK_FOR_NEW_AVAILABLE_FIXES = "check_for_new_available_fixes";
13718
13833
  var MCP_TOOL_FETCH_AVAILABLE_FIXES = "fetch_available_fixes";
13719
13834
  var MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES = "scan_and_fix_vulnerabilities";
13835
+ var MCP_TOOL_CHECKER = "mcp_checker";
13720
13836
 
13721
13837
  // src/mcp/core/McpServer.ts
13722
13838
  init_configs();
@@ -13741,6 +13857,9 @@ var ToolRegistry = class {
13741
13857
  getTool(name) {
13742
13858
  return this.tools.get(name);
13743
13859
  }
13860
+ getToolDefinition(name) {
13861
+ return this.tools.get(name)?.getDefinition();
13862
+ }
13744
13863
  getAllTools() {
13745
13864
  return Array.from(this.tools.values()).map((tool) => tool.getDefinition());
13746
13865
  }
@@ -13757,14 +13876,16 @@ var ToolRegistry = class {
13757
13876
 
13758
13877
  // src/mcp/core/McpServer.ts
13759
13878
  var McpServer = class {
13760
- constructor(config4) {
13879
+ constructor(config4, govOrgId = "") {
13761
13880
  __publicField(this, "server");
13762
13881
  __publicField(this, "toolRegistry");
13763
13882
  __publicField(this, "isEventHandlersSetup", false);
13764
13883
  __publicField(this, "eventHandlers", /* @__PURE__ */ new Map());
13765
13884
  __publicField(this, "parentProcessCheckInterval");
13766
13885
  __publicField(this, "parentPid");
13886
+ __publicField(this, "mcpUsageService");
13767
13887
  this.parentPid = process.ppid;
13888
+ this.mcpUsageService = govOrgId ? new McpUsageService(govOrgId) : null;
13768
13889
  this.server = new Server(
13769
13890
  {
13770
13891
  name: config4.name,
@@ -13788,18 +13909,18 @@ var McpServer = class {
13788
13909
  }
13789
13910
  async trackServerUsage(action, signalOrError) {
13790
13911
  try {
13791
- if (!mcpUsageService.hasOrganizationId()) {
13912
+ if (!this.mcpUsageService?.hasOrganizationId()) {
13792
13913
  logDebug(
13793
13914
  `[McpServer] Skipping ${action} usage tracking - organization ID not available`
13794
13915
  );
13795
13916
  return;
13796
13917
  }
13797
13918
  if (action === "start") {
13798
- await mcpUsageService.trackServerStart();
13919
+ await this.mcpUsageService?.trackServerStart();
13799
13920
  }
13800
13921
  if (action === "stop") {
13801
- await mcpUsageService.trackServerStop();
13802
- mcpUsageService.reset();
13922
+ await this.mcpUsageService?.trackServerStop();
13923
+ this.mcpUsageService?.reset();
13803
13924
  }
13804
13925
  } catch (usageError) {
13805
13926
  logWarn(`Failed to track MCP server ${action}`, {
@@ -14002,10 +14123,21 @@ var McpServer = class {
14002
14123
  }
14003
14124
  }
14004
14125
  async handleListToolsRequest(request) {
14005
- const govOrgId = configStore.get("GOV-ORG-ID") || "";
14006
- if (govOrgId) {
14126
+ const mcpCheckerTool = this.toolRegistry.getToolDefinition(MCP_TOOL_CHECKER);
14127
+ if (mcpCheckerTool) {
14007
14128
  return {
14008
- tools: []
14129
+ tools: [
14130
+ {
14131
+ name: mcpCheckerTool.name,
14132
+ display_name: mcpCheckerTool.display_name || mcpCheckerTool.name,
14133
+ description: mcpCheckerTool.description,
14134
+ inputSchema: {
14135
+ type: "object",
14136
+ properties: mcpCheckerTool.inputSchema.properties || {},
14137
+ required: mcpCheckerTool.inputSchema.required || []
14138
+ }
14139
+ }
14140
+ ]
14009
14141
  };
14010
14142
  }
14011
14143
  logInfo("Received list_tools request");
@@ -14215,10 +14347,12 @@ var BaseTool = class {
14215
14347
  };
14216
14348
  }
14217
14349
  async execute(args) {
14218
- logDebug(`Authenticating tool: ${this.name}`, { args });
14219
- const mcpGqlClient = await createAuthenticatedMcpGQLClient();
14220
- const userInfo = await mcpGqlClient.getUserInfo();
14221
- logDebug("User authenticated successfully", { userInfo });
14350
+ if (this.hasAuthentication) {
14351
+ logDebug(`Authenticating tool: ${this.name}`, { args });
14352
+ const mcpGqlClient = await createAuthenticatedMcpGQLClient();
14353
+ const userInfo = await mcpGqlClient.getUserInfo();
14354
+ logDebug("User authenticated successfully", { userInfo });
14355
+ }
14222
14356
  const validatedArgs = this.validateInput(args);
14223
14357
  logDebug(`Tool ${this.name} input validation successful`, {
14224
14358
  validatedArgs
@@ -17590,6 +17724,7 @@ Example payload:
17590
17724
  {
17591
17725
  "path": "/home/user/my-project"
17592
17726
  }`);
17727
+ __publicField(this, "hasAuthentication", true);
17593
17728
  __publicField(this, "inputSchema", {
17594
17729
  type: "object",
17595
17730
  properties: {
@@ -17732,6 +17867,7 @@ The tool will:
17732
17867
  3. Query the MOBB service by the origin remote URL and return a textual summary of available fixes (total and by severity) or a message if none are found.
17733
17868
 
17734
17869
  Call this tool instead of ${MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES} when you only need a fixes summary and do NOT want to perform scanning or code modifications.`);
17870
+ __publicField(this, "hasAuthentication", true);
17735
17871
  __publicField(this, "inputSchema", {
17736
17872
  type: "object",
17737
17873
  properties: {
@@ -17794,9 +17930,96 @@ Call this tool instead of ${MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES} when you only
17794
17930
  }
17795
17931
  };
17796
17932
 
17933
+ // src/mcp/tools/mcpChecker/mcpCheckerTool.ts
17934
+ import z36 from "zod";
17935
+
17936
+ // src/mcp/tools/mcpChecker/mcpCheckerService.ts
17937
+ var _McpCheckerService = class _McpCheckerService {
17938
+ constructor(govOrgId) {
17939
+ __publicField(this, "govOrgId");
17940
+ this.govOrgId = govOrgId;
17941
+ }
17942
+ static getInstance(govOrgId) {
17943
+ if (!_McpCheckerService.instances.has(govOrgId)) {
17944
+ _McpCheckerService.instances.set(govOrgId, new _McpCheckerService(govOrgId));
17945
+ }
17946
+ return _McpCheckerService.instances.get(govOrgId);
17947
+ }
17948
+ processMcpCheck() {
17949
+ if (!this.govOrgId) {
17950
+ return {
17951
+ content: [
17952
+ {
17953
+ type: "text",
17954
+ text: ""
17955
+ }
17956
+ ]
17957
+ };
17958
+ }
17959
+ logInfo("Executing built-in mcp_checker tool");
17960
+ const hostInfo = getHostInfo();
17961
+ const mcpServersInfo = hostInfo.mcps.filter((mcp) => mcp.mcpName !== "unknown").map(
17962
+ (mcp) => `- ${mcp.mcpName} (${mcp.ideName} ${mcp.ideVersion}): ${mcp.isRunning ? "\u2705 Running" : "\u274C Not Running"}`
17963
+ ).join("\n");
17964
+ const response = {
17965
+ content: [
17966
+ {
17967
+ type: "text",
17968
+ text: `MCP Server Status Report
17969
+
17970
+ User: ${hostInfo.user.name} (${hostInfo.user.email})
17971
+
17972
+ Configured MCP Servers:
17973
+ ${mcpServersInfo}
17974
+
17975
+ Total Servers: ${hostInfo.mcps.length}
17976
+ Running Servers: ${hostInfo.mcps.filter((mcp) => mcp.isRunning).length}`
17977
+ }
17978
+ ]
17979
+ };
17980
+ logInfo("mcp_checker tool executed successfully");
17981
+ return response;
17982
+ }
17983
+ };
17984
+ __publicField(_McpCheckerService, "instances", /* @__PURE__ */ new Map());
17985
+ var McpCheckerService = _McpCheckerService;
17986
+
17987
+ // src/mcp/tools/mcpChecker/mcpCheckerTool.ts
17988
+ var McpCheckerTool = class extends BaseTool {
17989
+ constructor(govOrgId) {
17990
+ super();
17991
+ __publicField(this, "name", MCP_TOOL_CHECKER);
17992
+ __publicField(this, "displayName", "MCP Checker");
17993
+ // A detailed description to guide the LLM on when and how to invoke this tool.
17994
+ __publicField(this, "description", "Check the MCP servers running on this IDE against organization policies.");
17995
+ __publicField(this, "inputValidationSchema", z36.object({}));
17996
+ __publicField(this, "inputSchema", {
17997
+ type: "object",
17998
+ properties: {},
17999
+ required: []
18000
+ });
18001
+ __publicField(this, "hasAuthentication", false);
18002
+ __publicField(this, "mcpCheckerService");
18003
+ this.mcpCheckerService = McpCheckerService.getInstance(govOrgId);
18004
+ }
18005
+ async executeInternal(args) {
18006
+ logDebug(`Executing tool: ${this.name}`, { args });
18007
+ try {
18008
+ return this.mcpCheckerService.processMcpCheck();
18009
+ } catch (error) {
18010
+ const errorResponse = this.createSuccessResponse(error.message);
18011
+ logError("Tool execution failed", {
18012
+ error: error.message,
18013
+ result: errorResponse
18014
+ });
18015
+ return errorResponse;
18016
+ }
18017
+ }
18018
+ };
18019
+
17797
18020
  // src/mcp/tools/scanAndFixVulnerabilities/ScanAndFixVulnerabilitiesTool.ts
17798
18021
  init_configs();
17799
- import z36 from "zod";
18022
+ import z37 from "zod";
17800
18023
 
17801
18024
  // src/mcp/tools/scanAndFixVulnerabilities/ScanAndFixVulnerabilitiesService.ts
17802
18025
  init_configs();
@@ -17981,16 +18204,17 @@ Example payload:
17981
18204
  "maxFiles": 50,
17982
18205
  "rescan": false
17983
18206
  }`);
17984
- __publicField(this, "inputValidationSchema", z36.object({
17985
- path: z36.string().describe(
18207
+ __publicField(this, "hasAuthentication", true);
18208
+ __publicField(this, "inputValidationSchema", z37.object({
18209
+ path: z37.string().describe(
17986
18210
  "Full local path to repository to scan and fix vulnerabilities"
17987
18211
  ),
17988
- offset: z36.number().optional().describe("Optional offset for pagination"),
17989
- limit: z36.number().optional().describe("Optional maximum number of results to return"),
17990
- maxFiles: z36.number().optional().describe(
18212
+ offset: z37.number().optional().describe("Optional offset for pagination"),
18213
+ limit: z37.number().optional().describe("Optional maximum number of results to return"),
18214
+ maxFiles: z37.number().optional().describe(
17991
18215
  `Optional maximum number of files to scan (default: ${MCP_DEFAULT_MAX_FILES_TO_SCAN}). Increase for comprehensive scans of larger codebases or decrease for faster focused scans.`
17992
18216
  ),
17993
- rescan: z36.boolean().optional().describe("Optional whether to rescan the repository")
18217
+ rescan: z37.boolean().optional().describe("Optional whether to rescan the repository")
17994
18218
  }));
17995
18219
  __publicField(this, "inputSchema", {
17996
18220
  type: "object",
@@ -18023,7 +18247,7 @@ Example payload:
18023
18247
  this.vulnerabilityFixService.reset();
18024
18248
  }
18025
18249
  async executeInternal(args) {
18026
- logDebug(`Executing tool: ${MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES}`, {
18250
+ logDebug(`Executing tool: ${this.name}`, {
18027
18251
  path: args.path
18028
18252
  });
18029
18253
  if (!args.path) {
@@ -18080,12 +18304,15 @@ Example payload:
18080
18304
  };
18081
18305
 
18082
18306
  // src/mcp/index.ts
18083
- function createMcpServer() {
18307
+ function createMcpServer(govOrgId) {
18084
18308
  logDebug("Creating MCP server");
18085
- const server = new McpServer({
18086
- name: "mobb-mcp",
18087
- version: packageJson.version
18088
- });
18309
+ const server = new McpServer(
18310
+ {
18311
+ name: "mobb-mcp",
18312
+ version: packageJson.version
18313
+ },
18314
+ govOrgId
18315
+ );
18089
18316
  const enabledToolsEnv = process.env["TOOLS_ENABLED"];
18090
18317
  const enabledToolsSet = enabledToolsEnv ? new Set(
18091
18318
  enabledToolsEnv.split(",").map((t) => t.trim()).filter((t) => t.length > 0)
@@ -18104,6 +18331,10 @@ function createMcpServer() {
18104
18331
  registerIfEnabled(scanAndFixVulnerabilitiesTool);
18105
18332
  registerIfEnabled(fetchAvailableFixesTool);
18106
18333
  registerIfEnabled(checkForNewAvailableFixesTool);
18334
+ if (govOrgId) {
18335
+ const mcpCheckerTool = new McpCheckerTool(govOrgId);
18336
+ registerIfEnabled(mcpCheckerTool);
18337
+ }
18107
18338
  logInfo("MCP server created and configured");
18108
18339
  return server;
18109
18340
  }
@@ -18112,8 +18343,7 @@ async function startMcpServer({
18112
18343
  }) {
18113
18344
  try {
18114
18345
  logDebug("Initializing MCP server");
18115
- configStore.set("GOV-ORG-ID", govOrgId);
18116
- const server = createMcpServer();
18346
+ const server = createMcpServer(govOrgId);
18117
18347
  await server.start();
18118
18348
  } catch (error) {
18119
18349
  logError("Failed to start MCP server", { error });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.0.183",
3
+ "version": "1.0.185",
4
4
  "description": "Automated secure code remediation tool",
5
5
  "repository": "git+https://github.com/mobb-dev/bugsy.git",
6
6
  "main": "dist/index.mjs",