mobbdev 1.0.183 → 1.0.184
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/dist/index.mjs +265 -102
- 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();
|
|
@@ -13382,6 +13376,8 @@ var getMCPConfigPath = (hostName) => {
|
|
|
13382
13376
|
"User",
|
|
13383
13377
|
"mcp.json"
|
|
13384
13378
|
);
|
|
13379
|
+
case "claude":
|
|
13380
|
+
return path11.join(home, ".claude.json");
|
|
13385
13381
|
default:
|
|
13386
13382
|
throw new Error(`Unknown hostName: ${hostName}`);
|
|
13387
13383
|
}
|
|
@@ -13389,7 +13385,24 @@ var getMCPConfigPath = (hostName) => {
|
|
|
13389
13385
|
var readMCPConfig = (hostName) => {
|
|
13390
13386
|
const filePath = getMCPConfigPath(hostName);
|
|
13391
13387
|
if (!fs10.existsSync(filePath)) return null;
|
|
13392
|
-
|
|
13388
|
+
const config4 = JSON.parse(fs10.readFileSync(filePath, "utf8"));
|
|
13389
|
+
if (hostName === "claude" && config4.projects) {
|
|
13390
|
+
const allMcpServers = {};
|
|
13391
|
+
for (const projectPath in config4.projects) {
|
|
13392
|
+
const project = config4.projects[projectPath];
|
|
13393
|
+
if (project?.mcpServers) {
|
|
13394
|
+
for (const [serverName, serverConfig] of Object.entries(
|
|
13395
|
+
project.mcpServers
|
|
13396
|
+
)) {
|
|
13397
|
+
allMcpServers[serverName] = serverConfig;
|
|
13398
|
+
}
|
|
13399
|
+
}
|
|
13400
|
+
}
|
|
13401
|
+
return {
|
|
13402
|
+
mcpServers: allMcpServers
|
|
13403
|
+
};
|
|
13404
|
+
}
|
|
13405
|
+
return config4;
|
|
13393
13406
|
};
|
|
13394
13407
|
var getRunningProcesses = () => {
|
|
13395
13408
|
try {
|
|
@@ -13398,11 +13411,29 @@ var getRunningProcesses = () => {
|
|
|
13398
13411
|
return "";
|
|
13399
13412
|
}
|
|
13400
13413
|
};
|
|
13414
|
+
var checkUrlAccessibility = (url) => {
|
|
13415
|
+
try {
|
|
13416
|
+
execSync(`curl -s --connect-timeout 5 --max-time 3 "${url}"`, {
|
|
13417
|
+
encoding: "utf8",
|
|
13418
|
+
stdio: "ignore"
|
|
13419
|
+
});
|
|
13420
|
+
return true;
|
|
13421
|
+
} catch (error) {
|
|
13422
|
+
if (error && typeof error === "object" && "status" in error) {
|
|
13423
|
+
const exitCode = error.status;
|
|
13424
|
+
if (exitCode === 28) {
|
|
13425
|
+
return true;
|
|
13426
|
+
}
|
|
13427
|
+
}
|
|
13428
|
+
return false;
|
|
13429
|
+
}
|
|
13430
|
+
};
|
|
13401
13431
|
var knownHosts = {
|
|
13402
13432
|
webstorm: "WebStorm",
|
|
13403
13433
|
cursor: "Cursor",
|
|
13404
13434
|
windsurf: "Windsurf",
|
|
13405
|
-
code: "Vscode"
|
|
13435
|
+
code: "Vscode",
|
|
13436
|
+
claude: "Claude"
|
|
13406
13437
|
};
|
|
13407
13438
|
var versionCommands = {
|
|
13408
13439
|
WebStorm: {
|
|
@@ -13437,6 +13468,16 @@ var versionCommands = {
|
|
|
13437
13468
|
win32: [
|
|
13438
13469
|
`(Get-Item "$env:LOCALAPPDATA\\Programs\\Microsoft VS Code\\Code.exe").VersionInfo.ProductVersion`
|
|
13439
13470
|
]
|
|
13471
|
+
},
|
|
13472
|
+
Claude: {
|
|
13473
|
+
darwin: [
|
|
13474
|
+
"claude --version",
|
|
13475
|
+
`grep -A1 CFBundleVersion "/Applications/Claude.app/Contents/Info.plist" | grep '<string>' | sed -E 's/.*<string>(.*)<\\/string>.*/\\1/'`
|
|
13476
|
+
],
|
|
13477
|
+
win32: [
|
|
13478
|
+
"claude --version",
|
|
13479
|
+
`(Get-Item "$env:LOCALAPPDATA\\Programs\\Claude\\Claude.exe").VersionInfo.ProductVersion`
|
|
13480
|
+
]
|
|
13440
13481
|
}
|
|
13441
13482
|
};
|
|
13442
13483
|
var getProcessInfo = (pid) => {
|
|
@@ -13481,50 +13522,46 @@ var getHostInfo = () => {
|
|
|
13481
13522
|
for (const [name, server] of Object.entries(
|
|
13482
13523
|
cfg.mcpServers || cfg.servers || {}
|
|
13483
13524
|
)) {
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13525
|
+
if (server.command || server.url) {
|
|
13526
|
+
servers.push({
|
|
13527
|
+
ide,
|
|
13528
|
+
name,
|
|
13529
|
+
command: `${server.command} ${server.args ? server.args?.join(" ") : ""}`,
|
|
13530
|
+
isRunning: false,
|
|
13531
|
+
...server.url && { url: server.url }
|
|
13532
|
+
});
|
|
13533
|
+
}
|
|
13490
13534
|
}
|
|
13491
13535
|
}
|
|
13492
13536
|
const runningLines = runningProcesses.split("\n");
|
|
13493
13537
|
for (const line of runningLines) {
|
|
13494
13538
|
if (line.includes("mcp")) {
|
|
13495
13539
|
const cmdLower = line.toLowerCase();
|
|
13540
|
+
let ideName = "Unknown";
|
|
13541
|
+
const pidMatch = line.trim().split(/\s+/)[1];
|
|
13542
|
+
const pid = parseInt(String(pidMatch), 10);
|
|
13543
|
+
if (!isNaN(pid)) {
|
|
13544
|
+
let currentPid = pid;
|
|
13545
|
+
while (currentPid && currentPid !== 0) {
|
|
13546
|
+
const proc = getProcessInfo(currentPid);
|
|
13547
|
+
if (!proc) break;
|
|
13548
|
+
const cmdProc = proc.cmd.toLowerCase();
|
|
13549
|
+
const found = Object.keys(knownHosts).find(
|
|
13550
|
+
(key) => cmdProc.includes(key)
|
|
13551
|
+
);
|
|
13552
|
+
if (found) {
|
|
13553
|
+
ideName = knownHosts[found] || "Unknown";
|
|
13554
|
+
break;
|
|
13555
|
+
}
|
|
13556
|
+
currentPid = parseInt(proc.ppid, 10);
|
|
13557
|
+
}
|
|
13558
|
+
}
|
|
13496
13559
|
const existingServer = servers.find(
|
|
13497
|
-
(s) => s.command && cmdLower.includes(s.command.toLowerCase())
|
|
13560
|
+
(s) => s.command && cmdLower.includes(s.command.toLowerCase()) && s.ide.toLowerCase() === ideName.toLowerCase()
|
|
13498
13561
|
);
|
|
13499
13562
|
if (existingServer) {
|
|
13500
13563
|
existingServer.isRunning = true;
|
|
13501
13564
|
} 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
13565
|
servers.push({
|
|
13529
13566
|
ide: ideName.toLowerCase(),
|
|
13530
13567
|
name: "unknown",
|
|
@@ -13534,6 +13571,14 @@ var getHostInfo = () => {
|
|
|
13534
13571
|
}
|
|
13535
13572
|
}
|
|
13536
13573
|
}
|
|
13574
|
+
for (const server of servers) {
|
|
13575
|
+
if (server.url && !server.isRunning) {
|
|
13576
|
+
const isUrlAccessible = checkUrlAccessibility(server.url);
|
|
13577
|
+
if (isUrlAccessible) {
|
|
13578
|
+
server.isRunning = true;
|
|
13579
|
+
}
|
|
13580
|
+
}
|
|
13581
|
+
}
|
|
13537
13582
|
for (const { ide, name, command, isRunning } of servers) {
|
|
13538
13583
|
const config4 = allConfigs[ide] || null;
|
|
13539
13584
|
const ideName = ide.charAt(0).toUpperCase() + ide.slice(1) || "Unknown";
|
|
@@ -13570,11 +13615,17 @@ var getHostInfo = () => {
|
|
|
13570
13615
|
};
|
|
13571
13616
|
|
|
13572
13617
|
// src/mcp/services/McpUsageService/McpUsageService.ts
|
|
13618
|
+
init_configs();
|
|
13619
|
+
import fetch5 from "node-fetch";
|
|
13620
|
+
import os4 from "os";
|
|
13621
|
+
import { v4 as uuidv43, v5 as uuidv5 } from "uuid";
|
|
13573
13622
|
var McpUsageService = class {
|
|
13574
|
-
constructor() {
|
|
13623
|
+
constructor(govOrgId) {
|
|
13575
13624
|
__publicField(this, "configKey", "mcpUsage");
|
|
13576
13625
|
__publicField(this, "intervalId", null);
|
|
13577
13626
|
__publicField(this, "REST_API_URL", MCP_DEFAULT_REST_API_URL);
|
|
13627
|
+
__publicField(this, "govOrgId");
|
|
13628
|
+
this.govOrgId = govOrgId;
|
|
13578
13629
|
this.startPeriodicTracking();
|
|
13579
13630
|
if (process.env["API_URL"]) {
|
|
13580
13631
|
const url = new URL(process.env["API_URL"]);
|
|
@@ -13594,7 +13645,7 @@ var McpUsageService = class {
|
|
|
13594
13645
|
logDebug(`[UsageService] Triggering periodic usage service`, {
|
|
13595
13646
|
MCP_PERIODIC_TRACK_INTERVAL
|
|
13596
13647
|
});
|
|
13597
|
-
await
|
|
13648
|
+
await this.trackServerStart();
|
|
13598
13649
|
}, 1e4);
|
|
13599
13650
|
}
|
|
13600
13651
|
generateHostId() {
|
|
@@ -13614,18 +13665,16 @@ var McpUsageService = class {
|
|
|
13614
13665
|
return hostId;
|
|
13615
13666
|
}
|
|
13616
13667
|
getOrganizationId() {
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
organizationId
|
|
13668
|
+
if (this.govOrgId) {
|
|
13669
|
+
logDebug("[UsageService] Using provided organization ID", {
|
|
13670
|
+
organizationId: this.govOrgId
|
|
13621
13671
|
});
|
|
13622
|
-
return
|
|
13672
|
+
return this.govOrgId;
|
|
13623
13673
|
}
|
|
13624
13674
|
return "";
|
|
13625
13675
|
}
|
|
13626
13676
|
hasOrganizationId() {
|
|
13627
|
-
|
|
13628
|
-
return !!organizationId;
|
|
13677
|
+
return !!this.govOrgId;
|
|
13629
13678
|
}
|
|
13630
13679
|
createUsageData(mcpHostId, organizationId, status) {
|
|
13631
13680
|
const { user, mcps } = getHostInfo();
|
|
@@ -13711,12 +13760,12 @@ var McpUsageService = class {
|
|
|
13711
13760
|
this.intervalId = null;
|
|
13712
13761
|
}
|
|
13713
13762
|
};
|
|
13714
|
-
var mcpUsageService = new McpUsageService();
|
|
13715
13763
|
|
|
13716
13764
|
// src/mcp/tools/toolNames.ts
|
|
13717
13765
|
var MCP_TOOL_CHECK_FOR_NEW_AVAILABLE_FIXES = "check_for_new_available_fixes";
|
|
13718
13766
|
var MCP_TOOL_FETCH_AVAILABLE_FIXES = "fetch_available_fixes";
|
|
13719
13767
|
var MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES = "scan_and_fix_vulnerabilities";
|
|
13768
|
+
var MCP_TOOL_CHECKER = "mcp_checker";
|
|
13720
13769
|
|
|
13721
13770
|
// src/mcp/core/McpServer.ts
|
|
13722
13771
|
init_configs();
|
|
@@ -13741,6 +13790,9 @@ var ToolRegistry = class {
|
|
|
13741
13790
|
getTool(name) {
|
|
13742
13791
|
return this.tools.get(name);
|
|
13743
13792
|
}
|
|
13793
|
+
getToolDefinition(name) {
|
|
13794
|
+
return this.tools.get(name)?.getDefinition();
|
|
13795
|
+
}
|
|
13744
13796
|
getAllTools() {
|
|
13745
13797
|
return Array.from(this.tools.values()).map((tool) => tool.getDefinition());
|
|
13746
13798
|
}
|
|
@@ -13757,14 +13809,16 @@ var ToolRegistry = class {
|
|
|
13757
13809
|
|
|
13758
13810
|
// src/mcp/core/McpServer.ts
|
|
13759
13811
|
var McpServer = class {
|
|
13760
|
-
constructor(config4) {
|
|
13812
|
+
constructor(config4, govOrgId = "") {
|
|
13761
13813
|
__publicField(this, "server");
|
|
13762
13814
|
__publicField(this, "toolRegistry");
|
|
13763
13815
|
__publicField(this, "isEventHandlersSetup", false);
|
|
13764
13816
|
__publicField(this, "eventHandlers", /* @__PURE__ */ new Map());
|
|
13765
13817
|
__publicField(this, "parentProcessCheckInterval");
|
|
13766
13818
|
__publicField(this, "parentPid");
|
|
13819
|
+
__publicField(this, "mcpUsageService");
|
|
13767
13820
|
this.parentPid = process.ppid;
|
|
13821
|
+
this.mcpUsageService = govOrgId ? new McpUsageService(govOrgId) : null;
|
|
13768
13822
|
this.server = new Server(
|
|
13769
13823
|
{
|
|
13770
13824
|
name: config4.name,
|
|
@@ -13788,18 +13842,18 @@ var McpServer = class {
|
|
|
13788
13842
|
}
|
|
13789
13843
|
async trackServerUsage(action, signalOrError) {
|
|
13790
13844
|
try {
|
|
13791
|
-
if (!mcpUsageService
|
|
13845
|
+
if (!this.mcpUsageService?.hasOrganizationId()) {
|
|
13792
13846
|
logDebug(
|
|
13793
13847
|
`[McpServer] Skipping ${action} usage tracking - organization ID not available`
|
|
13794
13848
|
);
|
|
13795
13849
|
return;
|
|
13796
13850
|
}
|
|
13797
13851
|
if (action === "start") {
|
|
13798
|
-
await mcpUsageService
|
|
13852
|
+
await this.mcpUsageService?.trackServerStart();
|
|
13799
13853
|
}
|
|
13800
13854
|
if (action === "stop") {
|
|
13801
|
-
await mcpUsageService
|
|
13802
|
-
mcpUsageService
|
|
13855
|
+
await this.mcpUsageService?.trackServerStop();
|
|
13856
|
+
this.mcpUsageService?.reset();
|
|
13803
13857
|
}
|
|
13804
13858
|
} catch (usageError) {
|
|
13805
13859
|
logWarn(`Failed to track MCP server ${action}`, {
|
|
@@ -14002,10 +14056,21 @@ var McpServer = class {
|
|
|
14002
14056
|
}
|
|
14003
14057
|
}
|
|
14004
14058
|
async handleListToolsRequest(request) {
|
|
14005
|
-
const
|
|
14006
|
-
if (
|
|
14059
|
+
const mcpCheckerTool = this.toolRegistry.getToolDefinition(MCP_TOOL_CHECKER);
|
|
14060
|
+
if (mcpCheckerTool) {
|
|
14007
14061
|
return {
|
|
14008
|
-
tools: [
|
|
14062
|
+
tools: [
|
|
14063
|
+
{
|
|
14064
|
+
name: mcpCheckerTool.name,
|
|
14065
|
+
display_name: mcpCheckerTool.display_name || mcpCheckerTool.name,
|
|
14066
|
+
description: mcpCheckerTool.description,
|
|
14067
|
+
inputSchema: {
|
|
14068
|
+
type: "object",
|
|
14069
|
+
properties: mcpCheckerTool.inputSchema.properties || {},
|
|
14070
|
+
required: mcpCheckerTool.inputSchema.required || []
|
|
14071
|
+
}
|
|
14072
|
+
}
|
|
14073
|
+
]
|
|
14009
14074
|
};
|
|
14010
14075
|
}
|
|
14011
14076
|
logInfo("Received list_tools request");
|
|
@@ -14215,10 +14280,12 @@ var BaseTool = class {
|
|
|
14215
14280
|
};
|
|
14216
14281
|
}
|
|
14217
14282
|
async execute(args) {
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14283
|
+
if (this.hasAuthentication) {
|
|
14284
|
+
logDebug(`Authenticating tool: ${this.name}`, { args });
|
|
14285
|
+
const mcpGqlClient = await createAuthenticatedMcpGQLClient();
|
|
14286
|
+
const userInfo = await mcpGqlClient.getUserInfo();
|
|
14287
|
+
logDebug("User authenticated successfully", { userInfo });
|
|
14288
|
+
}
|
|
14222
14289
|
const validatedArgs = this.validateInput(args);
|
|
14223
14290
|
logDebug(`Tool ${this.name} input validation successful`, {
|
|
14224
14291
|
validatedArgs
|
|
@@ -17590,6 +17657,7 @@ Example payload:
|
|
|
17590
17657
|
{
|
|
17591
17658
|
"path": "/home/user/my-project"
|
|
17592
17659
|
}`);
|
|
17660
|
+
__publicField(this, "hasAuthentication", true);
|
|
17593
17661
|
__publicField(this, "inputSchema", {
|
|
17594
17662
|
type: "object",
|
|
17595
17663
|
properties: {
|
|
@@ -17732,6 +17800,7 @@ The tool will:
|
|
|
17732
17800
|
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
17801
|
|
|
17734
17802
|
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.`);
|
|
17803
|
+
__publicField(this, "hasAuthentication", true);
|
|
17735
17804
|
__publicField(this, "inputSchema", {
|
|
17736
17805
|
type: "object",
|
|
17737
17806
|
properties: {
|
|
@@ -17794,9 +17863,96 @@ Call this tool instead of ${MCP_TOOL_SCAN_AND_FIX_VULNERABILITIES} when you only
|
|
|
17794
17863
|
}
|
|
17795
17864
|
};
|
|
17796
17865
|
|
|
17866
|
+
// src/mcp/tools/mcpChecker/mcpCheckerTool.ts
|
|
17867
|
+
import z36 from "zod";
|
|
17868
|
+
|
|
17869
|
+
// src/mcp/tools/mcpChecker/mcpCheckerService.ts
|
|
17870
|
+
var _McpCheckerService = class _McpCheckerService {
|
|
17871
|
+
constructor(govOrgId) {
|
|
17872
|
+
__publicField(this, "govOrgId");
|
|
17873
|
+
this.govOrgId = govOrgId;
|
|
17874
|
+
}
|
|
17875
|
+
static getInstance(govOrgId) {
|
|
17876
|
+
if (!_McpCheckerService.instances.has(govOrgId)) {
|
|
17877
|
+
_McpCheckerService.instances.set(govOrgId, new _McpCheckerService(govOrgId));
|
|
17878
|
+
}
|
|
17879
|
+
return _McpCheckerService.instances.get(govOrgId);
|
|
17880
|
+
}
|
|
17881
|
+
processMcpCheck() {
|
|
17882
|
+
if (!this.govOrgId) {
|
|
17883
|
+
return {
|
|
17884
|
+
content: [
|
|
17885
|
+
{
|
|
17886
|
+
type: "text",
|
|
17887
|
+
text: ""
|
|
17888
|
+
}
|
|
17889
|
+
]
|
|
17890
|
+
};
|
|
17891
|
+
}
|
|
17892
|
+
logInfo("Executing built-in mcp_checker tool");
|
|
17893
|
+
const hostInfo = getHostInfo();
|
|
17894
|
+
const mcpServersInfo = hostInfo.mcps.filter((mcp) => mcp.mcpName !== "unknown").map(
|
|
17895
|
+
(mcp) => `- ${mcp.mcpName} (${mcp.ideName} ${mcp.ideVersion}): ${mcp.isRunning ? "\u2705 Running" : "\u274C Not Running"}`
|
|
17896
|
+
).join("\n");
|
|
17897
|
+
const response = {
|
|
17898
|
+
content: [
|
|
17899
|
+
{
|
|
17900
|
+
type: "text",
|
|
17901
|
+
text: `MCP Server Status Report
|
|
17902
|
+
|
|
17903
|
+
User: ${hostInfo.user.name} (${hostInfo.user.email})
|
|
17904
|
+
|
|
17905
|
+
Configured MCP Servers:
|
|
17906
|
+
${mcpServersInfo}
|
|
17907
|
+
|
|
17908
|
+
Total Servers: ${hostInfo.mcps.length}
|
|
17909
|
+
Running Servers: ${hostInfo.mcps.filter((mcp) => mcp.isRunning).length}`
|
|
17910
|
+
}
|
|
17911
|
+
]
|
|
17912
|
+
};
|
|
17913
|
+
logInfo("mcp_checker tool executed successfully");
|
|
17914
|
+
return response;
|
|
17915
|
+
}
|
|
17916
|
+
};
|
|
17917
|
+
__publicField(_McpCheckerService, "instances", /* @__PURE__ */ new Map());
|
|
17918
|
+
var McpCheckerService = _McpCheckerService;
|
|
17919
|
+
|
|
17920
|
+
// src/mcp/tools/mcpChecker/mcpCheckerTool.ts
|
|
17921
|
+
var McpCheckerTool = class extends BaseTool {
|
|
17922
|
+
constructor(govOrgId) {
|
|
17923
|
+
super();
|
|
17924
|
+
__publicField(this, "name", MCP_TOOL_CHECKER);
|
|
17925
|
+
__publicField(this, "displayName", "MCP Checker");
|
|
17926
|
+
// A detailed description to guide the LLM on when and how to invoke this tool.
|
|
17927
|
+
__publicField(this, "description", "Check the MCP servers running on this IDE against organization policies.");
|
|
17928
|
+
__publicField(this, "inputValidationSchema", z36.object({}));
|
|
17929
|
+
__publicField(this, "inputSchema", {
|
|
17930
|
+
type: "object",
|
|
17931
|
+
properties: {},
|
|
17932
|
+
required: []
|
|
17933
|
+
});
|
|
17934
|
+
__publicField(this, "hasAuthentication", false);
|
|
17935
|
+
__publicField(this, "mcpCheckerService");
|
|
17936
|
+
this.mcpCheckerService = McpCheckerService.getInstance(govOrgId);
|
|
17937
|
+
}
|
|
17938
|
+
async executeInternal(args) {
|
|
17939
|
+
logDebug(`Executing tool: ${this.name}`, { args });
|
|
17940
|
+
try {
|
|
17941
|
+
return this.mcpCheckerService.processMcpCheck();
|
|
17942
|
+
} catch (error) {
|
|
17943
|
+
const errorResponse = this.createSuccessResponse(error.message);
|
|
17944
|
+
logError("Tool execution failed", {
|
|
17945
|
+
error: error.message,
|
|
17946
|
+
result: errorResponse
|
|
17947
|
+
});
|
|
17948
|
+
return errorResponse;
|
|
17949
|
+
}
|
|
17950
|
+
}
|
|
17951
|
+
};
|
|
17952
|
+
|
|
17797
17953
|
// src/mcp/tools/scanAndFixVulnerabilities/ScanAndFixVulnerabilitiesTool.ts
|
|
17798
17954
|
init_configs();
|
|
17799
|
-
import
|
|
17955
|
+
import z37 from "zod";
|
|
17800
17956
|
|
|
17801
17957
|
// src/mcp/tools/scanAndFixVulnerabilities/ScanAndFixVulnerabilitiesService.ts
|
|
17802
17958
|
init_configs();
|
|
@@ -17981,16 +18137,17 @@ Example payload:
|
|
|
17981
18137
|
"maxFiles": 50,
|
|
17982
18138
|
"rescan": false
|
|
17983
18139
|
}`);
|
|
17984
|
-
__publicField(this, "
|
|
17985
|
-
|
|
18140
|
+
__publicField(this, "hasAuthentication", true);
|
|
18141
|
+
__publicField(this, "inputValidationSchema", z37.object({
|
|
18142
|
+
path: z37.string().describe(
|
|
17986
18143
|
"Full local path to repository to scan and fix vulnerabilities"
|
|
17987
18144
|
),
|
|
17988
|
-
offset:
|
|
17989
|
-
limit:
|
|
17990
|
-
maxFiles:
|
|
18145
|
+
offset: z37.number().optional().describe("Optional offset for pagination"),
|
|
18146
|
+
limit: z37.number().optional().describe("Optional maximum number of results to return"),
|
|
18147
|
+
maxFiles: z37.number().optional().describe(
|
|
17991
18148
|
`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
18149
|
),
|
|
17993
|
-
rescan:
|
|
18150
|
+
rescan: z37.boolean().optional().describe("Optional whether to rescan the repository")
|
|
17994
18151
|
}));
|
|
17995
18152
|
__publicField(this, "inputSchema", {
|
|
17996
18153
|
type: "object",
|
|
@@ -18023,7 +18180,7 @@ Example payload:
|
|
|
18023
18180
|
this.vulnerabilityFixService.reset();
|
|
18024
18181
|
}
|
|
18025
18182
|
async executeInternal(args) {
|
|
18026
|
-
logDebug(`Executing tool: ${
|
|
18183
|
+
logDebug(`Executing tool: ${this.name}`, {
|
|
18027
18184
|
path: args.path
|
|
18028
18185
|
});
|
|
18029
18186
|
if (!args.path) {
|
|
@@ -18080,12 +18237,15 @@ Example payload:
|
|
|
18080
18237
|
};
|
|
18081
18238
|
|
|
18082
18239
|
// src/mcp/index.ts
|
|
18083
|
-
function createMcpServer() {
|
|
18240
|
+
function createMcpServer(govOrgId) {
|
|
18084
18241
|
logDebug("Creating MCP server");
|
|
18085
|
-
const server = new McpServer(
|
|
18086
|
-
|
|
18087
|
-
|
|
18088
|
-
|
|
18242
|
+
const server = new McpServer(
|
|
18243
|
+
{
|
|
18244
|
+
name: "mobb-mcp",
|
|
18245
|
+
version: packageJson.version
|
|
18246
|
+
},
|
|
18247
|
+
govOrgId
|
|
18248
|
+
);
|
|
18089
18249
|
const enabledToolsEnv = process.env["TOOLS_ENABLED"];
|
|
18090
18250
|
const enabledToolsSet = enabledToolsEnv ? new Set(
|
|
18091
18251
|
enabledToolsEnv.split(",").map((t) => t.trim()).filter((t) => t.length > 0)
|
|
@@ -18104,6 +18264,10 @@ function createMcpServer() {
|
|
|
18104
18264
|
registerIfEnabled(scanAndFixVulnerabilitiesTool);
|
|
18105
18265
|
registerIfEnabled(fetchAvailableFixesTool);
|
|
18106
18266
|
registerIfEnabled(checkForNewAvailableFixesTool);
|
|
18267
|
+
if (govOrgId) {
|
|
18268
|
+
const mcpCheckerTool = new McpCheckerTool(govOrgId);
|
|
18269
|
+
registerIfEnabled(mcpCheckerTool);
|
|
18270
|
+
}
|
|
18107
18271
|
logInfo("MCP server created and configured");
|
|
18108
18272
|
return server;
|
|
18109
18273
|
}
|
|
@@ -18112,8 +18276,7 @@ async function startMcpServer({
|
|
|
18112
18276
|
}) {
|
|
18113
18277
|
try {
|
|
18114
18278
|
logDebug("Initializing MCP server");
|
|
18115
|
-
|
|
18116
|
-
const server = createMcpServer();
|
|
18279
|
+
const server = createMcpServer(govOrgId);
|
|
18117
18280
|
await server.start();
|
|
18118
18281
|
} catch (error) {
|
|
18119
18282
|
logError("Failed to start MCP server", { error });
|