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.
- package/dist/index.mjs +346 -116
- 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
|
|
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
|
|
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
|
|
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
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
"
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
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
|
|
13390
|
-
const filePath = getMCPConfigPath(hostName);
|
|
13437
|
+
var readConfigFile = (filePath) => {
|
|
13391
13438
|
if (!fs10.existsSync(filePath)) return null;
|
|
13392
|
-
|
|
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
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
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
|
|
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
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
organizationId
|
|
13735
|
+
if (this.govOrgId) {
|
|
13736
|
+
logDebug("[UsageService] Using provided organization ID", {
|
|
13737
|
+
organizationId: this.govOrgId
|
|
13621
13738
|
});
|
|
13622
|
-
return
|
|
13739
|
+
return this.govOrgId;
|
|
13623
13740
|
}
|
|
13624
13741
|
return "";
|
|
13625
13742
|
}
|
|
13626
13743
|
hasOrganizationId() {
|
|
13627
|
-
|
|
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
|
|
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
|
|
13919
|
+
await this.mcpUsageService?.trackServerStart();
|
|
13799
13920
|
}
|
|
13800
13921
|
if (action === "stop") {
|
|
13801
|
-
await mcpUsageService
|
|
13802
|
-
mcpUsageService
|
|
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
|
|
14006
|
-
if (
|
|
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
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
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
|
|
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, "
|
|
17985
|
-
|
|
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:
|
|
17989
|
-
limit:
|
|
17990
|
-
maxFiles:
|
|
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:
|
|
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: ${
|
|
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
|
-
|
|
18087
|
-
|
|
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
|
-
|
|
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 });
|