@kwonye/mcpx 0.1.93 → 0.1.95
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/adapters/claude-desktop.d.ts.map +1 -1
- package/dist/adapters/claude.d.ts +2 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/cline.d.ts +3 -1
- package/dist/adapters/cline.d.ts.map +1 -1
- package/dist/adapters/codex.d.ts +2 -1
- package/dist/adapters/codex.d.ts.map +1 -1
- package/dist/adapters/cursor.d.ts +2 -1
- package/dist/adapters/cursor.d.ts.map +1 -1
- package/dist/adapters/hermes.d.ts +11 -0
- package/dist/adapters/hermes.d.ts.map +1 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/kiro.d.ts.map +1 -1
- package/dist/adapters/openclaw.d.ts +11 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/opencode.d.ts +2 -1
- package/dist/adapters/opencode.d.ts.map +1 -1
- package/dist/adapters/qwen.d.ts.map +1 -1
- package/dist/adapters/utils/index.d.ts +18 -4
- package/dist/adapters/utils/index.d.ts.map +1 -1
- package/dist/adapters/vscode.d.ts +2 -1
- package/dist/adapters/vscode.d.ts.map +1 -1
- package/dist/{cli-y7ba5qvr.js → cli-28fsxhe3.js} +430 -156
- package/dist/{cli-qvkpwy9w.js → cli-njtbb11m.js} +138 -43
- package/dist/{cli-8vxva0cb.js → cli-tk8bggg5.js} +81 -8
- package/dist/{cli-np0wwh6m.js → cli-v27bt25d.js} +157 -11
- package/dist/{cli-kwyp9ywh.js → cli-wxw1t3rr.js} +941 -303
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +388 -77
- package/dist/compat/hermes.d.ts +7 -0
- package/dist/compat/hermes.d.ts.map +1 -0
- package/dist/compat/index.d.ts.map +1 -1
- package/dist/compat/openclaw.d.ts +7 -0
- package/dist/compat/openclaw.d.ts.map +1 -0
- package/dist/{config-2s5nsm2g.js → config-5p08cb0c.js} +6 -2
- package/dist/core/add-command.d.ts.map +1 -1
- package/dist/core/config-repair.d.ts.map +1 -1
- package/dist/core/config-store.d.ts +33 -0
- package/dist/core/config-store.d.ts.map +1 -0
- package/dist/core/config.d.ts +13 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/daemon.d.ts +5 -1
- package/dist/core/daemon.d.ts.map +1 -1
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +30 -6
- package/dist/core/managed-index-lock.d.ts +2 -0
- package/dist/core/managed-index-lock.d.ts.map +1 -0
- package/dist/core/oauth.d.ts.map +1 -1
- package/dist/core/plugin-host.d.ts +2 -0
- package/dist/core/plugin-host.d.ts.map +1 -0
- package/dist/core/plugin-manager.d.ts +19 -6
- package/dist/core/plugin-manager.d.ts.map +1 -1
- package/dist/core/plugin-parse.d.ts.map +1 -1
- package/dist/core/plugin-projections.d.ts +6 -2
- package/dist/core/plugin-projections.d.ts.map +1 -1
- package/dist/core/registry.d.ts +4 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/secrets.d.ts.map +1 -1
- package/dist/core/server-auth.d.ts.map +1 -1
- package/dist/core/skill-projections.d.ts +3 -0
- package/dist/core/skill-projections.d.ts.map +1 -0
- package/dist/core/status.d.ts +1 -0
- package/dist/core/status.d.ts.map +1 -1
- package/dist/core/sync.d.ts +19 -2
- package/dist/core/sync.d.ts.map +1 -1
- package/dist/core/update-manager.d.ts.map +1 -1
- package/dist/gateway/server.d.ts +4 -1
- package/dist/gateway/server.d.ts.map +1 -1
- package/dist/plugin-host-954a7tf7.js +129 -0
- package/dist/{plugin-manager-1sc4b6am.js → plugin-manager-m8ar2271.js} +12 -4
- package/dist/{registry-mztfy0cz.js → registry-n12thgf2.js} +1 -1
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/cli-m2645syd.js +0 -2199
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
APP_VERSION,
|
|
4
3
|
STATUS_CLIENTS,
|
|
5
4
|
applyAuthReference,
|
|
6
5
|
buildStatusReport,
|
|
@@ -14,6 +13,8 @@ import {
|
|
|
14
13
|
listAuthBindings,
|
|
15
14
|
mapRegistryToSpec,
|
|
16
15
|
maybePrefixBearer,
|
|
16
|
+
mutateActiveConfig,
|
|
17
|
+
mutateConfig,
|
|
17
18
|
performRollback,
|
|
18
19
|
performUpdate,
|
|
19
20
|
probeHttpAuthRequirement,
|
|
@@ -30,25 +31,28 @@ import {
|
|
|
30
31
|
startDaemon,
|
|
31
32
|
stopDaemon,
|
|
32
33
|
toSecretRef
|
|
33
|
-
} from "./cli-
|
|
34
|
+
} from "./cli-28fsxhe3.js";
|
|
34
35
|
import {
|
|
36
|
+
APP_VERSION,
|
|
35
37
|
deleteSkill,
|
|
36
38
|
getAdapters,
|
|
37
39
|
getGatewayUrl,
|
|
38
40
|
getSkill,
|
|
39
41
|
listSkills,
|
|
40
42
|
loadManagedIndex,
|
|
43
|
+
persistSyncState,
|
|
41
44
|
saveSkill,
|
|
42
45
|
syncAllClients
|
|
43
|
-
} from "./cli-
|
|
46
|
+
} from "./cli-wxw1t3rr.js";
|
|
44
47
|
import {
|
|
48
|
+
ConfigLoadError,
|
|
45
49
|
loadConfig,
|
|
46
50
|
loadMergedConfig,
|
|
47
51
|
loadProjectConfig,
|
|
48
52
|
resolveActiveConfig,
|
|
49
53
|
saveConfig,
|
|
50
54
|
saveProjectConfig
|
|
51
|
-
} from "./cli-
|
|
55
|
+
} from "./cli-v27bt25d.js";
|
|
52
56
|
import {
|
|
53
57
|
SecretsManager,
|
|
54
58
|
addServer,
|
|
@@ -58,7 +62,7 @@ import {
|
|
|
58
62
|
removeServer,
|
|
59
63
|
rotateGatewayToken,
|
|
60
64
|
setServerEnabled
|
|
61
|
-
} from "./cli-
|
|
65
|
+
} from "./cli-tk8bggg5.js";
|
|
62
66
|
import {
|
|
63
67
|
getConfigPath,
|
|
64
68
|
getManagedIndexPath,
|
|
@@ -729,6 +733,203 @@ function parseQwenArgs(argv) {
|
|
|
729
733
|
}
|
|
730
734
|
}
|
|
731
735
|
|
|
736
|
+
// src/compat/openclaw.ts
|
|
737
|
+
function parseOpenClawArgs(args) {
|
|
738
|
+
if (args.length === 0) {
|
|
739
|
+
return { error: "Usage: mcpx openclaw mcp add <name> --url <url> | --command <cmd>" };
|
|
740
|
+
}
|
|
741
|
+
let name;
|
|
742
|
+
let url;
|
|
743
|
+
let command;
|
|
744
|
+
let transport;
|
|
745
|
+
const headers = [];
|
|
746
|
+
const envVars = [];
|
|
747
|
+
const commandArgs = [];
|
|
748
|
+
let cwd;
|
|
749
|
+
let hasAuthOAuth = false;
|
|
750
|
+
let hasInclude = false;
|
|
751
|
+
let hasExclude = false;
|
|
752
|
+
let hasTimeout = false;
|
|
753
|
+
let hasConnectTimeout = false;
|
|
754
|
+
for (let i = 0;i < args.length; i++) {
|
|
755
|
+
const arg = args[i];
|
|
756
|
+
if (!name && !arg.startsWith("--")) {
|
|
757
|
+
name = arg;
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
if (arg === "--url") {
|
|
761
|
+
url = args[++i];
|
|
762
|
+
} else if (arg === "--command") {
|
|
763
|
+
command = args[++i];
|
|
764
|
+
} else if (arg === "--transport") {
|
|
765
|
+
transport = args[++i];
|
|
766
|
+
} else if (arg === "--header") {
|
|
767
|
+
const val = args[++i];
|
|
768
|
+
if (val && !val.startsWith("--")) {
|
|
769
|
+
headers.push(val);
|
|
770
|
+
}
|
|
771
|
+
} else if (arg === "--arg") {
|
|
772
|
+
const val = args[++i];
|
|
773
|
+
if (val && !val.startsWith("--")) {
|
|
774
|
+
commandArgs.push(val);
|
|
775
|
+
}
|
|
776
|
+
} else if (arg === "--env") {
|
|
777
|
+
const val = args[++i];
|
|
778
|
+
if (val && !val.startsWith("--")) {
|
|
779
|
+
envVars.push(val);
|
|
780
|
+
}
|
|
781
|
+
} else if (arg === "--cwd") {
|
|
782
|
+
cwd = args[++i];
|
|
783
|
+
} else if (arg === "--auth") {
|
|
784
|
+
const val = args[++i];
|
|
785
|
+
if (val === "oauth") {
|
|
786
|
+
hasAuthOAuth = true;
|
|
787
|
+
}
|
|
788
|
+
} else if (arg.startsWith("--include")) {
|
|
789
|
+
hasInclude = true;
|
|
790
|
+
} else if (arg.startsWith("--exclude")) {
|
|
791
|
+
hasExclude = true;
|
|
792
|
+
} else if (arg === "--timeout") {
|
|
793
|
+
hasTimeout = true;
|
|
794
|
+
i++;
|
|
795
|
+
} else if (arg === "--connect-timeout") {
|
|
796
|
+
hasConnectTimeout = true;
|
|
797
|
+
i++;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
if (!name) {
|
|
801
|
+
return { error: "Server name is required." };
|
|
802
|
+
}
|
|
803
|
+
if (hasAuthOAuth) {
|
|
804
|
+
return { error: "--auth oauth is not supported. Use `mcpx auth` to configure auth after adding the server." };
|
|
805
|
+
}
|
|
806
|
+
if (hasInclude || hasExclude) {
|
|
807
|
+
return { error: "--include/--exclude are not supported. Use `mcpx add` directly for advanced configuration." };
|
|
808
|
+
}
|
|
809
|
+
if (url && command) {
|
|
810
|
+
return { error: "Cannot combine --url and --command. Specify one transport mode." };
|
|
811
|
+
}
|
|
812
|
+
if (hasTimeout) {
|
|
813
|
+
return { error: "--timeout is not supported. Configure timeouts in the server config after adding." };
|
|
814
|
+
}
|
|
815
|
+
if (hasConnectTimeout) {
|
|
816
|
+
return { error: "--connect-timeout is not supported. Configure timeouts in the server config after adding." };
|
|
817
|
+
}
|
|
818
|
+
if (url) {
|
|
819
|
+
const spec = {
|
|
820
|
+
transport: "http",
|
|
821
|
+
url
|
|
822
|
+
};
|
|
823
|
+
if (headers.length > 0) {
|
|
824
|
+
const headerObj = {};
|
|
825
|
+
for (const h of headers) {
|
|
826
|
+
const colonIndex = h.indexOf(":");
|
|
827
|
+
if (colonIndex > 0) {
|
|
828
|
+
const key = h.slice(0, colonIndex).trim();
|
|
829
|
+
const value = h.slice(colonIndex + 1).trim();
|
|
830
|
+
headerObj[key] = value;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
spec.headers = headerObj;
|
|
834
|
+
}
|
|
835
|
+
return { name, spec };
|
|
836
|
+
}
|
|
837
|
+
if (command) {
|
|
838
|
+
const spec = {
|
|
839
|
+
transport: "stdio",
|
|
840
|
+
command
|
|
841
|
+
};
|
|
842
|
+
if (commandArgs.length > 0) {
|
|
843
|
+
spec.args = commandArgs;
|
|
844
|
+
}
|
|
845
|
+
if (envVars.length > 0) {
|
|
846
|
+
const envObj = {};
|
|
847
|
+
for (const e of envVars) {
|
|
848
|
+
const eqIndex = e.indexOf("=");
|
|
849
|
+
if (eqIndex > 0) {
|
|
850
|
+
envObj[e.slice(0, eqIndex)] = e.slice(eqIndex + 1);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
spec.env = envObj;
|
|
854
|
+
}
|
|
855
|
+
if (cwd) {
|
|
856
|
+
spec.cwd = cwd;
|
|
857
|
+
}
|
|
858
|
+
return { name, spec };
|
|
859
|
+
}
|
|
860
|
+
return { error: "Server name is required." };
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// src/compat/hermes.ts
|
|
864
|
+
function parseHermesArgs(args) {
|
|
865
|
+
if (args.length === 0) {
|
|
866
|
+
return { error: "Usage: mcpx hermes mcp add <name> --url <url> | --command <cmd>" };
|
|
867
|
+
}
|
|
868
|
+
let name;
|
|
869
|
+
let url;
|
|
870
|
+
let command;
|
|
871
|
+
const envVars = [];
|
|
872
|
+
const commandArgs = [];
|
|
873
|
+
let hasAuth = false;
|
|
874
|
+
let hasPreset = false;
|
|
875
|
+
for (let i = 0;i < args.length; i++) {
|
|
876
|
+
const arg = args[i];
|
|
877
|
+
if (!name && !arg.startsWith("--")) {
|
|
878
|
+
name = arg;
|
|
879
|
+
continue;
|
|
880
|
+
}
|
|
881
|
+
if (arg === "--url") {
|
|
882
|
+
url = args[++i];
|
|
883
|
+
} else if (arg === "--command") {
|
|
884
|
+
command = args[++i];
|
|
885
|
+
} else if (arg === "--args") {
|
|
886
|
+
while (i + 1 < args.length && !args[i + 1].startsWith("--")) {
|
|
887
|
+
commandArgs.push(args[++i]);
|
|
888
|
+
}
|
|
889
|
+
} else if (arg === "--env") {
|
|
890
|
+
const val = args[++i];
|
|
891
|
+
if (val && !val.startsWith("--")) {
|
|
892
|
+
envVars.push(val);
|
|
893
|
+
}
|
|
894
|
+
} else if (arg === "--auth") {
|
|
895
|
+
hasAuth = true;
|
|
896
|
+
} else if (arg === "--preset") {
|
|
897
|
+
hasPreset = true;
|
|
898
|
+
i++;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (!name) {
|
|
902
|
+
return { error: "Server name is required." };
|
|
903
|
+
}
|
|
904
|
+
if (hasAuth) {
|
|
905
|
+
return { error: "--auth is not supported. Use `mcpx auth` to configure auth after adding the server." };
|
|
906
|
+
}
|
|
907
|
+
if (hasPreset) {
|
|
908
|
+
return { error: "--preset is not supported. Use `mcpx add` directly for advanced configuration." };
|
|
909
|
+
}
|
|
910
|
+
if (url) {
|
|
911
|
+
return { name, spec: { transport: "http", url } };
|
|
912
|
+
}
|
|
913
|
+
if (command) {
|
|
914
|
+
const spec = { transport: "stdio", command };
|
|
915
|
+
if (commandArgs.length > 0) {
|
|
916
|
+
spec.args = commandArgs;
|
|
917
|
+
}
|
|
918
|
+
if (envVars.length > 0) {
|
|
919
|
+
const envObj = {};
|
|
920
|
+
for (const e of envVars) {
|
|
921
|
+
const eqIndex = e.indexOf("=");
|
|
922
|
+
if (eqIndex > 0) {
|
|
923
|
+
envObj[e.slice(0, eqIndex)] = e.slice(eqIndex + 1);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
spec.env = envObj;
|
|
927
|
+
}
|
|
928
|
+
return { name, spec };
|
|
929
|
+
}
|
|
930
|
+
return { error: "Server name is required." };
|
|
931
|
+
}
|
|
932
|
+
|
|
732
933
|
// src/compat/unsupported.ts
|
|
733
934
|
var UNSUPPORTED_CLIENTS = {
|
|
734
935
|
"cursor-agent": "Cursor MCP management uses a different interface. Use `mcpx add <name> <url|command>` directly to add MCP servers to mcpx.",
|
|
@@ -825,11 +1026,68 @@ function parseCompatibilityArgs(argv) {
|
|
|
825
1026
|
normalizedArgs: result.normalizedArgs
|
|
826
1027
|
};
|
|
827
1028
|
}
|
|
1029
|
+
if (argv[0] === "openclaw" && argv[1] === "mcp" && argv[2] === "add") {
|
|
1030
|
+
const openclawArgs = argv.slice(3);
|
|
1031
|
+
const result = parseOpenClawArgs(openclawArgs);
|
|
1032
|
+
if ("error" in result) {
|
|
1033
|
+
return {
|
|
1034
|
+
client: "openclaw",
|
|
1035
|
+
normalizedArgs: null,
|
|
1036
|
+
error: result.error
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
return {
|
|
1040
|
+
client: "openclaw",
|
|
1041
|
+
normalizedArgs: ["--name", result.name, ...buildSpecArgs(result.spec)]
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
if (argv[0] === "hermes" && argv[1] === "mcp" && argv[2] === "add") {
|
|
1045
|
+
const hermesArgs = argv.slice(3);
|
|
1046
|
+
const result = parseHermesArgs(hermesArgs);
|
|
1047
|
+
if ("error" in result) {
|
|
1048
|
+
return {
|
|
1049
|
+
client: "hermes",
|
|
1050
|
+
normalizedArgs: null,
|
|
1051
|
+
error: result.error
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
client: "hermes",
|
|
1056
|
+
normalizedArgs: ["--name", result.name, ...buildSpecArgs(result.spec)]
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
828
1059
|
return {
|
|
829
1060
|
client: null,
|
|
830
1061
|
normalizedArgs: null
|
|
831
1062
|
};
|
|
832
1063
|
}
|
|
1064
|
+
function buildSpecArgs(spec) {
|
|
1065
|
+
const args = [];
|
|
1066
|
+
if (spec.transport === "http") {
|
|
1067
|
+
args.push(spec.url);
|
|
1068
|
+
if (spec.headers) {
|
|
1069
|
+
for (const [k, v] of Object.entries(spec.headers)) {
|
|
1070
|
+
args.push("--header", `${k}=${v}`);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
} else {
|
|
1074
|
+
args.push("--command", spec.command);
|
|
1075
|
+
if (Array.isArray(spec.args) && spec.args.length > 0) {
|
|
1076
|
+
for (const a of spec.args) {
|
|
1077
|
+
args.push("--arg", a);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
if (spec.env) {
|
|
1081
|
+
for (const [k, v] of Object.entries(spec.env)) {
|
|
1082
|
+
args.push("--env", `${k}=${v}`);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
if (spec.cwd) {
|
|
1086
|
+
args.push("--cwd", spec.cwd);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
return args;
|
|
1090
|
+
}
|
|
833
1091
|
|
|
834
1092
|
// src/core/proxy.ts
|
|
835
1093
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
@@ -1057,6 +1315,10 @@ function printSyncSummary(summary, asJson = false) {
|
|
|
1057
1315
|
}
|
|
1058
1316
|
process.stdout.write(`
|
|
1059
1317
|
`);
|
|
1318
|
+
if (result.driftedEntries && result.driftedEntries.length > 0) {
|
|
1319
|
+
process.stdout.write(` (note: ${result.driftedEntries.length} manually-edited entr${result.driftedEntries.length === 1 ? "y was" : "ies were"} reset to mcpx-managed values: ${result.driftedEntries.join(", ")})
|
|
1320
|
+
`);
|
|
1321
|
+
}
|
|
1060
1322
|
}
|
|
1061
1323
|
}
|
|
1062
1324
|
async function ensureDaemonIfEnabled(cliPath, secrets) {
|
|
@@ -1069,11 +1331,14 @@ async function ensureDaemonIfEnabled(cliPath, secrets) {
|
|
|
1069
1331
|
}
|
|
1070
1332
|
await startDaemon(config, cliPath, secrets);
|
|
1071
1333
|
}
|
|
1072
|
-
async function autoSyncManagedEntries(
|
|
1334
|
+
async function autoSyncManagedEntries(cliPath) {
|
|
1073
1335
|
const secrets = new SecretsManager;
|
|
1074
1336
|
await ensureDaemonIfEnabled(cliPath, secrets);
|
|
1075
|
-
const
|
|
1076
|
-
const summary = syncAllClients(
|
|
1337
|
+
const config = loadMergedConfig();
|
|
1338
|
+
const summary = syncAllClients(config, secrets);
|
|
1339
|
+
await mutateConfig((freshConfig) => {
|
|
1340
|
+
persistSyncState(summary, freshConfig);
|
|
1341
|
+
});
|
|
1077
1342
|
printSyncSummary(summary, false);
|
|
1078
1343
|
ensureExitCodeForSyncFailures(summary.hasErrors);
|
|
1079
1344
|
}
|
|
@@ -1567,6 +1832,8 @@ async function reconnectGatewayAndSync(cliPath) {
|
|
|
1567
1832
|
process.stdout.write(`${restart.message} pid=${restart.pid} port=${restart.port}
|
|
1568
1833
|
`);
|
|
1569
1834
|
const summary = syncAllClients(config, secrets);
|
|
1835
|
+
persistSyncState(summary, config);
|
|
1836
|
+
saveConfig(config);
|
|
1570
1837
|
printSyncSummary(summary, false);
|
|
1571
1838
|
}
|
|
1572
1839
|
async function setServerEnabledInteractively(rl, serverName, enabled, cliPath) {
|
|
@@ -1595,7 +1862,7 @@ async function setServerEnabledInteractively(rl, serverName, enabled, cliPath) {
|
|
|
1595
1862
|
`);
|
|
1596
1863
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
1597
1864
|
`);
|
|
1598
|
-
await autoSyncManagedEntries(
|
|
1865
|
+
await autoSyncManagedEntries(cliPath);
|
|
1599
1866
|
return true;
|
|
1600
1867
|
}
|
|
1601
1868
|
}
|
|
@@ -1609,7 +1876,7 @@ async function setServerEnabledInteractively(rl, serverName, enabled, cliPath) {
|
|
|
1609
1876
|
`);
|
|
1610
1877
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
1611
1878
|
`);
|
|
1612
|
-
await autoSyncManagedEntries(
|
|
1879
|
+
await autoSyncManagedEntries(cliPath);
|
|
1613
1880
|
return true;
|
|
1614
1881
|
}
|
|
1615
1882
|
function buildServerActionTitle(server) {
|
|
@@ -1731,25 +1998,23 @@ async function runInteractiveStatusMenu(cliPath) {
|
|
|
1731
1998
|
}
|
|
1732
1999
|
function registerEnabledCommand(parent, enabled, cliPath) {
|
|
1733
2000
|
parent.command(enabled ? "enable <name>" : "disable <name>").option("-g, --global", "Force target the global configuration").option("-l, --local", "Force target (or initialize) a local `.mcpx.json` configuration").description(`${enabled ? "Enable" : "Disable"} an upstream MCP server`).action(async (name, options) => {
|
|
1734
|
-
const
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
if (
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
2001
|
+
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2002
|
+
setServerEnabled(config, name, enabled);
|
|
2003
|
+
});
|
|
2004
|
+
if (type === "project" && projectPath) {
|
|
2005
|
+
await mutateConfig((globalConfig) => {
|
|
2006
|
+
registerProject(globalConfig, projectPath, globalConfig.projects?.[path.resolve(projectPath)]?.name);
|
|
2007
|
+
});
|
|
1741
2008
|
}
|
|
1742
|
-
process.stdout.write(`${enabled ? "Enabled" : "Disabled"} server: ${name} (${
|
|
2009
|
+
process.stdout.write(`${enabled ? "Enabled" : "Disabled"} server: ${name} (${type} config)
|
|
1743
2010
|
`);
|
|
1744
2011
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
1745
2012
|
`);
|
|
1746
|
-
|
|
1747
|
-
await autoSyncManagedEntries(mergedConfig, cliPath);
|
|
2013
|
+
await autoSyncManagedEntries(cliPath);
|
|
1748
2014
|
});
|
|
1749
2015
|
}
|
|
1750
2016
|
function registerAddCommand(parent, cliPath) {
|
|
1751
2017
|
parent.command("add [values...]").allowUnknownOption(true).option("--transport <transport>", "MCP transport (auto|http|stdio)", "auto").option("--header <header>", "Header entry in KEY=VALUE form", (value, previous = []) => [...previous, value], []).option("--env <env>", "Env entry in KEY=VALUE form for stdio upstreams", (value, previous = []) => [...previous, value], []).option("--cwd <cwd>", "Working directory for stdio upstream").option("--force", "Overwrite existing server with same name").option("-g, --global", "Force saving to global configuration").option("-l, --local", "Force saving to local project configuration").description("Add an upstream MCP server").action(async (values, options) => {
|
|
1752
|
-
const context = resolveActiveConfig({ global: options.global, local: options.local });
|
|
1753
2018
|
const safeValues = values ?? [];
|
|
1754
2019
|
const secrets = new SecretsManager;
|
|
1755
2020
|
if (safeValues.length === 1 && safeValues[0]?.includes("/")) {
|
|
@@ -1804,46 +2069,46 @@ Value: ` : `${input.name} (${input.kind}): `;
|
|
|
1804
2069
|
spec.env = Object.keys(env).length > 0 ? env : undefined;
|
|
1805
2070
|
}
|
|
1806
2071
|
}
|
|
1807
|
-
if (context.type === "project") {
|
|
1808
|
-
const globalConfig = loadConfig();
|
|
1809
|
-
registerProject(globalConfig, context.projectPath);
|
|
1810
|
-
saveConfig(globalConfig);
|
|
1811
|
-
}
|
|
1812
|
-
addServer(context.config, shortName, spec, options.force ?? false);
|
|
1813
2072
|
await maybeAutoConfigureAuthForAddedServer(shortName, spec, secrets);
|
|
1814
|
-
|
|
1815
|
-
|
|
2073
|
+
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2074
|
+
addServer(config, shortName, spec, options.force ?? false);
|
|
2075
|
+
});
|
|
2076
|
+
if (type === "project" && projectPath) {
|
|
2077
|
+
await mutateConfig((globalConfig) => {
|
|
2078
|
+
registerProject(globalConfig, projectPath, globalConfig.projects?.[path.resolve(projectPath)]?.name);
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
process.stdout.write(`Added server: ${shortName} (${spec.transport}) from registry "${registryName}"${type === "project" ? ` (project: ${projectPath})` : ""}
|
|
1816
2082
|
`);
|
|
1817
2083
|
} else {
|
|
1818
2084
|
const parsed = parseAddServerSpec(safeValues, options);
|
|
1819
|
-
if (context.type === "project") {
|
|
1820
|
-
const globalConfig = loadConfig();
|
|
1821
|
-
registerProject(globalConfig, context.projectPath);
|
|
1822
|
-
saveConfig(globalConfig);
|
|
1823
|
-
}
|
|
1824
|
-
addServer(context.config, parsed.name, parsed.spec, options.force ?? false);
|
|
1825
2085
|
await maybeAutoConfigureAuthForAddedServer(parsed.name, parsed.spec, secrets);
|
|
1826
|
-
|
|
1827
|
-
|
|
2086
|
+
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2087
|
+
addServer(config, parsed.name, parsed.spec, options.force ?? false);
|
|
2088
|
+
});
|
|
2089
|
+
if (type === "project" && projectPath) {
|
|
2090
|
+
await mutateConfig((globalConfig) => {
|
|
2091
|
+
registerProject(globalConfig, projectPath, globalConfig.projects?.[path.resolve(projectPath)]?.name);
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
process.stdout.write(`Added server: ${parsed.name} (${parsed.spec.transport})${type === "project" ? ` (project: ${projectPath})` : ""}
|
|
1828
2095
|
`);
|
|
1829
2096
|
}
|
|
1830
2097
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
1831
2098
|
`);
|
|
1832
|
-
|
|
1833
|
-
await autoSyncManagedEntries(mergedConfig, cliPath);
|
|
2099
|
+
await autoSyncManagedEntries(cliPath);
|
|
1834
2100
|
});
|
|
1835
2101
|
}
|
|
1836
2102
|
function registerRemoveCommand(parent, cliPath) {
|
|
1837
2103
|
parent.command("remove <name>").option("--force", "Do not error if server does not exist").option("-g, --global", "Force target global configuration").option("-l, --local", "Force target local project configuration").description("Remove an upstream MCP server").action(async (name, options) => {
|
|
1838
|
-
const
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
process.stdout.write(`Removed server: ${name} ${
|
|
2104
|
+
const { type, projectPath } = await mutateActiveConfig({ global: options.global, local: options.local }, (config) => {
|
|
2105
|
+
removeServer(config, name, options.force ?? false);
|
|
2106
|
+
});
|
|
2107
|
+
process.stdout.write(`Removed server: ${name} ${type === "project" ? `from project: ${projectPath}` : "globally"}
|
|
1842
2108
|
`);
|
|
1843
2109
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
1844
2110
|
`);
|
|
1845
|
-
|
|
1846
|
-
await autoSyncManagedEntries(mergedConfig, cliPath);
|
|
2111
|
+
await autoSyncManagedEntries(cliPath);
|
|
1847
2112
|
});
|
|
1848
2113
|
}
|
|
1849
2114
|
function registerListCommand(parent) {
|
|
@@ -1914,12 +2179,14 @@ function registerListCommand(parent) {
|
|
|
1914
2179
|
});
|
|
1915
2180
|
}
|
|
1916
2181
|
function registerSyncCommand(program, cliPath) {
|
|
1917
|
-
program.command("sync [clients...]").option("--client <id>", "Limit sync to specific client(s), comma-separated or repeated", (value, prev = []) => [...prev, value], []).option("--json", "Output JSON").description("Sync gateway configuration to supported clients (e.g. `mcpx sync claude`)").action(async (clients, options) => {
|
|
1918
|
-
const config =
|
|
2182
|
+
program.command("sync [clients...]").option("--client <id>", "Limit sync to specific client(s), comma-separated or repeated", (value, prev = []) => [...prev, value], []).option("--import", "Also scan clients for unmanaged servers and adopt them into the mcpx catalog", false).option("--json", "Output JSON").description("Sync gateway configuration to supported clients (e.g. `mcpx sync claude`)").action(async (clients, options) => {
|
|
2183
|
+
const config = loadConfig();
|
|
1919
2184
|
const targetClients = parseClientList([...clients ?? [], ...options.client ?? []]);
|
|
1920
2185
|
const secrets = new SecretsManager;
|
|
1921
2186
|
await ensureDaemonIfEnabled(cliPath, secrets);
|
|
1922
|
-
const summary = syncAllClients(config, secrets, targetClients);
|
|
2187
|
+
const summary = syncAllClients(config, secrets, { targetClients, importScan: options.import ?? false });
|
|
2188
|
+
persistSyncState(summary, config);
|
|
2189
|
+
saveConfig(config);
|
|
1923
2190
|
printSyncSummary(summary, options.json ?? false);
|
|
1924
2191
|
ensureExitCodeForSyncFailures(summary.hasErrors);
|
|
1925
2192
|
});
|
|
@@ -2309,11 +2576,11 @@ function registerProjectCommands(program, cliPath) {
|
|
|
2309
2576
|
name: projectName,
|
|
2310
2577
|
servers: {}
|
|
2311
2578
|
};
|
|
2312
|
-
const { saveProjectConfig: saveProjectConfig2 } = await import("./config-
|
|
2579
|
+
const { saveProjectConfig: saveProjectConfig2 } = await import("./config-5p08cb0c.js");
|
|
2313
2580
|
saveProjectConfig2(localConfig, targetPath);
|
|
2314
2581
|
process.stdout.write(`Initialized project configuration at: ${targetPath}
|
|
2315
2582
|
`);
|
|
2316
|
-
const { registerProject: registerProject2 } = await import("./registry-
|
|
2583
|
+
const { registerProject: registerProject2 } = await import("./registry-n12thgf2.js");
|
|
2317
2584
|
const globalConfig = loadConfig();
|
|
2318
2585
|
registerProject2(globalConfig, process.cwd(), projectName);
|
|
2319
2586
|
saveConfig(globalConfig);
|
|
@@ -2344,21 +2611,20 @@ function registerProjectCommands(program, cliPath) {
|
|
|
2344
2611
|
process.exit(1);
|
|
2345
2612
|
}
|
|
2346
2613
|
const entry = globalConfig.projects[resolvedPath];
|
|
2347
|
-
const { unregisterProject: unregisterProject2 } = await import("./registry-
|
|
2614
|
+
const { unregisterProject: unregisterProject2 } = await import("./registry-n12thgf2.js");
|
|
2348
2615
|
unregisterProject2(globalConfig, resolvedPath);
|
|
2349
2616
|
saveConfig(globalConfig);
|
|
2350
2617
|
process.stdout.write(`Unregistered project "${entry.name}" (${resolvedPath}) from the global configuration.
|
|
2351
2618
|
`);
|
|
2352
2619
|
process.stdout.write(`Auto-syncing managed gateway entries across all supported clients...
|
|
2353
2620
|
`);
|
|
2354
|
-
|
|
2355
|
-
await autoSyncManagedEntries(mergedConfig, cliPath);
|
|
2621
|
+
await autoSyncManagedEntries(cliPath);
|
|
2356
2622
|
});
|
|
2357
2623
|
}
|
|
2358
2624
|
function registerPluginCommands(program, _cliPath) {
|
|
2359
2625
|
const plugin = program.command("plugin").description("Manage plugins");
|
|
2360
2626
|
plugin.command("inspect <source>").description("Inspect plugin manifest and components").action(async (source) => {
|
|
2361
|
-
const { inspectPlugin } = await import("./plugin-manager-
|
|
2627
|
+
const { inspectPlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2362
2628
|
try {
|
|
2363
2629
|
const info = await inspectPlugin(source);
|
|
2364
2630
|
process.stdout.write(JSON.stringify(info, null, 2) + `
|
|
@@ -2370,7 +2636,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2370
2636
|
}
|
|
2371
2637
|
});
|
|
2372
2638
|
plugin.command("install <source>").option("--name <name>", "Plugin name").option("--no-enable", "Don't enable plugin after install").description("Install plugin").action(async (source, options) => {
|
|
2373
|
-
const { installPlugin } = await import("./plugin-manager-
|
|
2639
|
+
const { installPlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2374
2640
|
try {
|
|
2375
2641
|
const p = await installPlugin(source, {
|
|
2376
2642
|
name: options.name,
|
|
@@ -2385,7 +2651,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2385
2651
|
}
|
|
2386
2652
|
});
|
|
2387
2653
|
plugin.command("approve <name> <component>").description("Approve a plugin component (hooks, mcpServers)").action(async (name, component) => {
|
|
2388
|
-
const { approvePluginComponent } = await import("./plugin-manager-
|
|
2654
|
+
const { approvePluginComponent } = await import("./plugin-manager-m8ar2271.js");
|
|
2389
2655
|
try {
|
|
2390
2656
|
await approvePluginComponent(name, component);
|
|
2391
2657
|
process.stdout.write(`Approved ${component} for plugin ${name}
|
|
@@ -2397,7 +2663,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2397
2663
|
}
|
|
2398
2664
|
});
|
|
2399
2665
|
plugin.command("prepare <name>").description("Install plugin dependencies").action(async (name) => {
|
|
2400
|
-
const { preparePlugin } = await import("./plugin-manager-
|
|
2666
|
+
const { preparePlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2401
2667
|
try {
|
|
2402
2668
|
await preparePlugin(name);
|
|
2403
2669
|
process.stdout.write(`Plugin ${name} prepared
|
|
@@ -2409,7 +2675,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2409
2675
|
}
|
|
2410
2676
|
});
|
|
2411
2677
|
plugin.command("update <name>").description("Update plugin to latest version").action(async (name) => {
|
|
2412
|
-
const { updatePlugin } = await import("./plugin-manager-
|
|
2678
|
+
const { updatePlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2413
2679
|
try {
|
|
2414
2680
|
const p = await updatePlugin(name);
|
|
2415
2681
|
process.stdout.write(`Plugin ${name} updated to ${p.version}
|
|
@@ -2421,7 +2687,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2421
2687
|
}
|
|
2422
2688
|
});
|
|
2423
2689
|
plugin.command("uninstall <name>").option("--keep-data", "Keep plugin data after uninstall").description("Uninstall plugin").action(async (name, options) => {
|
|
2424
|
-
const { uninstallPlugin } = await import("./plugin-manager-
|
|
2690
|
+
const { uninstallPlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2425
2691
|
try {
|
|
2426
2692
|
await uninstallPlugin(name, options.keepData || false);
|
|
2427
2693
|
process.stdout.write(`Plugin ${name} uninstalled
|
|
@@ -2432,24 +2698,40 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2432
2698
|
process.exit(1);
|
|
2433
2699
|
}
|
|
2434
2700
|
});
|
|
2435
|
-
plugin.command("enable <name>").description("Enable plugin").action(async (name) => {
|
|
2436
|
-
const { enablePlugin } = await import("./plugin-manager-1sc4b6am.js");
|
|
2701
|
+
plugin.command("enable <name>").option("--project <path>", "Scope this enable to a single registered project instead of globally").description("Enable plugin (globally, or for one project with --project)").action(async (name, options) => {
|
|
2437
2702
|
try {
|
|
2438
|
-
|
|
2439
|
-
|
|
2703
|
+
if (options.project) {
|
|
2704
|
+
const { setPluginProjectOverride } = await import("./plugin-manager-m8ar2271.js");
|
|
2705
|
+
const resolvedPath = path.resolve(options.project);
|
|
2706
|
+
await setPluginProjectOverride(name, resolvedPath, { enabled: true });
|
|
2707
|
+
process.stdout.write(`Plugin ${name} enabled for project: ${resolvedPath}
|
|
2440
2708
|
`);
|
|
2709
|
+
} else {
|
|
2710
|
+
const { enablePlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2711
|
+
await enablePlugin(name);
|
|
2712
|
+
process.stdout.write(`Plugin ${name} enabled
|
|
2713
|
+
`);
|
|
2714
|
+
}
|
|
2441
2715
|
} catch (e) {
|
|
2442
2716
|
process.stderr.write(`Error: ${e.message}
|
|
2443
2717
|
`);
|
|
2444
2718
|
process.exit(1);
|
|
2445
2719
|
}
|
|
2446
2720
|
});
|
|
2447
|
-
plugin.command("disable <name>").description("Disable plugin").action(async (name) => {
|
|
2448
|
-
const { disablePlugin } = await import("./plugin-manager-1sc4b6am.js");
|
|
2721
|
+
plugin.command("disable <name>").option("--project <path>", "Scope this disable to a single registered project instead of globally").description("Disable plugin (globally, or for one project with --project)").action(async (name, options) => {
|
|
2449
2722
|
try {
|
|
2450
|
-
|
|
2451
|
-
|
|
2723
|
+
if (options.project) {
|
|
2724
|
+
const { setPluginProjectOverride } = await import("./plugin-manager-m8ar2271.js");
|
|
2725
|
+
const resolvedPath = path.resolve(options.project);
|
|
2726
|
+
await setPluginProjectOverride(name, resolvedPath, { enabled: false });
|
|
2727
|
+
process.stdout.write(`Plugin ${name} disabled for project: ${resolvedPath}
|
|
2452
2728
|
`);
|
|
2729
|
+
} else {
|
|
2730
|
+
const { disablePlugin } = await import("./plugin-manager-m8ar2271.js");
|
|
2731
|
+
await disablePlugin(name);
|
|
2732
|
+
process.stdout.write(`Plugin ${name} disabled
|
|
2733
|
+
`);
|
|
2734
|
+
}
|
|
2453
2735
|
} catch (e) {
|
|
2454
2736
|
process.stderr.write(`Error: ${e.message}
|
|
2455
2737
|
`);
|
|
@@ -2457,7 +2739,7 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2457
2739
|
}
|
|
2458
2740
|
});
|
|
2459
2741
|
plugin.command("status [name]").description("Show plugin status").action(async (name) => {
|
|
2460
|
-
const { getPluginStatus, listPlugins } = await import("./plugin-manager-
|
|
2742
|
+
const { getPluginStatus, listPlugins } = await import("./plugin-manager-m8ar2271.js");
|
|
2461
2743
|
try {
|
|
2462
2744
|
if (name) {
|
|
2463
2745
|
const p = await getPluginStatus(name);
|
|
@@ -2480,6 +2762,12 @@ function registerPluginCommands(program, _cliPath) {
|
|
|
2480
2762
|
}
|
|
2481
2763
|
});
|
|
2482
2764
|
}
|
|
2765
|
+
function registerPluginHostCommand(program) {
|
|
2766
|
+
program.command("plugin-host <plugin> <server>").description("Run a plugin MCP server under mcpx policy enforcement").action(async (plugin, server) => {
|
|
2767
|
+
const { runPluginHost } = await import("./plugin-host-954a7tf7.js");
|
|
2768
|
+
runPluginHost(plugin, server);
|
|
2769
|
+
});
|
|
2770
|
+
}
|
|
2483
2771
|
function registerProxyCommand(program) {
|
|
2484
2772
|
program.command("proxy <name>").description("Run a stdio MCP proxy bridging to the local mcpx HTTP gateway for the given upstream server").action(async (name) => {
|
|
2485
2773
|
await runStdioProxy(name);
|
|
@@ -2504,14 +2792,19 @@ async function runCli(argv = process.argv) {
|
|
|
2504
2792
|
const stagedCliPath = getStagedCliPath();
|
|
2505
2793
|
const stagedInfo = getStagedUpdate();
|
|
2506
2794
|
if (stagedCliPath && stagedInfo && stagedCliPath !== argv[1] && shouldUseStagedCli(stagedInfo.version, APP_VERSION)) {
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2795
|
+
try {
|
|
2796
|
+
execFileSync(process.execPath, [stagedCliPath, ...rawArgs], {
|
|
2797
|
+
stdio: "inherit",
|
|
2798
|
+
env: {
|
|
2799
|
+
...process.env,
|
|
2800
|
+
MCPX_USING_STAGED: "1"
|
|
2801
|
+
}
|
|
2802
|
+
});
|
|
2803
|
+
return;
|
|
2804
|
+
} catch (error) {
|
|
2805
|
+
process.stderr.write(`Warning: staged update v${stagedInfo.version} failed to run (${error.message}). ` + `Falling back to the currently installed version (v${APP_VERSION}). ` + `Run "mcpx update rollback" to clear the broken staged update.
|
|
2806
|
+
`);
|
|
2807
|
+
}
|
|
2515
2808
|
}
|
|
2516
2809
|
}
|
|
2517
2810
|
if (rawArgs.length > 0) {
|
|
@@ -2541,6 +2834,7 @@ async function runCli(argv = process.argv) {
|
|
|
2541
2834
|
registerAuthCommands(program);
|
|
2542
2835
|
registerClientsCommands(program);
|
|
2543
2836
|
registerSkillsCommands(program);
|
|
2837
|
+
registerPluginHostCommand(program);
|
|
2544
2838
|
registerProxyCommand(program);
|
|
2545
2839
|
registerMcpCompat(program, cliPath);
|
|
2546
2840
|
registerUpdateCommand(program);
|
|
@@ -2550,8 +2844,25 @@ async function runCli(argv = process.argv) {
|
|
|
2550
2844
|
}
|
|
2551
2845
|
if (process.argv[1] && import.meta.url === pathToFileURL(fs.realpathSync(process.argv[1])).href) {
|
|
2552
2846
|
runCli().catch((error) => {
|
|
2553
|
-
|
|
2847
|
+
if (error instanceof ConfigLoadError) {
|
|
2848
|
+
process.stderr.write(`Config error: ${error.message}
|
|
2554
2849
|
`);
|
|
2850
|
+
if (error.backupPath) {
|
|
2851
|
+
process.stderr.write(`Backup saved to: ${error.backupPath}
|
|
2852
|
+
`);
|
|
2853
|
+
}
|
|
2854
|
+
if (error.issues && error.issues.length > 0) {
|
|
2855
|
+
for (const issue of error.issues.slice(0, 5)) {
|
|
2856
|
+
process.stderr.write(` - ${issue}
|
|
2857
|
+
`);
|
|
2858
|
+
}
|
|
2859
|
+
}
|
|
2860
|
+
process.stderr.write(`Fix the config file or restore from backup.
|
|
2861
|
+
`);
|
|
2862
|
+
} else {
|
|
2863
|
+
process.stderr.write(`${error.message}
|
|
2864
|
+
`);
|
|
2865
|
+
}
|
|
2555
2866
|
process.exit(1);
|
|
2556
2867
|
});
|
|
2557
2868
|
}
|