add-mcp 1.10.0 → 1.10.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/dist/{chunk-56AZIA6W.js → chunk-B27GVIBZ.js} +157 -3
- package/dist/index.js +6 -132
- package/dist/lib.js +1 -1
- package/package.json +1 -1
|
@@ -669,6 +669,150 @@ async function selectAgentsInteractive(availableAgents, options) {
|
|
|
669
669
|
return promptForAgents("Select agents to install to", agentChoices, false);
|
|
670
670
|
}
|
|
671
671
|
|
|
672
|
+
// src/source-parser.ts
|
|
673
|
+
function isUrl(input) {
|
|
674
|
+
return input.startsWith("http://") || input.startsWith("https://");
|
|
675
|
+
}
|
|
676
|
+
function looksLikePath(input) {
|
|
677
|
+
if (input.startsWith("/")) return true;
|
|
678
|
+
if (input.startsWith("~/") || input === "~") return true;
|
|
679
|
+
if (input.startsWith("./") || input.startsWith("../")) return true;
|
|
680
|
+
if (/^[A-Za-z]:[\\/]/.test(input)) return true;
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
function isCommand(input) {
|
|
684
|
+
if (looksLikePath(input)) {
|
|
685
|
+
return true;
|
|
686
|
+
}
|
|
687
|
+
if (input.includes(" ")) {
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
if (input.startsWith("npx ") || input.startsWith("node ") || input.startsWith("python ")) {
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
return false;
|
|
694
|
+
}
|
|
695
|
+
function isPackageName(input) {
|
|
696
|
+
if (input.startsWith("@") && input.includes("/")) {
|
|
697
|
+
return true;
|
|
698
|
+
}
|
|
699
|
+
if (/^[a-z0-9][\w.-]*(@[\w.-]+)?$/i.test(input)) {
|
|
700
|
+
return true;
|
|
701
|
+
}
|
|
702
|
+
return false;
|
|
703
|
+
}
|
|
704
|
+
var commonTlds = /* @__PURE__ */ new Set([
|
|
705
|
+
"com",
|
|
706
|
+
"org",
|
|
707
|
+
"net",
|
|
708
|
+
"io",
|
|
709
|
+
"dev",
|
|
710
|
+
"ai",
|
|
711
|
+
"tech",
|
|
712
|
+
"co",
|
|
713
|
+
"app",
|
|
714
|
+
"cloud",
|
|
715
|
+
"sh",
|
|
716
|
+
"run"
|
|
717
|
+
]);
|
|
718
|
+
function extractBrandFromHostname(hostname) {
|
|
719
|
+
const parts = hostname.split(".");
|
|
720
|
+
const meaningfulParts = parts.filter((part) => {
|
|
721
|
+
const lower = part.toLowerCase();
|
|
722
|
+
if (commonTlds.has(lower)) return false;
|
|
723
|
+
if (lower === "mcp" || lower === "api" || lower === "www") return false;
|
|
724
|
+
return true;
|
|
725
|
+
});
|
|
726
|
+
if (meaningfulParts.length > 0) {
|
|
727
|
+
return meaningfulParts[0];
|
|
728
|
+
}
|
|
729
|
+
if (parts.length >= 2) {
|
|
730
|
+
return parts[parts.length - 2];
|
|
731
|
+
}
|
|
732
|
+
return "mcp-server";
|
|
733
|
+
}
|
|
734
|
+
function inferName(input, type) {
|
|
735
|
+
if (type === "remote") {
|
|
736
|
+
try {
|
|
737
|
+
const url = new URL(input);
|
|
738
|
+
return extractBrandFromHostname(url.hostname);
|
|
739
|
+
} catch {
|
|
740
|
+
return "mcp-server";
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
if (type === "command") {
|
|
744
|
+
if (looksLikePath(input)) {
|
|
745
|
+
const segments = input.split(/[\\/]/);
|
|
746
|
+
const base = segments[segments.length - 1] || "mcp-server";
|
|
747
|
+
const withoutExt = base.replace(/\.[^.]+$/, "");
|
|
748
|
+
return extractPackageName(withoutExt || base);
|
|
749
|
+
}
|
|
750
|
+
const parts = input.split(" ");
|
|
751
|
+
let startIndex = 0;
|
|
752
|
+
if (parts[0] === "npx" || parts[0] === "node" || parts[0] === "python") {
|
|
753
|
+
startIndex = 1;
|
|
754
|
+
}
|
|
755
|
+
for (let i = startIndex; i < parts.length; i++) {
|
|
756
|
+
const part = parts[i];
|
|
757
|
+
if (part && !part.startsWith("-")) {
|
|
758
|
+
return extractPackageName(part);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return "mcp-server";
|
|
762
|
+
}
|
|
763
|
+
return extractPackageName(input);
|
|
764
|
+
}
|
|
765
|
+
function extractPackageName(input) {
|
|
766
|
+
let name = input;
|
|
767
|
+
const atIndex = name.lastIndexOf("@");
|
|
768
|
+
if (atIndex > 0 && !name.startsWith("@")) {
|
|
769
|
+
name = name.slice(0, atIndex);
|
|
770
|
+
} else if (name.startsWith("@") && name.indexOf("@", 1) > 0) {
|
|
771
|
+
const secondAt = name.indexOf("@", 1);
|
|
772
|
+
name = name.slice(0, secondAt);
|
|
773
|
+
}
|
|
774
|
+
if (name.startsWith("@") && name.includes("/")) {
|
|
775
|
+
const parts = name.split("/");
|
|
776
|
+
name = parts[1] || name;
|
|
777
|
+
}
|
|
778
|
+
name = name.replace(/^mcp-server-/, "");
|
|
779
|
+
name = name.replace(/^server-/, "");
|
|
780
|
+
name = name.replace(/-mcp$/, "");
|
|
781
|
+
return name || "mcp-server";
|
|
782
|
+
}
|
|
783
|
+
function parseSource(input) {
|
|
784
|
+
const trimmed = input.trim();
|
|
785
|
+
if (isUrl(trimmed)) {
|
|
786
|
+
return {
|
|
787
|
+
type: "remote",
|
|
788
|
+
value: trimmed,
|
|
789
|
+
inferredName: inferName(trimmed, "remote")
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
if (isCommand(trimmed)) {
|
|
793
|
+
return {
|
|
794
|
+
type: "command",
|
|
795
|
+
value: trimmed,
|
|
796
|
+
inferredName: inferName(trimmed, "command")
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
if (isPackageName(trimmed)) {
|
|
800
|
+
return {
|
|
801
|
+
type: "package",
|
|
802
|
+
value: trimmed,
|
|
803
|
+
inferredName: inferName(trimmed, "package")
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
return {
|
|
807
|
+
type: "package",
|
|
808
|
+
value: trimmed,
|
|
809
|
+
inferredName: inferName(trimmed, "package")
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function isRemoteSource(parsed) {
|
|
813
|
+
return parsed.type === "remote";
|
|
814
|
+
}
|
|
815
|
+
|
|
672
816
|
// src/formats/utils.ts
|
|
673
817
|
function deepMerge(target, source) {
|
|
674
818
|
const result = { ...target };
|
|
@@ -959,9 +1103,17 @@ function buildServerConfig(parsed, options = {}) {
|
|
|
959
1103
|
return config2;
|
|
960
1104
|
}
|
|
961
1105
|
if (parsed.type === "command") {
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1106
|
+
let command;
|
|
1107
|
+
let parsedArgs;
|
|
1108
|
+
if (looksLikePath(parsed.value)) {
|
|
1109
|
+
command = parsed.value;
|
|
1110
|
+
parsedArgs = [];
|
|
1111
|
+
} else {
|
|
1112
|
+
const parts = parsed.value.split(" ");
|
|
1113
|
+
command = parts[0];
|
|
1114
|
+
parsedArgs = parts.slice(1);
|
|
1115
|
+
}
|
|
1116
|
+
const args = [...parsedArgs, ...options.args ?? []];
|
|
965
1117
|
const config2 = {
|
|
966
1118
|
command,
|
|
967
1119
|
args
|
|
@@ -1207,6 +1359,8 @@ export {
|
|
|
1207
1359
|
isTransportSupported,
|
|
1208
1360
|
buildAgentSelectionChoices,
|
|
1209
1361
|
selectAgentsInteractive,
|
|
1362
|
+
parseSource,
|
|
1363
|
+
isRemoteSource,
|
|
1210
1364
|
getNestedValue,
|
|
1211
1365
|
readConfig2 as readConfig,
|
|
1212
1366
|
removeServerFromConfig,
|
package/dist/index.js
CHANGED
|
@@ -13,14 +13,16 @@ import {
|
|
|
13
13
|
getProjectCapableAgents,
|
|
14
14
|
installServer,
|
|
15
15
|
installServerForAgent,
|
|
16
|
+
isRemoteSource,
|
|
16
17
|
isTransportSupported,
|
|
17
18
|
listInstalledServers,
|
|
19
|
+
parseSource,
|
|
18
20
|
removeServerFromConfig,
|
|
19
21
|
saveFindRegistries,
|
|
20
22
|
selectAgentsInteractive,
|
|
21
23
|
supportsProjectConfig,
|
|
22
24
|
updateGitignoreWithPaths
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-B27GVIBZ.js";
|
|
24
26
|
|
|
25
27
|
// src/index.ts
|
|
26
28
|
import { program } from "commander";
|
|
@@ -35,134 +37,6 @@ var agentAliases = {
|
|
|
35
37
|
"github-copilot": "vscode"
|
|
36
38
|
};
|
|
37
39
|
|
|
38
|
-
// src/source-parser.ts
|
|
39
|
-
function isUrl(input) {
|
|
40
|
-
return input.startsWith("http://") || input.startsWith("https://");
|
|
41
|
-
}
|
|
42
|
-
function isCommand(input) {
|
|
43
|
-
if (input.includes(" ")) {
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
if (input.startsWith("npx ") || input.startsWith("node ") || input.startsWith("python ")) {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
function isPackageName(input) {
|
|
52
|
-
if (input.startsWith("@") && input.includes("/")) {
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
if (/^[a-z0-9][\w.-]*(@[\w.-]+)?$/i.test(input)) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
var commonTlds = /* @__PURE__ */ new Set([
|
|
61
|
-
"com",
|
|
62
|
-
"org",
|
|
63
|
-
"net",
|
|
64
|
-
"io",
|
|
65
|
-
"dev",
|
|
66
|
-
"ai",
|
|
67
|
-
"tech",
|
|
68
|
-
"co",
|
|
69
|
-
"app",
|
|
70
|
-
"cloud",
|
|
71
|
-
"sh",
|
|
72
|
-
"run"
|
|
73
|
-
]);
|
|
74
|
-
function extractBrandFromHostname(hostname) {
|
|
75
|
-
const parts = hostname.split(".");
|
|
76
|
-
const meaningfulParts = parts.filter((part) => {
|
|
77
|
-
const lower = part.toLowerCase();
|
|
78
|
-
if (commonTlds.has(lower)) return false;
|
|
79
|
-
if (lower === "mcp" || lower === "api" || lower === "www") return false;
|
|
80
|
-
return true;
|
|
81
|
-
});
|
|
82
|
-
if (meaningfulParts.length > 0) {
|
|
83
|
-
return meaningfulParts[0];
|
|
84
|
-
}
|
|
85
|
-
if (parts.length >= 2) {
|
|
86
|
-
return parts[parts.length - 2];
|
|
87
|
-
}
|
|
88
|
-
return "mcp-server";
|
|
89
|
-
}
|
|
90
|
-
function inferName(input, type) {
|
|
91
|
-
if (type === "remote") {
|
|
92
|
-
try {
|
|
93
|
-
const url = new URL(input);
|
|
94
|
-
return extractBrandFromHostname(url.hostname);
|
|
95
|
-
} catch {
|
|
96
|
-
return "mcp-server";
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (type === "command") {
|
|
100
|
-
const parts = input.split(" ");
|
|
101
|
-
let startIndex = 0;
|
|
102
|
-
if (parts[0] === "npx" || parts[0] === "node" || parts[0] === "python") {
|
|
103
|
-
startIndex = 1;
|
|
104
|
-
}
|
|
105
|
-
for (let i = startIndex; i < parts.length; i++) {
|
|
106
|
-
const part = parts[i];
|
|
107
|
-
if (part && !part.startsWith("-")) {
|
|
108
|
-
return extractPackageName(part);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return "mcp-server";
|
|
112
|
-
}
|
|
113
|
-
return extractPackageName(input);
|
|
114
|
-
}
|
|
115
|
-
function extractPackageName(input) {
|
|
116
|
-
let name = input;
|
|
117
|
-
const atIndex = name.lastIndexOf("@");
|
|
118
|
-
if (atIndex > 0 && !name.startsWith("@")) {
|
|
119
|
-
name = name.slice(0, atIndex);
|
|
120
|
-
} else if (name.startsWith("@") && name.indexOf("@", 1) > 0) {
|
|
121
|
-
const secondAt = name.indexOf("@", 1);
|
|
122
|
-
name = name.slice(0, secondAt);
|
|
123
|
-
}
|
|
124
|
-
if (name.startsWith("@") && name.includes("/")) {
|
|
125
|
-
const parts = name.split("/");
|
|
126
|
-
name = parts[1] || name;
|
|
127
|
-
}
|
|
128
|
-
name = name.replace(/^mcp-server-/, "");
|
|
129
|
-
name = name.replace(/^server-/, "");
|
|
130
|
-
name = name.replace(/-mcp$/, "");
|
|
131
|
-
return name || "mcp-server";
|
|
132
|
-
}
|
|
133
|
-
function parseSource(input) {
|
|
134
|
-
const trimmed = input.trim();
|
|
135
|
-
if (isUrl(trimmed)) {
|
|
136
|
-
return {
|
|
137
|
-
type: "remote",
|
|
138
|
-
value: trimmed,
|
|
139
|
-
inferredName: inferName(trimmed, "remote")
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
if (isCommand(trimmed)) {
|
|
143
|
-
return {
|
|
144
|
-
type: "command",
|
|
145
|
-
value: trimmed,
|
|
146
|
-
inferredName: inferName(trimmed, "command")
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
if (isPackageName(trimmed)) {
|
|
150
|
-
return {
|
|
151
|
-
type: "package",
|
|
152
|
-
value: trimmed,
|
|
153
|
-
inferredName: inferName(trimmed, "package")
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
type: "package",
|
|
158
|
-
value: trimmed,
|
|
159
|
-
inferredName: inferName(trimmed, "package")
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
function isRemoteSource(parsed) {
|
|
163
|
-
return parsed.type === "remote";
|
|
164
|
-
}
|
|
165
|
-
|
|
166
40
|
// src/find.ts
|
|
167
41
|
import * as p from "@clack/prompts";
|
|
168
42
|
|
|
@@ -906,7 +780,7 @@ async function runFind(query, options) {
|
|
|
906
780
|
// package.json
|
|
907
781
|
var package_default = {
|
|
908
782
|
name: "add-mcp",
|
|
909
|
-
version: "1.10.
|
|
783
|
+
version: "1.10.2",
|
|
910
784
|
description: "Add MCP servers to your favorite coding agents with a single command.",
|
|
911
785
|
author: "Andre Landgraf <andre@neon.tech>",
|
|
912
786
|
license: "Apache-2.0",
|
|
@@ -1823,7 +1697,7 @@ async function main(target, options) {
|
|
|
1823
1697
|
if (headerResult.invalid.length > 0) {
|
|
1824
1698
|
const hint = looksLikeEatenShellVar(headerResult.invalid, ":") ? " (looks like your shell expanded a ${VAR} to an empty string; use single quotes: --header 'Key: ${VAR}' to pass the template literally)" : "";
|
|
1825
1699
|
p2.log.error(
|
|
1826
|
-
`Invalid --header value(s): ${headerResult.invalid.join(", ")}. Use
|
|
1700
|
+
`Invalid --header value(s): ${headerResult.invalid.join(", ")}. Use 'Key: Value' format.${hint}`
|
|
1827
1701
|
);
|
|
1828
1702
|
process.exit(1);
|
|
1829
1703
|
}
|
|
@@ -1837,7 +1711,7 @@ async function main(target, options) {
|
|
|
1837
1711
|
if (envResult.invalid.length > 0) {
|
|
1838
1712
|
const hint = looksLikeEatenShellVar(envResult.invalid, "=") ? " (looks like your shell expanded a ${VAR} to an empty string; use single quotes: --env 'KEY=${VAR}' to pass the template literally)" : "";
|
|
1839
1713
|
p2.log.error(
|
|
1840
|
-
`Invalid --env value(s): ${envResult.invalid.join(", ")}. Use
|
|
1714
|
+
`Invalid --env value(s): ${envResult.invalid.join(", ")}. Use 'KEY=VALUE' format.${hint}`
|
|
1841
1715
|
);
|
|
1842
1716
|
process.exit(1);
|
|
1843
1717
|
}
|
package/dist/lib.js
CHANGED