@wuyax/mcps 0.1.0-beta.1 → 0.1.0-beta.2
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/README.md +339 -115
- package/dist/{chunk-XW2KL6W3.js → chunk-7V5XL4RI.js} +728 -144
- package/dist/cli.cjs +735 -179
- package/dist/cli.js +5 -17
- package/dist/index.cjs +743 -145
- package/dist/index.d.cts +78 -2
- package/dist/index.d.ts +78 -2
- package/dist/index.js +25 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,7 +40,11 @@ __export(src_exports, {
|
|
|
40
40
|
createAgentTransform: () => createAgentTransform,
|
|
41
41
|
detectGloballyInstalledMcpAgents: () => detectGloballyInstalledMcpAgents,
|
|
42
42
|
detectProjectInstalledMcpAgents: () => detectProjectInstalledMcpAgents,
|
|
43
|
+
displayServerDetails: () => displayServerDetails,
|
|
43
44
|
extractPackageName: () => extractPackageName,
|
|
45
|
+
formatArgsString: () => formatArgsString,
|
|
46
|
+
formatEnvText: () => formatEnvText,
|
|
47
|
+
formatHeadersText: () => formatHeadersText,
|
|
44
48
|
getMcpAgentConfig: () => getMcpAgentConfig,
|
|
45
49
|
getMcpAgentTypes: () => getMcpAgentTypes,
|
|
46
50
|
getMcpAgentsSupportingProjectScope: () => getMcpAgentsSupportingProjectScope,
|
|
@@ -58,8 +62,11 @@ __export(src_exports, {
|
|
|
58
62
|
listInstalledMcpServers: () => listInstalledMcpServers,
|
|
59
63
|
listServersInConfigFile: () => listServersInConfigFile,
|
|
60
64
|
mainMenu: () => mainMenu,
|
|
65
|
+
maskSecretHeader: () => maskSecretHeader,
|
|
66
|
+
maskSecretValue: () => maskSecretValue,
|
|
61
67
|
mcpAgentAliases: () => mcpAgentAliases,
|
|
62
68
|
mcpAgents: () => mcpAgents,
|
|
69
|
+
mcpManageCommand: () => mcpManageCommand,
|
|
63
70
|
normalizeServerConfig: () => normalizeServerConfig,
|
|
64
71
|
parseArgsString: () => parseArgsString,
|
|
65
72
|
parseEnvText: () => parseEnvText,
|
|
@@ -68,6 +75,10 @@ __export(src_exports, {
|
|
|
68
75
|
parseServerConfig: () => parseServerConfig,
|
|
69
76
|
parseSource: () => parseMcpSource,
|
|
70
77
|
promptArgsConfig: () => promptArgsConfig,
|
|
78
|
+
promptEditArgs: () => promptEditArgs,
|
|
79
|
+
promptEditEnvConfig: () => promptEditEnvConfig,
|
|
80
|
+
promptEditHeadersConfig: () => promptEditHeadersConfig,
|
|
81
|
+
promptEditKeyValueConfig: () => promptEditKeyValueConfig,
|
|
71
82
|
promptEnvConfig: () => promptEnvConfig,
|
|
72
83
|
promptHeadersConfig: () => promptHeadersConfig,
|
|
73
84
|
promptScope: () => promptScope,
|
|
@@ -82,6 +93,8 @@ __export(src_exports, {
|
|
|
82
93
|
resolveTargetAgents: () => resolveTargetAgents,
|
|
83
94
|
transformServerConfig: () => transformServerConfig,
|
|
84
95
|
transformServerConfigForAgent: () => transformServerConfigForAgent,
|
|
96
|
+
updateMcpServerForAgent: () => installMcpServerForAgent,
|
|
97
|
+
updateMcpServerForAgents: () => installMcpServerForAgents,
|
|
85
98
|
wizardAdd: () => wizardAdd,
|
|
86
99
|
wizardManage: () => wizardManage,
|
|
87
100
|
wizardRemove: () => wizardRemove,
|
|
@@ -543,9 +556,9 @@ var mcpAgentAliases = {
|
|
|
543
556
|
var getMcpAgentConfig = (agentType) => mcpAgents[agentType];
|
|
544
557
|
var getMcpAgentTypes = () => Object.values(mcpAgents).map((config) => config.name);
|
|
545
558
|
var isMcpAgentType = (value) => value in mcpAgents;
|
|
546
|
-
var resolveMcpAgentAlias = (
|
|
547
|
-
if (isMcpAgentType(
|
|
548
|
-
return mcpAgentAliases[
|
|
559
|
+
var resolveMcpAgentAlias = (input7) => {
|
|
560
|
+
if (isMcpAgentType(input7)) return input7;
|
|
561
|
+
return mcpAgentAliases[input7] ?? null;
|
|
549
562
|
};
|
|
550
563
|
var isMcpTransportSupported = (agent, transport) => agent.supportedTransports.includes(transport);
|
|
551
564
|
var detectProjectInstalledMcpAgents = (cwd) => getMcpAgentTypes().filter(
|
|
@@ -1291,11 +1304,11 @@ var installMcpServerForAgents = (serverName, serverConfig, agentTypes, options =
|
|
|
1291
1304
|
);
|
|
1292
1305
|
|
|
1293
1306
|
// src/utils/parse-mcp-agent-list.ts
|
|
1294
|
-
var parseMcpAgentList = (
|
|
1295
|
-
if (!
|
|
1296
|
-
if (
|
|
1307
|
+
var parseMcpAgentList = (input7) => {
|
|
1308
|
+
if (!input7 || input7.length === 0) return void 0;
|
|
1309
|
+
if (input7.includes("*")) return getMcpAgentTypes();
|
|
1297
1310
|
const resolved = [];
|
|
1298
|
-
for (const value of
|
|
1311
|
+
for (const value of input7) {
|
|
1299
1312
|
const agentType = resolveMcpAgentAlias(value);
|
|
1300
1313
|
if (!agentType) throw new Error(`Unknown MCP agent "${value}"`);
|
|
1301
1314
|
resolved.push(agentType);
|
|
@@ -1304,9 +1317,9 @@ var parseMcpAgentList = (input5) => {
|
|
|
1304
1317
|
};
|
|
1305
1318
|
|
|
1306
1319
|
// src/resolve-target-agents.ts
|
|
1307
|
-
var normalizeRequestedAgents = (
|
|
1308
|
-
if (!
|
|
1309
|
-
const rawList = [...
|
|
1320
|
+
var normalizeRequestedAgents = (input7) => {
|
|
1321
|
+
if (!input7 || input7.length === 0) return void 0;
|
|
1322
|
+
const rawList = [...input7];
|
|
1310
1323
|
if (rawList.every((item) => isMcpAgentType(item))) {
|
|
1311
1324
|
return rawList;
|
|
1312
1325
|
}
|
|
@@ -1366,29 +1379,29 @@ var REMOTE_URL_REGEX = /^https?:\/\//i;
|
|
|
1366
1379
|
var HAS_WHITESPACE_REGEX = /\s/;
|
|
1367
1380
|
var PACKAGE_NAME_REGEX = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(?:@[^\s]+)?$/;
|
|
1368
1381
|
var PATH_SEPARATOR_REGEX = /[/\\]/;
|
|
1369
|
-
var stripVersionSuffix = (
|
|
1370
|
-
if (
|
|
1371
|
-
const secondAtIndex =
|
|
1372
|
-
if (secondAtIndex > 0) return
|
|
1373
|
-
return
|
|
1374
|
-
}
|
|
1375
|
-
const atIndex =
|
|
1376
|
-
if (atIndex > 0) return
|
|
1377
|
-
return
|
|
1378
|
-
};
|
|
1379
|
-
var stripScopePrefix = (
|
|
1380
|
-
if (!
|
|
1381
|
-
const parts =
|
|
1382
|
-
return parts[1] ||
|
|
1383
|
-
};
|
|
1384
|
-
var stripPathPrefix = (
|
|
1385
|
-
if (!PATH_SEPARATOR_REGEX.test(
|
|
1386
|
-
const segments =
|
|
1382
|
+
var stripVersionSuffix = (input7) => {
|
|
1383
|
+
if (input7.startsWith("@")) {
|
|
1384
|
+
const secondAtIndex = input7.indexOf("@", 1);
|
|
1385
|
+
if (secondAtIndex > 0) return input7.slice(0, secondAtIndex);
|
|
1386
|
+
return input7;
|
|
1387
|
+
}
|
|
1388
|
+
const atIndex = input7.lastIndexOf("@");
|
|
1389
|
+
if (atIndex > 0) return input7.slice(0, atIndex);
|
|
1390
|
+
return input7;
|
|
1391
|
+
};
|
|
1392
|
+
var stripScopePrefix = (input7) => {
|
|
1393
|
+
if (!input7.startsWith("@") || !input7.includes("/")) return input7;
|
|
1394
|
+
const parts = input7.split("/");
|
|
1395
|
+
return parts[1] || input7;
|
|
1396
|
+
};
|
|
1397
|
+
var stripPathPrefix = (input7) => {
|
|
1398
|
+
if (!PATH_SEPARATOR_REGEX.test(input7)) return input7;
|
|
1399
|
+
const segments = input7.split(PATH_SEPARATOR_REGEX);
|
|
1387
1400
|
const basename = segments[segments.length - 1];
|
|
1388
|
-
return basename ||
|
|
1401
|
+
return basename || input7;
|
|
1389
1402
|
};
|
|
1390
|
-
var extractPackageName = (
|
|
1391
|
-
let name = stripVersionSuffix(
|
|
1403
|
+
var extractPackageName = (input7) => {
|
|
1404
|
+
let name = stripVersionSuffix(input7);
|
|
1392
1405
|
name = stripScopePrefix(name);
|
|
1393
1406
|
name = stripPathPrefix(name);
|
|
1394
1407
|
name = name.replace(SCRIPT_EXTENSION_REGEX, "");
|
|
@@ -1406,9 +1419,9 @@ var extractPackageName = (input5) => {
|
|
|
1406
1419
|
}
|
|
1407
1420
|
return name || MCP_DEFAULT_SERVER_NAME;
|
|
1408
1421
|
};
|
|
1409
|
-
var inferNameFromUrl = (
|
|
1422
|
+
var inferNameFromUrl = (input7) => {
|
|
1410
1423
|
try {
|
|
1411
|
-
const url = new URL(
|
|
1424
|
+
const url = new URL(input7);
|
|
1412
1425
|
const host = url.hostname;
|
|
1413
1426
|
const labels = host.split(".").filter((segment) => segment.length > 0);
|
|
1414
1427
|
if (labels.length === 0) return MCP_DEFAULT_SERVER_NAME;
|
|
@@ -1437,8 +1450,8 @@ var inferNameFromCommand = (command) => {
|
|
|
1437
1450
|
const firstNonFlag = tokens.find((token) => !token.startsWith("-"));
|
|
1438
1451
|
return firstNonFlag ? extractPackageName(firstNonFlag) : MCP_DEFAULT_SERVER_NAME;
|
|
1439
1452
|
};
|
|
1440
|
-
var parseMcpSource = (
|
|
1441
|
-
const trimmed =
|
|
1453
|
+
var parseMcpSource = (input7) => {
|
|
1454
|
+
const trimmed = input7.trim();
|
|
1442
1455
|
if (trimmed.length === 0) {
|
|
1443
1456
|
throw new Error(
|
|
1444
1457
|
"Invalid MCP source: input is empty. Expected a remote URL, an npm package, or a command line."
|
|
@@ -1564,12 +1577,12 @@ var removeMcpServer = (options) => {
|
|
|
1564
1577
|
};
|
|
1565
1578
|
|
|
1566
1579
|
// src/interactive/main-menu.ts
|
|
1567
|
-
var
|
|
1568
|
-
var
|
|
1580
|
+
var import_prompts11 = require("@inquirer/prompts");
|
|
1581
|
+
var import_picocolors11 = __toESM(require("picocolors"), 1);
|
|
1569
1582
|
|
|
1570
1583
|
// src/interactive/wizard-add.ts
|
|
1571
|
-
var
|
|
1572
|
-
var
|
|
1584
|
+
var import_prompts8 = require("@inquirer/prompts");
|
|
1585
|
+
var import_picocolors8 = __toESM(require("picocolors"), 1);
|
|
1573
1586
|
|
|
1574
1587
|
// src/utils/logger.ts
|
|
1575
1588
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
@@ -1693,10 +1706,25 @@ var promptArgsConfig = async (initialArgs = []) => {
|
|
|
1693
1706
|
});
|
|
1694
1707
|
return parseArgsString(raw.trim());
|
|
1695
1708
|
};
|
|
1709
|
+
var formatArgsString = (args) => {
|
|
1710
|
+
return args.map((arg) => arg.includes(" ") || arg.includes('"') ? `"${arg.replace(/"/g, '\\"')}"` : arg).join(" ");
|
|
1711
|
+
};
|
|
1712
|
+
var promptEditArgs = async (currentArgs = []) => {
|
|
1713
|
+
const defaultStr = formatArgsString(currentArgs);
|
|
1714
|
+
const raw = await (0, import_prompts3.input)({
|
|
1715
|
+
message: "Edit command arguments (space-separated, wrap paths with spaces in quotes, leave empty to clear):",
|
|
1716
|
+
default: defaultStr
|
|
1717
|
+
});
|
|
1718
|
+
const trimmed = raw.trim();
|
|
1719
|
+
if (!trimmed) {
|
|
1720
|
+
return [];
|
|
1721
|
+
}
|
|
1722
|
+
return parseArgsString(trimmed);
|
|
1723
|
+
};
|
|
1696
1724
|
|
|
1697
1725
|
// src/interactive/prompts/env.ts
|
|
1698
|
-
var
|
|
1699
|
-
var
|
|
1726
|
+
var import_prompts6 = require("@inquirer/prompts");
|
|
1727
|
+
var import_picocolors6 = __toESM(require("picocolors"), 1);
|
|
1700
1728
|
|
|
1701
1729
|
// src/interactive/prompts/multiline.ts
|
|
1702
1730
|
var import_node_readline = require("readline");
|
|
@@ -1759,8 +1787,166 @@ var promptEditorText = async (options) => {
|
|
|
1759
1787
|
}
|
|
1760
1788
|
};
|
|
1761
1789
|
|
|
1790
|
+
// src/interactive/prompts/kv.ts
|
|
1791
|
+
var import_prompts5 = require("@inquirer/prompts");
|
|
1792
|
+
var import_picocolors5 = __toESM(require("picocolors"), 1);
|
|
1793
|
+
var promptEditKeyValueConfig = async (currentItems = {}, options) => {
|
|
1794
|
+
let items = { ...currentItems };
|
|
1795
|
+
while (true) {
|
|
1796
|
+
const keys = Object.keys(items);
|
|
1797
|
+
console.log();
|
|
1798
|
+
if (keys.length === 0) {
|
|
1799
|
+
console.log(import_picocolors5.default.dim(` No ${options.itemsNoun} configured.`));
|
|
1800
|
+
} else {
|
|
1801
|
+
console.log(import_picocolors5.default.cyan(import_picocolors5.default.bold(` Configured ${options.title} (${keys.length}):`)));
|
|
1802
|
+
for (const [k, v] of Object.entries(items)) {
|
|
1803
|
+
const sep = options.separator === "=" ? "=" : ": ";
|
|
1804
|
+
console.log(` ${import_picocolors5.default.bold(k)}${sep}${import_picocolors5.default.dim(options.maskValue(k, v))}`);
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
console.log();
|
|
1808
|
+
const choice = await (0, import_prompts5.select)({
|
|
1809
|
+
message: `Manage ${options.itemsNoun}:`,
|
|
1810
|
+
choices: [
|
|
1811
|
+
{
|
|
1812
|
+
name: "Open in system default editor ($EDITOR)",
|
|
1813
|
+
value: "editor"
|
|
1814
|
+
},
|
|
1815
|
+
{
|
|
1816
|
+
name: `Add or modify a ${options.itemNoun}`,
|
|
1817
|
+
value: "upsert"
|
|
1818
|
+
},
|
|
1819
|
+
...keys.length > 0 ? [
|
|
1820
|
+
{
|
|
1821
|
+
name: `Delete a ${options.itemNoun}`,
|
|
1822
|
+
value: "delete"
|
|
1823
|
+
}
|
|
1824
|
+
] : [],
|
|
1825
|
+
{
|
|
1826
|
+
name: `Paste multiline ${options.itemsNoun} into terminal`,
|
|
1827
|
+
value: "paste"
|
|
1828
|
+
},
|
|
1829
|
+
...keys.length > 0 ? [
|
|
1830
|
+
{
|
|
1831
|
+
name: `Clear all ${options.itemsNoun}`,
|
|
1832
|
+
value: "clear"
|
|
1833
|
+
}
|
|
1834
|
+
] : [],
|
|
1835
|
+
{
|
|
1836
|
+
name: `Done (finish editing ${options.itemsNoun})`,
|
|
1837
|
+
value: "done"
|
|
1838
|
+
}
|
|
1839
|
+
]
|
|
1840
|
+
});
|
|
1841
|
+
if (choice === "done") {
|
|
1842
|
+
return items;
|
|
1843
|
+
}
|
|
1844
|
+
if (choice === "editor") {
|
|
1845
|
+
const defaultText = options.formatText(items);
|
|
1846
|
+
const text = await promptEditorText({
|
|
1847
|
+
message: options.editorMessage,
|
|
1848
|
+
postfix: options.editorPostfix,
|
|
1849
|
+
defaultText
|
|
1850
|
+
});
|
|
1851
|
+
const parsed = options.parseText(text);
|
|
1852
|
+
items = parsed;
|
|
1853
|
+
logger.success(`${options.title} updated (${Object.keys(items).length} total)`);
|
|
1854
|
+
} else if (choice === "upsert") {
|
|
1855
|
+
const key = await (0, import_prompts5.input)({
|
|
1856
|
+
message: options.keyPromptMessage,
|
|
1857
|
+
validate: (val) => {
|
|
1858
|
+
const trimmed = val.trim();
|
|
1859
|
+
if (!trimmed) return `${options.itemNoun} name cannot be empty`;
|
|
1860
|
+
if (/\s/.test(trimmed)) return `${options.itemNoun} name cannot contain spaces`;
|
|
1861
|
+
return true;
|
|
1862
|
+
}
|
|
1863
|
+
});
|
|
1864
|
+
const trimmedKey = key.trim();
|
|
1865
|
+
const existingVal = items[trimmedKey];
|
|
1866
|
+
const isSecret = options.isSecretKey(trimmedKey);
|
|
1867
|
+
let newVal;
|
|
1868
|
+
if (isSecret) {
|
|
1869
|
+
newVal = await (0, import_prompts5.password)({
|
|
1870
|
+
message: existingVal !== void 0 ? `New value for (${trimmedKey}) [leave empty to keep current]:` : `${options.valuePromptMessage} for (${trimmedKey}) [sensitive content masked]:`,
|
|
1871
|
+
mask: "*"
|
|
1872
|
+
});
|
|
1873
|
+
if (existingVal !== void 0 && newVal === "") {
|
|
1874
|
+
newVal = existingVal;
|
|
1875
|
+
}
|
|
1876
|
+
} else {
|
|
1877
|
+
newVal = await (0, import_prompts5.input)({
|
|
1878
|
+
message: `${options.valuePromptMessage} for (${trimmedKey}):`,
|
|
1879
|
+
default: existingVal
|
|
1880
|
+
});
|
|
1881
|
+
}
|
|
1882
|
+
items[trimmedKey] = newVal;
|
|
1883
|
+
logger.success(`${existingVal !== void 0 ? "Updated" : "Added"}: ${import_picocolors5.default.cyan(trimmedKey)}`);
|
|
1884
|
+
} else if (choice === "delete") {
|
|
1885
|
+
const toDelete = await (0, import_prompts5.select)({
|
|
1886
|
+
message: `Select ${options.itemNoun} to delete:`,
|
|
1887
|
+
choices: [
|
|
1888
|
+
...keys.map((k) => ({ name: k, value: k })),
|
|
1889
|
+
{ name: "Cancel", value: "__cancel__" }
|
|
1890
|
+
]
|
|
1891
|
+
});
|
|
1892
|
+
if (toDelete !== "__cancel__") {
|
|
1893
|
+
delete items[toDelete];
|
|
1894
|
+
logger.success(`Deleted: ${import_picocolors5.default.cyan(toDelete)}`);
|
|
1895
|
+
}
|
|
1896
|
+
} else if (choice === "paste") {
|
|
1897
|
+
const pasted = await readMultilineTextFromTerminal(options.pasteMessage);
|
|
1898
|
+
const parsed = options.parseText(pasted);
|
|
1899
|
+
const count = Object.keys(parsed).length;
|
|
1900
|
+
if (count === 0) {
|
|
1901
|
+
logger.warn(`No valid ${options.itemsNoun} recognized`);
|
|
1902
|
+
} else {
|
|
1903
|
+
if (keys.length > 0) {
|
|
1904
|
+
const pasteMode = await (0, import_prompts5.select)({
|
|
1905
|
+
message: `How to apply pasted ${options.itemsNoun}?`,
|
|
1906
|
+
choices: [
|
|
1907
|
+
{ name: `Merge with existing ${options.itemsNoun}`, value: "merge" },
|
|
1908
|
+
{ name: `Replace all existing ${options.itemsNoun}`, value: "replace" }
|
|
1909
|
+
]
|
|
1910
|
+
});
|
|
1911
|
+
if (pasteMode === "replace") {
|
|
1912
|
+
items = parsed;
|
|
1913
|
+
} else {
|
|
1914
|
+
Object.assign(items, parsed);
|
|
1915
|
+
}
|
|
1916
|
+
} else {
|
|
1917
|
+
items = parsed;
|
|
1918
|
+
}
|
|
1919
|
+
logger.success(`Successfully applied ${import_picocolors5.default.cyan(String(count))} ${options.itemsNoun}`);
|
|
1920
|
+
}
|
|
1921
|
+
} else if (choice === "clear") {
|
|
1922
|
+
const confirmClear = await (0, import_prompts5.confirm)({
|
|
1923
|
+
message: `Are you sure you want to clear all ${options.itemsNoun}?`,
|
|
1924
|
+
default: false
|
|
1925
|
+
});
|
|
1926
|
+
if (confirmClear) {
|
|
1927
|
+
items = {};
|
|
1928
|
+
logger.success(`Cleared all ${options.itemsNoun}`);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
};
|
|
1933
|
+
|
|
1762
1934
|
// src/interactive/prompts/env.ts
|
|
1763
1935
|
var SECRET_KEY_PATTERN = /(token|key|secret|password|passwd|auth|credential)/i;
|
|
1936
|
+
var maskSecretValue = (key, value) => {
|
|
1937
|
+
if (!SECRET_KEY_PATTERN.test(key) || value.length <= 4) {
|
|
1938
|
+
return value;
|
|
1939
|
+
}
|
|
1940
|
+
return `${value.slice(0, 2)}***${value.slice(-2)}`;
|
|
1941
|
+
};
|
|
1942
|
+
var formatEnvText = (env) => {
|
|
1943
|
+
return Object.entries(env).map(([key, value]) => {
|
|
1944
|
+
if (/[\s"']/.test(value)) {
|
|
1945
|
+
return `${key}="${value.replace(/"/g, '\\"')}"`;
|
|
1946
|
+
}
|
|
1947
|
+
return `${key}=${value}`;
|
|
1948
|
+
}).join("\n");
|
|
1949
|
+
};
|
|
1764
1950
|
var parseEnvText = (rawText) => {
|
|
1765
1951
|
const result = {};
|
|
1766
1952
|
const lines = rawText.split(/\r?\n/);
|
|
@@ -1786,9 +1972,9 @@ var promptEnvConfig = async (initialEnv = {}) => {
|
|
|
1786
1972
|
const env = { ...initialEnv };
|
|
1787
1973
|
const initialCount = Object.keys(env).length;
|
|
1788
1974
|
if (initialCount > 0) {
|
|
1789
|
-
logger.info(`Includes ${
|
|
1975
|
+
logger.info(`Includes ${import_picocolors6.default.cyan(String(initialCount))} preset environment variables`);
|
|
1790
1976
|
}
|
|
1791
|
-
const mode = await (0,
|
|
1977
|
+
const mode = await (0, import_prompts6.select)({
|
|
1792
1978
|
message: "Configure environment variables?",
|
|
1793
1979
|
choices: [
|
|
1794
1980
|
{
|
|
@@ -1815,7 +2001,8 @@ var promptEnvConfig = async (initialEnv = {}) => {
|
|
|
1815
2001
|
if (mode === "paste" || mode === "editor") {
|
|
1816
2002
|
const pasted = mode === "editor" ? await promptEditorText({
|
|
1817
2003
|
message: "Paste or edit environment variables in editor, then save and exit:",
|
|
1818
|
-
postfix: ".env"
|
|
2004
|
+
postfix: ".env",
|
|
2005
|
+
defaultText: formatEnvText(env)
|
|
1819
2006
|
}) : await readMultilineTextFromTerminal("Paste .env formatted content (multiline supported):");
|
|
1820
2007
|
const parsed = parseEnvText(pasted);
|
|
1821
2008
|
const count = Object.keys(parsed).length;
|
|
@@ -1823,17 +2010,16 @@ var promptEnvConfig = async (initialEnv = {}) => {
|
|
|
1823
2010
|
logger.warn("No valid KEY=VALUE pairs recognized");
|
|
1824
2011
|
} else {
|
|
1825
2012
|
Object.assign(env, parsed);
|
|
1826
|
-
logger.success(`Successfully parsed ${
|
|
2013
|
+
logger.success(`Successfully parsed ${import_picocolors6.default.cyan(String(count))} environment variables:`);
|
|
1827
2014
|
for (const [k, v] of Object.entries(parsed)) {
|
|
1828
|
-
|
|
1829
|
-
console.log(` ${import_picocolors5.default.bold(k)}=${import_picocolors5.default.dim(masked)}`);
|
|
2015
|
+
console.log(` ${import_picocolors6.default.bold(k)}=${import_picocolors6.default.dim(maskSecretValue(k, v))}`);
|
|
1830
2016
|
}
|
|
1831
2017
|
}
|
|
1832
2018
|
return env;
|
|
1833
2019
|
}
|
|
1834
2020
|
logger.info("Entering environment variables (leave key empty and press enter to finish):");
|
|
1835
2021
|
while (true) {
|
|
1836
|
-
const key = await (0,
|
|
2022
|
+
const key = await (0, import_prompts6.input)({
|
|
1837
2023
|
message: "Variable name (Key, leave empty to finish):",
|
|
1838
2024
|
validate: (val2) => {
|
|
1839
2025
|
const trimmed = val2.trim();
|
|
@@ -1847,25 +2033,49 @@ var promptEnvConfig = async (initialEnv = {}) => {
|
|
|
1847
2033
|
const isSecret = SECRET_KEY_PATTERN.test(trimmedKey);
|
|
1848
2034
|
let val;
|
|
1849
2035
|
if (isSecret) {
|
|
1850
|
-
val = await (0,
|
|
2036
|
+
val = await (0, import_prompts6.password)({
|
|
1851
2037
|
message: `Value for (${trimmedKey}) [secret masked]:`,
|
|
1852
2038
|
mask: "*"
|
|
1853
2039
|
});
|
|
1854
2040
|
} else {
|
|
1855
|
-
val = await (0,
|
|
2041
|
+
val = await (0, import_prompts6.input)({
|
|
1856
2042
|
message: `Value for (${trimmedKey}):`
|
|
1857
2043
|
});
|
|
1858
2044
|
}
|
|
1859
2045
|
env[trimmedKey] = val;
|
|
1860
|
-
logger.success(`Added: ${
|
|
2046
|
+
logger.success(`Added: ${import_picocolors6.default.cyan(trimmedKey)}`);
|
|
1861
2047
|
}
|
|
1862
2048
|
return env;
|
|
1863
2049
|
};
|
|
2050
|
+
var promptEditEnvConfig = async (currentEnv = {}) => promptEditKeyValueConfig(currentEnv, {
|
|
2051
|
+
title: "Environment Variables",
|
|
2052
|
+
itemNoun: "variable",
|
|
2053
|
+
itemsNoun: "environment variables",
|
|
2054
|
+
separator: "=",
|
|
2055
|
+
editorPostfix: ".env",
|
|
2056
|
+
editorMessage: "Edit environment variables in editor, then save and exit:",
|
|
2057
|
+
pasteMessage: "Paste .env formatted content (multiline supported):",
|
|
2058
|
+
keyPromptMessage: "Variable name (Key):",
|
|
2059
|
+
valuePromptMessage: "Value",
|
|
2060
|
+
isSecretKey: (k) => SECRET_KEY_PATTERN.test(k),
|
|
2061
|
+
maskValue: maskSecretValue,
|
|
2062
|
+
formatText: formatEnvText,
|
|
2063
|
+
parseText: parseEnvText
|
|
2064
|
+
});
|
|
1864
2065
|
|
|
1865
2066
|
// src/interactive/prompts/headers.ts
|
|
1866
|
-
var
|
|
1867
|
-
var
|
|
2067
|
+
var import_prompts7 = require("@inquirer/prompts");
|
|
2068
|
+
var import_picocolors7 = __toESM(require("picocolors"), 1);
|
|
1868
2069
|
var SECRET_HEADER_PATTERN = /(authorization|token|key|secret|auth)/i;
|
|
2070
|
+
var maskSecretHeader = (key, value) => {
|
|
2071
|
+
if (!SECRET_HEADER_PATTERN.test(key) || value.length <= 8) {
|
|
2072
|
+
return value;
|
|
2073
|
+
}
|
|
2074
|
+
return `${value.slice(0, 4)}***${value.slice(-3)}`;
|
|
2075
|
+
};
|
|
2076
|
+
var formatHeadersText = (headers) => {
|
|
2077
|
+
return Object.entries(headers).map(([key, value]) => `${key}: ${value}`).join("\n");
|
|
2078
|
+
};
|
|
1869
2079
|
var parseHeadersText = (rawText) => {
|
|
1870
2080
|
const result = {};
|
|
1871
2081
|
const lines = rawText.split(/\r?\n/);
|
|
@@ -1895,7 +2105,7 @@ var parseHeadersText = (rawText) => {
|
|
|
1895
2105
|
};
|
|
1896
2106
|
var promptHeadersConfig = async (initialHeaders = {}) => {
|
|
1897
2107
|
const headers = { ...initialHeaders };
|
|
1898
|
-
const mode = await (0,
|
|
2108
|
+
const mode = await (0, import_prompts7.select)({
|
|
1899
2109
|
message: "Select HTTP headers configuration method:",
|
|
1900
2110
|
choices: [
|
|
1901
2111
|
{
|
|
@@ -1921,7 +2131,8 @@ var promptHeadersConfig = async (initialHeaders = {}) => {
|
|
|
1921
2131
|
}
|
|
1922
2132
|
if (mode === "paste" || mode === "editor") {
|
|
1923
2133
|
const pasted = mode === "editor" ? await promptEditorText({
|
|
1924
|
-
message: "Paste or edit HTTP headers in editor, then save and exit:"
|
|
2134
|
+
message: "Paste or edit HTTP headers in editor, then save and exit:",
|
|
2135
|
+
defaultText: formatHeadersText(headers)
|
|
1925
2136
|
}) : await readMultilineTextFromTerminal(
|
|
1926
2137
|
"Paste HTTP headers content (multiline supported, e.g. Authorization: Bearer ...):"
|
|
1927
2138
|
);
|
|
@@ -1931,17 +2142,16 @@ var promptHeadersConfig = async (initialHeaders = {}) => {
|
|
|
1931
2142
|
logger.warn("No valid Key: Value pairs recognized");
|
|
1932
2143
|
} else {
|
|
1933
2144
|
Object.assign(headers, parsed);
|
|
1934
|
-
logger.success(`Successfully parsed ${
|
|
2145
|
+
logger.success(`Successfully parsed ${import_picocolors7.default.cyan(String(count))} headers:`);
|
|
1935
2146
|
for (const [k, v] of Object.entries(parsed)) {
|
|
1936
|
-
|
|
1937
|
-
console.log(` ${import_picocolors6.default.bold(k)}: ${import_picocolors6.default.dim(masked)}`);
|
|
2147
|
+
console.log(` ${import_picocolors7.default.bold(k)}: ${import_picocolors7.default.dim(maskSecretHeader(k, v))}`);
|
|
1938
2148
|
}
|
|
1939
2149
|
}
|
|
1940
2150
|
return headers;
|
|
1941
2151
|
}
|
|
1942
2152
|
logger.info("Entering HTTP headers (leave header name empty and press enter to finish):");
|
|
1943
2153
|
while (true) {
|
|
1944
|
-
const name = await (0,
|
|
2154
|
+
const name = await (0, import_prompts7.input)({
|
|
1945
2155
|
message: "Header name (e.g. Authorization, leave empty to finish):",
|
|
1946
2156
|
validate: (val2) => {
|
|
1947
2157
|
const trimmed = val2.trim();
|
|
@@ -1955,28 +2165,42 @@ var promptHeadersConfig = async (initialHeaders = {}) => {
|
|
|
1955
2165
|
const isSecret = SECRET_HEADER_PATTERN.test(trimmedName);
|
|
1956
2166
|
let val;
|
|
1957
2167
|
if (isSecret) {
|
|
1958
|
-
val = await (0,
|
|
2168
|
+
val = await (0, import_prompts7.password)({
|
|
1959
2169
|
message: `Header value for (${trimmedName}) [sensitive content masked]:`,
|
|
1960
2170
|
mask: "*"
|
|
1961
2171
|
});
|
|
1962
2172
|
} else {
|
|
1963
|
-
val = await (0,
|
|
2173
|
+
val = await (0, import_prompts7.input)({
|
|
1964
2174
|
message: `Header value for (${trimmedName}):`
|
|
1965
2175
|
});
|
|
1966
2176
|
}
|
|
1967
2177
|
headers[trimmedName] = val;
|
|
1968
|
-
logger.success(`Added: ${
|
|
2178
|
+
logger.success(`Added: ${import_picocolors7.default.cyan(trimmedName)}`);
|
|
1969
2179
|
}
|
|
1970
2180
|
return headers;
|
|
1971
2181
|
};
|
|
2182
|
+
var promptEditHeadersConfig = async (currentHeaders = {}) => promptEditKeyValueConfig(currentHeaders, {
|
|
2183
|
+
title: "HTTP Headers",
|
|
2184
|
+
itemNoun: "header",
|
|
2185
|
+
itemsNoun: "HTTP headers",
|
|
2186
|
+
separator: ":",
|
|
2187
|
+
editorMessage: "Edit HTTP headers in editor, then save and exit:",
|
|
2188
|
+
pasteMessage: "Paste HTTP headers content (multiline supported, e.g. Authorization: Bearer ...):",
|
|
2189
|
+
keyPromptMessage: "Header name (e.g. Authorization):",
|
|
2190
|
+
valuePromptMessage: "Header value",
|
|
2191
|
+
isSecretKey: (k) => SECRET_HEADER_PATTERN.test(k),
|
|
2192
|
+
maskValue: maskSecretHeader,
|
|
2193
|
+
formatText: formatHeadersText,
|
|
2194
|
+
parseText: parseHeadersText
|
|
2195
|
+
});
|
|
1972
2196
|
|
|
1973
2197
|
// src/interactive/wizard-add.ts
|
|
1974
2198
|
var wizardAdd = async (initial = {}) => {
|
|
1975
2199
|
const cwd = initial.cwd ?? process.cwd();
|
|
1976
|
-
logger.info(
|
|
2200
|
+
logger.info(import_picocolors8.default.bold("Welcome to the MCP interactive add wizard"));
|
|
1977
2201
|
let source = initial.source;
|
|
1978
2202
|
if (!source) {
|
|
1979
|
-
const sourceType = await (0,
|
|
2203
|
+
const sourceType = await (0, import_prompts8.select)({
|
|
1980
2204
|
message: "Select MCP server type:",
|
|
1981
2205
|
choices: [
|
|
1982
2206
|
{
|
|
@@ -1994,12 +2218,12 @@ var wizardAdd = async (initial = {}) => {
|
|
|
1994
2218
|
]
|
|
1995
2219
|
});
|
|
1996
2220
|
if (sourceType === "npm") {
|
|
1997
|
-
source = await (0,
|
|
1998
|
-
message: "Enter npm package name (e.g. @modelcontextprotocol/server-postgres
|
|
2221
|
+
source = await (0, import_prompts8.input)({
|
|
2222
|
+
message: "Enter npm package name (e.g. @modelcontextprotocol/server-postgres):",
|
|
1999
2223
|
validate: (val) => val.trim() ? true : "Package name cannot be empty"
|
|
2000
2224
|
});
|
|
2001
2225
|
} else if (sourceType === "remote") {
|
|
2002
|
-
source = await (0,
|
|
2226
|
+
source = await (0, import_prompts8.input)({
|
|
2003
2227
|
message: "Enter remote server URL (e.g. https://mcp.example.com/sse):",
|
|
2004
2228
|
validate: (val) => {
|
|
2005
2229
|
const trimmed = val.trim();
|
|
@@ -2009,7 +2233,7 @@ var wizardAdd = async (initial = {}) => {
|
|
|
2009
2233
|
}
|
|
2010
2234
|
});
|
|
2011
2235
|
} else {
|
|
2012
|
-
source = await (0,
|
|
2236
|
+
source = await (0, import_prompts8.input)({
|
|
2013
2237
|
message: "Enter command and arguments (e.g. python -m my_mcp_server or docker run ...):",
|
|
2014
2238
|
validate: (val) => val.trim() ? true : "Command cannot be empty"
|
|
2015
2239
|
});
|
|
@@ -2019,7 +2243,7 @@ var wizardAdd = async (initial = {}) => {
|
|
|
2019
2243
|
const parsed = parseMcpSource(source);
|
|
2020
2244
|
let serverName = initial.name;
|
|
2021
2245
|
if (!serverName) {
|
|
2022
|
-
serverName = await (0,
|
|
2246
|
+
serverName = await (0, import_prompts8.input)({
|
|
2023
2247
|
message: "MCP server name:",
|
|
2024
2248
|
default: parsed.inferredName,
|
|
2025
2249
|
validate: (val) => val.trim() ? true : "Server name cannot be empty"
|
|
@@ -2031,7 +2255,7 @@ var wizardAdd = async (initial = {}) => {
|
|
|
2031
2255
|
if (parsed.type === "remote") {
|
|
2032
2256
|
if (!transport) {
|
|
2033
2257
|
const isSseUrl = /\/sse\b/i.test(parsed.value);
|
|
2034
|
-
transport = await (0,
|
|
2258
|
+
transport = await (0, import_prompts8.select)({
|
|
2035
2259
|
message: "Select remote transport protocol:",
|
|
2036
2260
|
choices: [
|
|
2037
2261
|
{ name: "HTTP", value: "http" },
|
|
@@ -2041,7 +2265,7 @@ var wizardAdd = async (initial = {}) => {
|
|
|
2041
2265
|
});
|
|
2042
2266
|
}
|
|
2043
2267
|
if (Object.keys(headers).length === 0) {
|
|
2044
|
-
const needHeader = await (0,
|
|
2268
|
+
const needHeader = await (0, import_prompts8.confirm)({
|
|
2045
2269
|
message: "Configure HTTP headers (e.g. Authorization Bearer token)?",
|
|
2046
2270
|
default: false
|
|
2047
2271
|
});
|
|
@@ -2063,28 +2287,28 @@ var wizardAdd = async (initial = {}) => {
|
|
|
2063
2287
|
if (parsed.type !== "remote") {
|
|
2064
2288
|
env = await promptEnvConfig(env);
|
|
2065
2289
|
}
|
|
2066
|
-
console.log("\n" +
|
|
2067
|
-
console.log(` ${
|
|
2068
|
-
console.log(` ${
|
|
2069
|
-
console.log(` ${
|
|
2070
|
-
console.log(` ${
|
|
2071
|
-
console.log(` ${
|
|
2290
|
+
console.log("\n" + import_picocolors8.default.cyan(import_picocolors8.default.bold("Configuration Preview:")));
|
|
2291
|
+
console.log(` ${import_picocolors8.default.bold("Server Name:")} ${import_picocolors8.default.green(serverName)}`);
|
|
2292
|
+
console.log(` ${import_picocolors8.default.bold("Server Type:")} ${import_picocolors8.default.magenta(parsed.type)}`);
|
|
2293
|
+
console.log(` ${import_picocolors8.default.bold("Source/Command:")} ${import_picocolors8.default.dim(source)}`);
|
|
2294
|
+
console.log(` ${import_picocolors8.default.bold("Scope:")} ${isGlobal ? import_picocolors8.default.yellow("Global") : import_picocolors8.default.blue("Project")}`);
|
|
2295
|
+
console.log(` ${import_picocolors8.default.bold("Target Agents:")} ${import_picocolors8.default.cyan(selectedAgents.join(", "))}`);
|
|
2072
2296
|
if (args.length > 0) {
|
|
2073
|
-
console.log(` ${
|
|
2297
|
+
console.log(` ${import_picocolors8.default.bold("Arguments:")} ${import_picocolors8.default.dim(args.join(" "))}`);
|
|
2074
2298
|
}
|
|
2075
2299
|
if (transport) {
|
|
2076
|
-
console.log(` ${
|
|
2300
|
+
console.log(` ${import_picocolors8.default.bold("Transport:")} ${import_picocolors8.default.magenta(transport)}`);
|
|
2077
2301
|
}
|
|
2078
2302
|
const envKeys = Object.keys(env);
|
|
2079
2303
|
if (envKeys.length > 0) {
|
|
2080
|
-
console.log(` ${
|
|
2304
|
+
console.log(` ${import_picocolors8.default.bold("Environment Variables:")} ${import_picocolors8.default.dim(envKeys.join(", "))} (${envKeys.length})`);
|
|
2081
2305
|
}
|
|
2082
2306
|
const headerKeys = Object.keys(headers);
|
|
2083
2307
|
if (headerKeys.length > 0) {
|
|
2084
|
-
console.log(` ${
|
|
2308
|
+
console.log(` ${import_picocolors8.default.bold("Headers:")} ${import_picocolors8.default.dim(headerKeys.join(", "))} (${headerKeys.length})`);
|
|
2085
2309
|
}
|
|
2086
2310
|
console.log();
|
|
2087
|
-
const proceed = await (0,
|
|
2311
|
+
const proceed = await (0, import_prompts8.confirm)({
|
|
2088
2312
|
message: "Confirm installation with this configuration?",
|
|
2089
2313
|
default: true
|
|
2090
2314
|
});
|
|
@@ -2104,26 +2328,26 @@ var wizardAdd = async (initial = {}) => {
|
|
|
2104
2328
|
env
|
|
2105
2329
|
});
|
|
2106
2330
|
logger.info(
|
|
2107
|
-
`Writing ${
|
|
2331
|
+
`Writing ${import_picocolors8.default.bold(result.serverName)} to ${import_picocolors8.default.cyan(String(result.results.length))} agent config files...`
|
|
2108
2332
|
);
|
|
2109
2333
|
let allSuccess = true;
|
|
2110
2334
|
for (const record of result.results) {
|
|
2111
2335
|
if (record.success) {
|
|
2112
|
-
logger.success(`${
|
|
2336
|
+
logger.success(`${import_picocolors8.default.cyan(record.agent)}: Successfully written to ${import_picocolors8.default.dim(record.path)}`);
|
|
2113
2337
|
} else {
|
|
2114
2338
|
allSuccess = false;
|
|
2115
|
-
logger.error(`${
|
|
2339
|
+
logger.error(`${import_picocolors8.default.cyan(record.agent)}: Failed to write - ${record.error}`);
|
|
2116
2340
|
}
|
|
2117
2341
|
}
|
|
2118
2342
|
if (allSuccess) {
|
|
2119
|
-
logger.success(
|
|
2343
|
+
logger.success(import_picocolors8.default.bold(`MCP server "${serverName}" configured successfully!`));
|
|
2120
2344
|
}
|
|
2121
2345
|
return allSuccess;
|
|
2122
2346
|
};
|
|
2123
2347
|
|
|
2124
2348
|
// src/interactive/wizard-manage.ts
|
|
2125
|
-
var
|
|
2126
|
-
var
|
|
2349
|
+
var import_prompts9 = require("@inquirer/prompts");
|
|
2350
|
+
var import_picocolors9 = __toESM(require("picocolors"), 1);
|
|
2127
2351
|
|
|
2128
2352
|
// src/interactive/utils/group-installed-servers.ts
|
|
2129
2353
|
var normalizeServerConfig = parseServerConfig;
|
|
@@ -2151,6 +2375,204 @@ var groupInstalledServersByName = (installed) => {
|
|
|
2151
2375
|
};
|
|
2152
2376
|
|
|
2153
2377
|
// src/interactive/wizard-manage.ts
|
|
2378
|
+
var displayServerDetails = ({
|
|
2379
|
+
serverName,
|
|
2380
|
+
config,
|
|
2381
|
+
agents,
|
|
2382
|
+
isGlobal,
|
|
2383
|
+
titlePrefix = "MCP Server Details"
|
|
2384
|
+
}) => {
|
|
2385
|
+
console.log("\n" + import_picocolors9.default.cyan(import_picocolors9.default.bold(`${titlePrefix}: [${serverName}]`)));
|
|
2386
|
+
if (isGlobal !== void 0) {
|
|
2387
|
+
console.log(` ${import_picocolors9.default.bold("Scope:")} ${isGlobal ? "Global" : "Project"}`);
|
|
2388
|
+
}
|
|
2389
|
+
if (agents && agents.length > 0) {
|
|
2390
|
+
console.log(
|
|
2391
|
+
` ${import_picocolors9.default.bold("Configured Agents:")} ${import_picocolors9.default.green(agents.map((a) => getMcpAgentConfig(a).displayName).join(", "))}`
|
|
2392
|
+
);
|
|
2393
|
+
}
|
|
2394
|
+
const isRemote = Boolean(config.url && config.url.length > 0);
|
|
2395
|
+
if (isRemote) {
|
|
2396
|
+
console.log(` ${import_picocolors9.default.bold("Transport:")} ${import_picocolors9.default.magenta(config.type ?? "http")}`);
|
|
2397
|
+
console.log(` ${import_picocolors9.default.bold("URL:")} ${import_picocolors9.default.dim(config.url ?? "")}`);
|
|
2398
|
+
const headerKeys = Object.keys(config.headers ?? {});
|
|
2399
|
+
if (headerKeys.length > 0) {
|
|
2400
|
+
console.log(` ${import_picocolors9.default.bold("Headers:")} ${import_picocolors9.default.cyan(String(headerKeys.length))}`);
|
|
2401
|
+
for (const [k, v] of Object.entries(config.headers ?? {})) {
|
|
2402
|
+
console.log(` ${import_picocolors9.default.bold(k)}: ${import_picocolors9.default.dim(maskSecretHeader(k, v))}`);
|
|
2403
|
+
}
|
|
2404
|
+
} else {
|
|
2405
|
+
console.log(` ${import_picocolors9.default.bold("Headers:")} ${import_picocolors9.default.dim("(none)")}`);
|
|
2406
|
+
}
|
|
2407
|
+
} else {
|
|
2408
|
+
console.log(` ${import_picocolors9.default.bold("Command:")} ${import_picocolors9.default.magenta(config.command ?? "")}`);
|
|
2409
|
+
const argsStr = config.args && config.args.length > 0 ? config.args.join(" ") : "(none)";
|
|
2410
|
+
console.log(` ${import_picocolors9.default.bold("Arguments:")} ${import_picocolors9.default.dim(argsStr)}`);
|
|
2411
|
+
const envKeys = Object.keys(config.env ?? {});
|
|
2412
|
+
if (envKeys.length > 0) {
|
|
2413
|
+
console.log(` ${import_picocolors9.default.bold("Environment Variables:")} ${import_picocolors9.default.cyan(String(envKeys.length))}`);
|
|
2414
|
+
for (const [k, v] of Object.entries(config.env ?? {})) {
|
|
2415
|
+
console.log(` ${import_picocolors9.default.bold(k)}=${import_picocolors9.default.dim(maskSecretValue(k, v))}`);
|
|
2416
|
+
}
|
|
2417
|
+
} else {
|
|
2418
|
+
console.log(` ${import_picocolors9.default.bold("Environment Variables:")} ${import_picocolors9.default.dim("(none)")}`);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
console.log();
|
|
2422
|
+
};
|
|
2423
|
+
var handleEditServerConfig = async ({
|
|
2424
|
+
targetGroup,
|
|
2425
|
+
isGlobal,
|
|
2426
|
+
cwd
|
|
2427
|
+
}) => {
|
|
2428
|
+
const serverName = targetGroup.serverName;
|
|
2429
|
+
let workingConfig = {
|
|
2430
|
+
...targetGroup.config,
|
|
2431
|
+
args: targetGroup.config.args ? [...targetGroup.config.args] : void 0,
|
|
2432
|
+
env: targetGroup.config.env ? { ...targetGroup.config.env } : void 0,
|
|
2433
|
+
headers: targetGroup.config.headers ? { ...targetGroup.config.headers } : void 0
|
|
2434
|
+
};
|
|
2435
|
+
while (true) {
|
|
2436
|
+
const isRemote = Boolean(workingConfig.url && workingConfig.url.length > 0);
|
|
2437
|
+
displayServerDetails({
|
|
2438
|
+
serverName,
|
|
2439
|
+
config: workingConfig,
|
|
2440
|
+
titlePrefix: "Edit Server Configuration"
|
|
2441
|
+
});
|
|
2442
|
+
const editChoices = isRemote ? [
|
|
2443
|
+
{ name: "Edit HTTP Headers (headers)", value: "headers" },
|
|
2444
|
+
{ name: "Edit Remote URL (url)", value: "url" },
|
|
2445
|
+
{ name: "Edit Transport Protocol (type)", value: "transport" },
|
|
2446
|
+
{ name: "Reset changes to original", value: "reset" },
|
|
2447
|
+
{ name: "Save and apply changes", value: "save" },
|
|
2448
|
+
{ name: "Cancel (discard changes)", value: "cancel" }
|
|
2449
|
+
] : [
|
|
2450
|
+
{ name: "Edit Environment Variables (env)", value: "env" },
|
|
2451
|
+
{ name: "Edit Command Arguments (args)", value: "args" },
|
|
2452
|
+
{ name: "Edit Executable Command (command)", value: "command" },
|
|
2453
|
+
{ name: "Reset changes to original", value: "reset" },
|
|
2454
|
+
{ name: "Save and apply changes", value: "save" },
|
|
2455
|
+
{ name: "Cancel (discard changes)", value: "cancel" }
|
|
2456
|
+
];
|
|
2457
|
+
const editAction = await (0, import_prompts9.select)({
|
|
2458
|
+
message: `What would you like to modify in [${serverName}]?`,
|
|
2459
|
+
choices: editChoices
|
|
2460
|
+
});
|
|
2461
|
+
if (editAction === "cancel") {
|
|
2462
|
+
logger.info("Modification cancelled; changes discarded");
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2465
|
+
if (editAction === "reset") {
|
|
2466
|
+
workingConfig = {
|
|
2467
|
+
...targetGroup.config,
|
|
2468
|
+
args: targetGroup.config.args ? [...targetGroup.config.args] : void 0,
|
|
2469
|
+
env: targetGroup.config.env ? { ...targetGroup.config.env } : void 0,
|
|
2470
|
+
headers: targetGroup.config.headers ? { ...targetGroup.config.headers } : void 0
|
|
2471
|
+
};
|
|
2472
|
+
logger.info("Configuration reset to original");
|
|
2473
|
+
continue;
|
|
2474
|
+
}
|
|
2475
|
+
if (editAction === "env") {
|
|
2476
|
+
workingConfig.env = await promptEditEnvConfig(workingConfig.env ?? {});
|
|
2477
|
+
} else if (editAction === "args") {
|
|
2478
|
+
workingConfig.args = await promptEditArgs(workingConfig.args ?? []);
|
|
2479
|
+
} else if (editAction === "command") {
|
|
2480
|
+
const newCmd = await (0, import_prompts9.input)({
|
|
2481
|
+
message: "Executable command:",
|
|
2482
|
+
default: workingConfig.command,
|
|
2483
|
+
validate: (val) => val.trim() ? true : "Command cannot be empty"
|
|
2484
|
+
});
|
|
2485
|
+
workingConfig.command = newCmd.trim();
|
|
2486
|
+
} else if (editAction === "headers") {
|
|
2487
|
+
workingConfig.headers = await promptEditHeadersConfig(workingConfig.headers ?? {});
|
|
2488
|
+
} else if (editAction === "url") {
|
|
2489
|
+
const newUrl = await (0, import_prompts9.input)({
|
|
2490
|
+
message: "Remote server URL:",
|
|
2491
|
+
default: workingConfig.url,
|
|
2492
|
+
validate: (val) => {
|
|
2493
|
+
const trimmed = val.trim();
|
|
2494
|
+
if (!trimmed) return "URL cannot be empty";
|
|
2495
|
+
if (!/^https?:\/\//i.test(trimmed)) {
|
|
2496
|
+
return "Please enter a valid URL starting with http:// or https://";
|
|
2497
|
+
}
|
|
2498
|
+
return true;
|
|
2499
|
+
}
|
|
2500
|
+
});
|
|
2501
|
+
workingConfig.url = newUrl.trim();
|
|
2502
|
+
} else if (editAction === "transport") {
|
|
2503
|
+
workingConfig.type = await (0, import_prompts9.select)({
|
|
2504
|
+
message: "Select remote transport protocol:",
|
|
2505
|
+
choices: [
|
|
2506
|
+
{ name: "HTTP", value: "http" },
|
|
2507
|
+
{ name: "SSE (Server-Sent Events)", value: "sse" }
|
|
2508
|
+
],
|
|
2509
|
+
default: workingConfig.type === "sse" ? "sse" : "http"
|
|
2510
|
+
});
|
|
2511
|
+
} else if (editAction === "save") {
|
|
2512
|
+
let targetAgents = targetGroup.agents;
|
|
2513
|
+
if (targetGroup.agents.length > 1) {
|
|
2514
|
+
targetAgents = await (0, import_prompts9.checkbox)({
|
|
2515
|
+
message: "Select agents to update configuration (Space to toggle):",
|
|
2516
|
+
choices: targetGroup.agents.map((a) => ({
|
|
2517
|
+
name: `${getMcpAgentConfig(a).displayName} (${a})`,
|
|
2518
|
+
value: a,
|
|
2519
|
+
checked: true
|
|
2520
|
+
})),
|
|
2521
|
+
loop: false,
|
|
2522
|
+
validate: (ans) => ans.length === 0 ? "Please select at least one agent" : true
|
|
2523
|
+
});
|
|
2524
|
+
}
|
|
2525
|
+
const requestedTransport = workingConfig.url ? workingConfig.type ?? "http" : "stdio";
|
|
2526
|
+
const compatibleAgents = [];
|
|
2527
|
+
const incompatibleAgents = [];
|
|
2528
|
+
for (const agent of targetAgents) {
|
|
2529
|
+
const agentConfig = getMcpAgentConfig(agent);
|
|
2530
|
+
if (isMcpTransportSupported(agentConfig, requestedTransport)) {
|
|
2531
|
+
compatibleAgents.push(agent);
|
|
2532
|
+
} else {
|
|
2533
|
+
const reason = agentConfig.unsupportedTransportMessage ?? `Agent does not support ${requestedTransport} transport`;
|
|
2534
|
+
incompatibleAgents.push({ agent, reason });
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
if (incompatibleAgents.length > 0) {
|
|
2538
|
+
for (const item of incompatibleAgents) {
|
|
2539
|
+
logger.warn(`Skipping ${import_picocolors9.default.cyan(item.agent)}: ${item.reason}`);
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
if (compatibleAgents.length === 0) {
|
|
2543
|
+
logger.error(
|
|
2544
|
+
`None of the selected agents support ${requestedTransport} transport. Cannot update.`
|
|
2545
|
+
);
|
|
2546
|
+
continue;
|
|
2547
|
+
}
|
|
2548
|
+
const agentNames = compatibleAgents.map((a) => getMcpAgentConfig(a).displayName).join(", ");
|
|
2549
|
+
const confirmed = await (0, import_prompts9.confirm)({
|
|
2550
|
+
message: `Confirm updating configuration for [${serverName}] across: ${agentNames}?`,
|
|
2551
|
+
default: true
|
|
2552
|
+
});
|
|
2553
|
+
if (!confirmed) {
|
|
2554
|
+
logger.warn("Update cancelled");
|
|
2555
|
+
continue;
|
|
2556
|
+
}
|
|
2557
|
+
for (const targetAgent of compatibleAgents) {
|
|
2558
|
+
const res = installMcpServerForAgent(serverName, workingConfig, targetAgent, {
|
|
2559
|
+
global: isGlobal,
|
|
2560
|
+
cwd
|
|
2561
|
+
});
|
|
2562
|
+
if (res.success) {
|
|
2563
|
+
logger.success(
|
|
2564
|
+
`${import_picocolors9.default.cyan(targetAgent)}: Successfully updated configuration in ${import_picocolors9.default.dim(res.path)}`
|
|
2565
|
+
);
|
|
2566
|
+
} else {
|
|
2567
|
+
logger.error(`${import_picocolors9.default.cyan(targetAgent)}: Update failed - ${res.error}`);
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
targetGroup.config = workingConfig;
|
|
2571
|
+
logger.success(`Configuration for [${serverName}] updated successfully!`);
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
};
|
|
2154
2576
|
var wizardManage = async (options = {}) => {
|
|
2155
2577
|
const cwd = options.cwd ?? process.cwd();
|
|
2156
2578
|
const isGlobal = await promptScope({
|
|
@@ -2164,51 +2586,48 @@ var wizardManage = async (options = {}) => {
|
|
|
2164
2586
|
return;
|
|
2165
2587
|
}
|
|
2166
2588
|
const grouped = groupInstalledServersByName(installed);
|
|
2589
|
+
let pendingServerName = options.serverName;
|
|
2167
2590
|
while (true) {
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
choices
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2591
|
+
let chosenServerName;
|
|
2592
|
+
if (pendingServerName && grouped.has(pendingServerName)) {
|
|
2593
|
+
chosenServerName = pendingServerName;
|
|
2594
|
+
pendingServerName = void 0;
|
|
2595
|
+
} else {
|
|
2596
|
+
pendingServerName = void 0;
|
|
2597
|
+
const choices = Array.from(grouped.values()).map((g) => {
|
|
2598
|
+
const agentNames = g.agents.map((a) => getMcpAgentConfig(a).displayName).join(", ");
|
|
2599
|
+
return {
|
|
2600
|
+
name: `${import_picocolors9.default.bold(g.serverName)} ${import_picocolors9.default.dim(`(configured in: ${agentNames})`)}`,
|
|
2601
|
+
value: g.serverName
|
|
2602
|
+
};
|
|
2603
|
+
});
|
|
2604
|
+
choices.push({
|
|
2605
|
+
name: `Back`,
|
|
2606
|
+
value: "__back__"
|
|
2607
|
+
});
|
|
2608
|
+
chosenServerName = await (0, import_prompts9.select)({
|
|
2609
|
+
message: "Select MCP server to manage or sync:",
|
|
2610
|
+
choices
|
|
2611
|
+
});
|
|
2612
|
+
if (chosenServerName === "__back__") {
|
|
2613
|
+
return;
|
|
2614
|
+
}
|
|
2185
2615
|
}
|
|
2186
2616
|
const targetGroup = grouped.get(chosenServerName);
|
|
2187
2617
|
if (!targetGroup) continue;
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
console.log(` ${import_picocolors8.default.bold("URL:")} ${import_picocolors8.default.dim(cfg.url)} (${cfg.type})`);
|
|
2196
|
-
if (cfg.headers && Object.keys(cfg.headers).length > 0) {
|
|
2197
|
-
console.log(` ${import_picocolors8.default.bold("Headers:")} ${Object.keys(cfg.headers).join(", ")}`);
|
|
2198
|
-
}
|
|
2199
|
-
} else if (isStdioServerConfig(cfg)) {
|
|
2200
|
-
console.log(` ${import_picocolors8.default.bold("Command:")} ${import_picocolors8.default.magenta(cfg.command)}`);
|
|
2201
|
-
if (cfg.args && cfg.args.length > 0) {
|
|
2202
|
-
console.log(` ${import_picocolors8.default.bold("Arguments:")} ${import_picocolors8.default.dim(cfg.args.join(" "))}`);
|
|
2203
|
-
}
|
|
2204
|
-
if (cfg.env && Object.keys(cfg.env).length > 0) {
|
|
2205
|
-
console.log(` ${import_picocolors8.default.bold("Environment Variables:")} ${import_picocolors8.default.dim(Object.keys(cfg.env).join(", "))}`);
|
|
2206
|
-
}
|
|
2207
|
-
}
|
|
2208
|
-
console.log();
|
|
2209
|
-
const action = await (0, import_prompts8.select)({
|
|
2618
|
+
displayServerDetails({
|
|
2619
|
+
serverName: chosenServerName,
|
|
2620
|
+
config: targetGroup.config,
|
|
2621
|
+
agents: targetGroup.agents,
|
|
2622
|
+
isGlobal
|
|
2623
|
+
});
|
|
2624
|
+
const action = await (0, import_prompts9.select)({
|
|
2210
2625
|
message: `What would you like to do with [${chosenServerName}]?`,
|
|
2211
2626
|
choices: [
|
|
2627
|
+
{
|
|
2628
|
+
name: "Edit server configuration",
|
|
2629
|
+
value: "edit"
|
|
2630
|
+
},
|
|
2212
2631
|
{
|
|
2213
2632
|
name: "Sync / clone to other agents",
|
|
2214
2633
|
value: "sync"
|
|
@@ -2220,23 +2639,34 @@ var wizardManage = async (options = {}) => {
|
|
|
2220
2639
|
]
|
|
2221
2640
|
});
|
|
2222
2641
|
if (action === "back") continue;
|
|
2642
|
+
if (action === "edit") {
|
|
2643
|
+
await handleEditServerConfig({
|
|
2644
|
+
targetGroup,
|
|
2645
|
+
isGlobal,
|
|
2646
|
+
cwd
|
|
2647
|
+
});
|
|
2648
|
+
continue;
|
|
2649
|
+
}
|
|
2223
2650
|
if (action === "sync") {
|
|
2224
2651
|
const allAllowedAgents = isGlobal ? getMcpAgentTypes() : getMcpAgentsSupportingProjectScope();
|
|
2225
2652
|
const candidateAgents = allAllowedAgents.filter((a) => !targetGroup.agents.includes(a));
|
|
2226
2653
|
if (candidateAgents.length === 0) {
|
|
2227
|
-
logger.info(
|
|
2654
|
+
logger.info(
|
|
2655
|
+
"All supported agents in this scope already have this MCP server configured; no sync needed"
|
|
2656
|
+
);
|
|
2228
2657
|
continue;
|
|
2229
2658
|
}
|
|
2230
|
-
const selectedToSync = await (0,
|
|
2659
|
+
const selectedToSync = await (0, import_prompts9.checkbox)({
|
|
2231
2660
|
message: "Select target agents to sync to (Space to select):",
|
|
2232
2661
|
choices: candidateAgents.map((a) => ({
|
|
2233
2662
|
name: `${getMcpAgentConfig(a).displayName} (${a})`,
|
|
2234
2663
|
value: a,
|
|
2235
2664
|
checked: false
|
|
2236
2665
|
})),
|
|
2666
|
+
loop: false,
|
|
2237
2667
|
validate: (ans) => ans.length === 0 ? "Please select at least one agent" : true
|
|
2238
2668
|
});
|
|
2239
|
-
const confirmed = await (0,
|
|
2669
|
+
const confirmed = await (0, import_prompts9.confirm)({
|
|
2240
2670
|
message: `Confirm syncing configuration of [${chosenServerName}] to: ${selectedToSync.join(", ")}?`,
|
|
2241
2671
|
default: true
|
|
2242
2672
|
});
|
|
@@ -2250,10 +2680,10 @@ var wizardManage = async (options = {}) => {
|
|
|
2250
2680
|
cwd
|
|
2251
2681
|
});
|
|
2252
2682
|
if (res.success) {
|
|
2253
|
-
logger.success(`${
|
|
2683
|
+
logger.success(`${import_picocolors9.default.cyan(targetAgent)}: Successfully synced to ${import_picocolors9.default.dim(res.path)}`);
|
|
2254
2684
|
targetGroup.agents.push(targetAgent);
|
|
2255
2685
|
} else {
|
|
2256
|
-
logger.error(`${
|
|
2686
|
+
logger.error(`${import_picocolors9.default.cyan(targetAgent)}: Sync failed - ${res.error}`);
|
|
2257
2687
|
}
|
|
2258
2688
|
}
|
|
2259
2689
|
}
|
|
@@ -2261,8 +2691,8 @@ var wizardManage = async (options = {}) => {
|
|
|
2261
2691
|
};
|
|
2262
2692
|
|
|
2263
2693
|
// src/interactive/wizard-remove.ts
|
|
2264
|
-
var
|
|
2265
|
-
var
|
|
2694
|
+
var import_prompts10 = require("@inquirer/prompts");
|
|
2695
|
+
var import_picocolors10 = __toESM(require("picocolors"), 1);
|
|
2266
2696
|
var wizardRemove = async (options = {}) => {
|
|
2267
2697
|
const cwd = options.cwd ?? process.cwd();
|
|
2268
2698
|
const isGlobal = await promptScope({
|
|
@@ -2279,10 +2709,10 @@ var wizardRemove = async (options = {}) => {
|
|
|
2279
2709
|
let serverName = options.name;
|
|
2280
2710
|
if (!serverName) {
|
|
2281
2711
|
const choices = Array.from(serverMap.values()).map((g) => ({
|
|
2282
|
-
name: `${
|
|
2712
|
+
name: `${import_picocolors10.default.bold(g.serverName)} ${import_picocolors10.default.dim(`(installed in: ${g.agents.map((a) => getMcpAgentConfig(a).displayName).join(", ")})`)}`,
|
|
2283
2713
|
value: g.serverName
|
|
2284
2714
|
}));
|
|
2285
|
-
serverName = await (0,
|
|
2715
|
+
serverName = await (0, import_prompts10.select)({
|
|
2286
2716
|
message: "Select MCP server to remove:",
|
|
2287
2717
|
choices
|
|
2288
2718
|
});
|
|
@@ -2294,13 +2724,14 @@ var wizardRemove = async (options = {}) => {
|
|
|
2294
2724
|
}
|
|
2295
2725
|
let targetAgents = options.agents;
|
|
2296
2726
|
if (!targetAgents || targetAgents.length === 0) {
|
|
2297
|
-
targetAgents = await (0,
|
|
2727
|
+
targetAgents = await (0, import_prompts10.checkbox)({
|
|
2298
2728
|
message: `Select agents to remove [${serverName}] from:`,
|
|
2299
2729
|
choices: installedAgents.map((agent) => ({
|
|
2300
2730
|
name: `${getMcpAgentConfig(agent)?.displayName ?? agent} (${agent})`,
|
|
2301
2731
|
value: agent,
|
|
2302
2732
|
checked: true
|
|
2303
2733
|
})),
|
|
2734
|
+
loop: false,
|
|
2304
2735
|
validate: (ans) => ans.length === 0 ? "Please select at least one agent" : true
|
|
2305
2736
|
});
|
|
2306
2737
|
} else {
|
|
@@ -2311,7 +2742,7 @@ var wizardRemove = async (options = {}) => {
|
|
|
2311
2742
|
}
|
|
2312
2743
|
targetAgents = validAgents;
|
|
2313
2744
|
}
|
|
2314
|
-
const confirmed = await (0,
|
|
2745
|
+
const confirmed = await (0, import_prompts10.confirm)({
|
|
2315
2746
|
message: `Confirm removing MCP server [${serverName}] from ${targetAgents.join(", ")}?`,
|
|
2316
2747
|
default: true
|
|
2317
2748
|
});
|
|
@@ -2328,10 +2759,10 @@ var wizardRemove = async (options = {}) => {
|
|
|
2328
2759
|
let removedCount = 0;
|
|
2329
2760
|
for (const res of results) {
|
|
2330
2761
|
if (res.removed) {
|
|
2331
|
-
logger.success(`${
|
|
2762
|
+
logger.success(`${import_picocolors10.default.cyan(res.agent)}: Successfully removed from ${import_picocolors10.default.dim(res.path)}`);
|
|
2332
2763
|
removedCount++;
|
|
2333
2764
|
} else if (res.error) {
|
|
2334
|
-
logger.error(`${
|
|
2765
|
+
logger.error(`${import_picocolors10.default.cyan(res.agent)}: Failed to remove - ${res.error}`);
|
|
2335
2766
|
}
|
|
2336
2767
|
}
|
|
2337
2768
|
if (removedCount > 0) {
|
|
@@ -2345,12 +2776,12 @@ var wizardRemove = async (options = {}) => {
|
|
|
2345
2776
|
// src/interactive/main-menu.ts
|
|
2346
2777
|
var mainMenu = async () => {
|
|
2347
2778
|
console.log();
|
|
2348
|
-
console.log(
|
|
2349
|
-
console.log(
|
|
2779
|
+
console.log(import_picocolors11.default.bold(import_picocolors11.default.cyan("mcps - Cross-Platform MCP Manager for AI Coding Agents")));
|
|
2780
|
+
console.log(import_picocolors11.default.dim("Cross-platform MCP server configuration & synchronization tool"));
|
|
2350
2781
|
console.log();
|
|
2351
2782
|
while (true) {
|
|
2352
2783
|
try {
|
|
2353
|
-
const action = await (0,
|
|
2784
|
+
const action = await (0, import_prompts11.select)({
|
|
2354
2785
|
message: "Select an action:",
|
|
2355
2786
|
choices: [
|
|
2356
2787
|
{
|
|
@@ -2372,7 +2803,7 @@ var mainMenu = async () => {
|
|
|
2372
2803
|
]
|
|
2373
2804
|
});
|
|
2374
2805
|
if (action === "exit") {
|
|
2375
|
-
console.log(
|
|
2806
|
+
console.log(import_picocolors11.default.dim("Goodbye!"));
|
|
2376
2807
|
break;
|
|
2377
2808
|
}
|
|
2378
2809
|
if (action === "add") {
|
|
@@ -2385,13 +2816,167 @@ var mainMenu = async () => {
|
|
|
2385
2816
|
console.log();
|
|
2386
2817
|
} catch (error) {
|
|
2387
2818
|
if (error?.name === "ExitPromptError") {
|
|
2388
|
-
console.log("\n" +
|
|
2819
|
+
console.log("\n" + import_picocolors11.default.dim("Exited."));
|
|
2389
2820
|
break;
|
|
2390
2821
|
}
|
|
2391
2822
|
throw error;
|
|
2392
2823
|
}
|
|
2393
2824
|
}
|
|
2394
2825
|
};
|
|
2826
|
+
|
|
2827
|
+
// src/cli/manage.ts
|
|
2828
|
+
var import_commander = require("commander");
|
|
2829
|
+
var import_picocolors12 = __toESM(require("picocolors"), 1);
|
|
2830
|
+
|
|
2831
|
+
// src/utils/parse-key-value-list.ts
|
|
2832
|
+
var parseKeyValueList = (entries, separator) => {
|
|
2833
|
+
if (!entries || entries.length === 0) return {};
|
|
2834
|
+
const result = {};
|
|
2835
|
+
for (const entry of entries) {
|
|
2836
|
+
const splitIndex = entry.indexOf(separator);
|
|
2837
|
+
if (splitIndex === -1) {
|
|
2838
|
+
throw new Error(`Invalid entry "${entry}": expected "${separator}" separator`);
|
|
2839
|
+
}
|
|
2840
|
+
const key = entry.slice(0, splitIndex).trim();
|
|
2841
|
+
const value = entry.slice(splitIndex + separator.length).trim();
|
|
2842
|
+
if (!key) throw new Error(`Invalid entry "${entry}": empty key`);
|
|
2843
|
+
result[key] = value;
|
|
2844
|
+
}
|
|
2845
|
+
return result;
|
|
2846
|
+
};
|
|
2847
|
+
|
|
2848
|
+
// src/cli/manage.ts
|
|
2849
|
+
var resolveTransport = (input7) => {
|
|
2850
|
+
if (!input7) return void 0;
|
|
2851
|
+
if (input7 === "http" || input7 === "sse") return input7;
|
|
2852
|
+
throw new Error(`Unsupported transport "${input7}" (expected: http, sse)`);
|
|
2853
|
+
};
|
|
2854
|
+
var mcpManageCommand = new import_commander.Command("manage").description("Inspect, modify, and sync installed MCP servers across coding agents").argument("[server-name]", "Optional server name to inspect or manage").option("-a, --agent <agents...>", "Target specific agents for update").option("-g, --global", "Manage global scope servers instead of project").option("-t, --transport <type>", "Transport type for remote servers (http or sse)").option("--header <header...>", "HTTP header (Header: Value), repeatable").option("--env <env...>", "Env var for stdio servers (KEY=VALUE), repeatable").option("--args <args...>", "CLI arguments for stdio/package servers").option("--command <command>", "Executable command for stdio servers").option("--url <url>", "Remote endpoint URL").option("-y, --yes", "Skip interactive prompts").action(async (serverName, options) => {
|
|
2855
|
+
try {
|
|
2856
|
+
const cwd = process.cwd();
|
|
2857
|
+
const isGlobal = Boolean(options.global);
|
|
2858
|
+
const hasModifications = options.command !== void 0 || options.args !== void 0 || options.env !== void 0 || options.header !== void 0 || options.url !== void 0 || options.transport !== void 0;
|
|
2859
|
+
const isInteractive = Boolean(process.stdin.isTTY && !options.yes);
|
|
2860
|
+
if (hasModifications) {
|
|
2861
|
+
if (!serverName) {
|
|
2862
|
+
logger.error('Missing required argument: "server-name" when passing modification flags.');
|
|
2863
|
+
process.exitCode = 1;
|
|
2864
|
+
return;
|
|
2865
|
+
}
|
|
2866
|
+
const installed = listInstalledMcpServers({ global: isGlobal, cwd });
|
|
2867
|
+
const grouped = groupInstalledServersByName(installed);
|
|
2868
|
+
const targetGroup = grouped.get(serverName);
|
|
2869
|
+
if (!targetGroup) {
|
|
2870
|
+
logger.error(
|
|
2871
|
+
`MCP server "${serverName}" is not configured in ${isGlobal ? "global" : "project"} scope.`
|
|
2872
|
+
);
|
|
2873
|
+
process.exitCode = 1;
|
|
2874
|
+
return;
|
|
2875
|
+
}
|
|
2876
|
+
const updatedConfig = {
|
|
2877
|
+
...targetGroup.config,
|
|
2878
|
+
args: targetGroup.config.args ? [...targetGroup.config.args] : void 0,
|
|
2879
|
+
env: targetGroup.config.env ? { ...targetGroup.config.env } : void 0,
|
|
2880
|
+
headers: targetGroup.config.headers ? { ...targetGroup.config.headers } : void 0
|
|
2881
|
+
};
|
|
2882
|
+
if (options.command !== void 0) {
|
|
2883
|
+
updatedConfig.command = options.command;
|
|
2884
|
+
}
|
|
2885
|
+
if (options.args !== void 0) {
|
|
2886
|
+
updatedConfig.args = options.args;
|
|
2887
|
+
}
|
|
2888
|
+
if (options.url !== void 0) {
|
|
2889
|
+
updatedConfig.url = options.url;
|
|
2890
|
+
}
|
|
2891
|
+
if (options.transport !== void 0) {
|
|
2892
|
+
updatedConfig.type = resolveTransport(options.transport);
|
|
2893
|
+
}
|
|
2894
|
+
if (options.env !== void 0) {
|
|
2895
|
+
const parsedEnv = parseKeyValueList(options.env, "=");
|
|
2896
|
+
updatedConfig.env = { ...updatedConfig.env ?? {}, ...parsedEnv };
|
|
2897
|
+
}
|
|
2898
|
+
if (options.header !== void 0) {
|
|
2899
|
+
const parsedHeaders = parseKeyValueList(options.header, ":");
|
|
2900
|
+
updatedConfig.headers = { ...updatedConfig.headers ?? {}, ...parsedHeaders };
|
|
2901
|
+
}
|
|
2902
|
+
const targetAgents = options.agent ? parseMcpAgentList(options.agent) ?? targetGroup.agents : targetGroup.agents;
|
|
2903
|
+
const requestedTransport = updatedConfig.url ? updatedConfig.type ?? "http" : "stdio";
|
|
2904
|
+
const compatibleAgents = [];
|
|
2905
|
+
for (const agent of targetAgents) {
|
|
2906
|
+
const agentConfig = getMcpAgentConfig(agent);
|
|
2907
|
+
if (isMcpTransportSupported(agentConfig, requestedTransport)) {
|
|
2908
|
+
compatibleAgents.push(agent);
|
|
2909
|
+
} else {
|
|
2910
|
+
const reason = agentConfig.unsupportedTransportMessage ?? `Agent does not support ${requestedTransport} transport`;
|
|
2911
|
+
logger.warn(`Skipping ${import_picocolors12.default.cyan(agent)}: ${reason}`);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
if (compatibleAgents.length === 0) {
|
|
2915
|
+
logger.error(
|
|
2916
|
+
`None of the target agents support ${requestedTransport} transport. Update aborted.`
|
|
2917
|
+
);
|
|
2918
|
+
process.exitCode = 1;
|
|
2919
|
+
return;
|
|
2920
|
+
}
|
|
2921
|
+
logger.info(
|
|
2922
|
+
`Updating ${import_picocolors12.default.bold(serverName)} across ${import_picocolors12.default.cyan(String(compatibleAgents.length))} agent(s)...`
|
|
2923
|
+
);
|
|
2924
|
+
let allSuccess = true;
|
|
2925
|
+
for (const agent of compatibleAgents) {
|
|
2926
|
+
const res = installMcpServerForAgent(serverName, updatedConfig, agent, {
|
|
2927
|
+
global: isGlobal,
|
|
2928
|
+
cwd
|
|
2929
|
+
});
|
|
2930
|
+
if (res.success) {
|
|
2931
|
+
logger.success(`${import_picocolors12.default.cyan(agent)}: Successfully updated in ${import_picocolors12.default.dim(res.path)}`);
|
|
2932
|
+
} else {
|
|
2933
|
+
allSuccess = false;
|
|
2934
|
+
logger.error(`${import_picocolors12.default.cyan(agent)}: Update failed - ${res.error}`);
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
if (!allSuccess) {
|
|
2938
|
+
process.exitCode = 1;
|
|
2939
|
+
}
|
|
2940
|
+
return;
|
|
2941
|
+
}
|
|
2942
|
+
if (!isInteractive) {
|
|
2943
|
+
if (!serverName) {
|
|
2944
|
+
logger.error(
|
|
2945
|
+
'Missing required argument: "server-name" for non-interactive manage command. Specify a server name or use interactive terminal.'
|
|
2946
|
+
);
|
|
2947
|
+
process.exitCode = 1;
|
|
2948
|
+
return;
|
|
2949
|
+
}
|
|
2950
|
+
const installed = listInstalledMcpServers({ global: isGlobal, cwd });
|
|
2951
|
+
const grouped = groupInstalledServersByName(installed);
|
|
2952
|
+
const targetGroup = grouped.get(serverName);
|
|
2953
|
+
if (!targetGroup) {
|
|
2954
|
+
logger.error(
|
|
2955
|
+
`MCP server "${serverName}" is not configured in ${isGlobal ? "global" : "project"} scope.`
|
|
2956
|
+
);
|
|
2957
|
+
process.exitCode = 1;
|
|
2958
|
+
return;
|
|
2959
|
+
}
|
|
2960
|
+
displayServerDetails({
|
|
2961
|
+
serverName,
|
|
2962
|
+
config: targetGroup.config,
|
|
2963
|
+
agents: targetGroup.agents,
|
|
2964
|
+
isGlobal
|
|
2965
|
+
});
|
|
2966
|
+
return;
|
|
2967
|
+
}
|
|
2968
|
+
await wizardManage({
|
|
2969
|
+
global: options.global,
|
|
2970
|
+
serverName
|
|
2971
|
+
});
|
|
2972
|
+
} catch (error) {
|
|
2973
|
+
if (error && typeof error === "object" && "name" in error && error.name === "ExitPromptError") {
|
|
2974
|
+
process.exit(0);
|
|
2975
|
+
}
|
|
2976
|
+
logger.error(toErrorMessage(error));
|
|
2977
|
+
process.exitCode = 1;
|
|
2978
|
+
}
|
|
2979
|
+
});
|
|
2395
2980
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2396
2981
|
0 && (module.exports = {
|
|
2397
2982
|
AgentConfigStore,
|
|
@@ -2404,7 +2989,11 @@ var mainMenu = async () => {
|
|
|
2404
2989
|
createAgentTransform,
|
|
2405
2990
|
detectGloballyInstalledMcpAgents,
|
|
2406
2991
|
detectProjectInstalledMcpAgents,
|
|
2992
|
+
displayServerDetails,
|
|
2407
2993
|
extractPackageName,
|
|
2994
|
+
formatArgsString,
|
|
2995
|
+
formatEnvText,
|
|
2996
|
+
formatHeadersText,
|
|
2408
2997
|
getMcpAgentConfig,
|
|
2409
2998
|
getMcpAgentTypes,
|
|
2410
2999
|
getMcpAgentsSupportingProjectScope,
|
|
@@ -2422,8 +3011,11 @@ var mainMenu = async () => {
|
|
|
2422
3011
|
listInstalledMcpServers,
|
|
2423
3012
|
listServersInConfigFile,
|
|
2424
3013
|
mainMenu,
|
|
3014
|
+
maskSecretHeader,
|
|
3015
|
+
maskSecretValue,
|
|
2425
3016
|
mcpAgentAliases,
|
|
2426
3017
|
mcpAgents,
|
|
3018
|
+
mcpManageCommand,
|
|
2427
3019
|
normalizeServerConfig,
|
|
2428
3020
|
parseArgsString,
|
|
2429
3021
|
parseEnvText,
|
|
@@ -2432,6 +3024,10 @@ var mainMenu = async () => {
|
|
|
2432
3024
|
parseServerConfig,
|
|
2433
3025
|
parseSource,
|
|
2434
3026
|
promptArgsConfig,
|
|
3027
|
+
promptEditArgs,
|
|
3028
|
+
promptEditEnvConfig,
|
|
3029
|
+
promptEditHeadersConfig,
|
|
3030
|
+
promptEditKeyValueConfig,
|
|
2435
3031
|
promptEnvConfig,
|
|
2436
3032
|
promptHeadersConfig,
|
|
2437
3033
|
promptScope,
|
|
@@ -2446,6 +3042,8 @@ var mainMenu = async () => {
|
|
|
2446
3042
|
resolveTargetAgents,
|
|
2447
3043
|
transformServerConfig,
|
|
2448
3044
|
transformServerConfigForAgent,
|
|
3045
|
+
updateMcpServerForAgent,
|
|
3046
|
+
updateMcpServerForAgents,
|
|
2449
3047
|
wizardAdd,
|
|
2450
3048
|
wizardManage,
|
|
2451
3049
|
wizardRemove,
|