@wuyax/mcps 0.1.0-beta.2 → 0.1.0
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/LICENSE +21 -0
- package/README.md +244 -20
- package/dist/chunk-AWD3VQ3S.js +1624 -0
- package/dist/chunk-O3BRJFEC.js +1898 -0
- package/dist/cli.cjs +1553 -852
- package/dist/cli.js +186 -16
- package/dist/index.cjs +678 -1755
- package/dist/index.d.cts +162 -299
- package/dist/index.d.ts +162 -299
- package/dist/index.js +29 -74
- package/dist/{chunk-7V5XL4RI.js → interactive.cjs} +1649 -1172
- package/dist/interactive.d.cts +228 -0
- package/dist/interactive.d.ts +228 -0
- package/dist/interactive.js +53 -0
- package/dist/types-lEP3zGvf.d.cts +128 -0
- package/dist/types-lEP3zGvf.d.ts +128 -0
- package/package.json +33 -1
package/dist/cli.js
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
|
+
displayServerDetails,
|
|
3
|
+
logCoHostedNotice,
|
|
4
|
+
logger,
|
|
5
|
+
mainMenu,
|
|
6
|
+
wizardAdd,
|
|
7
|
+
wizardManage,
|
|
8
|
+
wizardRemove
|
|
9
|
+
} from "./chunk-AWD3VQ3S.js";
|
|
10
|
+
import {
|
|
11
|
+
applyServerConfigDelta,
|
|
2
12
|
getMcpAgentTypes,
|
|
3
13
|
installMcpServer,
|
|
4
14
|
listInstalledMcpServers,
|
|
5
|
-
logger,
|
|
6
|
-
mainMenu,
|
|
7
|
-
mcpManageCommand,
|
|
8
|
-
parseKeyValueList,
|
|
9
15
|
parseMcpAgentList,
|
|
10
16
|
parseMcpSource,
|
|
17
|
+
queryGroupedInstalledServers,
|
|
11
18
|
removeMcpServer,
|
|
12
19
|
resolveTargetAgents,
|
|
13
20
|
toErrorMessage,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "./chunk-7V5XL4RI.js";
|
|
21
|
+
updateMcpServer
|
|
22
|
+
} from "./chunk-O3BRJFEC.js";
|
|
17
23
|
|
|
18
24
|
// src/cli.ts
|
|
19
|
-
import { Command as
|
|
25
|
+
import { Command as Command5 } from "commander";
|
|
20
26
|
|
|
21
27
|
// src/cli/add.ts
|
|
22
28
|
import { Command } from "commander";
|
|
@@ -25,12 +31,31 @@ import pc from "picocolors";
|
|
|
25
31
|
// src/utils/format-agent-list.ts
|
|
26
32
|
var formatAgentList = (agentList, emptyLabel = "(none)") => agentList.length === 0 ? emptyLabel : agentList.join(", ");
|
|
27
33
|
|
|
28
|
-
// src/
|
|
34
|
+
// src/utils/parse-key-value-list.ts
|
|
35
|
+
var parseKeyValueList = (entries, separator) => {
|
|
36
|
+
if (!entries || entries.length === 0) return {};
|
|
37
|
+
const result = {};
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
const splitIndex = entry.indexOf(separator);
|
|
40
|
+
if (splitIndex === -1) {
|
|
41
|
+
throw new Error(`Invalid entry "${entry}": expected "${separator}" separator`);
|
|
42
|
+
}
|
|
43
|
+
const key = entry.slice(0, splitIndex).trim();
|
|
44
|
+
const value = entry.slice(splitIndex + separator.length).trim();
|
|
45
|
+
if (!key) throw new Error(`Invalid entry "${entry}": empty key`);
|
|
46
|
+
result[key] = value;
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/utils/resolve-transport.ts
|
|
29
52
|
var resolveTransport = (input) => {
|
|
30
53
|
if (!input) return void 0;
|
|
31
54
|
if (input === "http" || input === "sse") return input;
|
|
32
55
|
throw new Error(`Unsupported transport "${input}" (expected: http, sse)`);
|
|
33
56
|
};
|
|
57
|
+
|
|
58
|
+
// src/cli/add.ts
|
|
34
59
|
var mcpAddCommand = new Command("add").description("Add an MCP server to coding agents").argument("[source]", "Remote URL, npm package, or command line").option("-a, --agent <agents...>", "Target specific agents (use '*' for all)").option("-g, --global", "Install to user-level config instead of project").option("-t, --transport <type>", "Transport type for remote servers (http or sse)").option("--header <header...>", "HTTP header (Key: Value), repeatable").option("--env <env...>", "Env var for stdio servers (KEY=VALUE), repeatable").option("--args <args...>", "CLI arguments for stdio/package servers").option("-n, --name <name>", "Server name override").option("-y, --yes", "Skip all prompts").option("--all", "Install to all supported agents").action(async (source, options) => {
|
|
35
60
|
try {
|
|
36
61
|
const isInteractive = Boolean(process.stdin.isTTY && !options.yes);
|
|
@@ -99,6 +124,7 @@ var mcpAddCommand = new Command("add").description("Add an MCP server to coding
|
|
|
99
124
|
for (const record of result.results) {
|
|
100
125
|
if (record.success) {
|
|
101
126
|
logger.success(`${pc.cyan(record.agent)} ${pc.dim(record.path)}`);
|
|
127
|
+
logCoHostedNotice("configured", record.coConfiguredAgents);
|
|
102
128
|
} else {
|
|
103
129
|
logger.error(`${pc.cyan(record.agent)}: ${record.error}`);
|
|
104
130
|
}
|
|
@@ -146,10 +172,153 @@ var mcpListCommand = new Command2("list").alias("ls").description("List installe
|
|
|
146
172
|
}
|
|
147
173
|
});
|
|
148
174
|
|
|
149
|
-
// src/cli/
|
|
175
|
+
// src/cli/manage.ts
|
|
150
176
|
import { Command as Command3 } from "commander";
|
|
151
177
|
import pc3 from "picocolors";
|
|
152
|
-
var
|
|
178
|
+
var requireTargetServerGroup = (serverName, scope) => {
|
|
179
|
+
const grouped = queryGroupedInstalledServers(scope);
|
|
180
|
+
const targetGroup = grouped.get(serverName);
|
|
181
|
+
if (!targetGroup) {
|
|
182
|
+
logger.error(
|
|
183
|
+
`MCP server "${serverName}" is not configured in ${scope.global ? "global" : "project"} scope.`
|
|
184
|
+
);
|
|
185
|
+
process.exitCode = 1;
|
|
186
|
+
return void 0;
|
|
187
|
+
}
|
|
188
|
+
return targetGroup;
|
|
189
|
+
};
|
|
190
|
+
var mcpManageCommand = new Command3("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("--clear-headers", "Clear all HTTP headers for remote servers").option("--env <env...>", "Env var for stdio servers (KEY=VALUE), repeatable").option("--clear-env", "Clear all environment variables for stdio servers").option("--args <args...>", "CLI arguments for stdio/package servers").option("--clear-args", "Clear all 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) => {
|
|
191
|
+
try {
|
|
192
|
+
const cwd = process.cwd();
|
|
193
|
+
const isGlobal = Boolean(options.global);
|
|
194
|
+
const hasModifications = options.command !== void 0 || options.args !== void 0 || Boolean(options.clearArgs) || options.env !== void 0 || Boolean(options.clearEnv) || options.header !== void 0 || Boolean(options.clearHeaders) || options.url !== void 0 || options.transport !== void 0;
|
|
195
|
+
const isInteractive = Boolean(process.stdin.isTTY && !options.yes);
|
|
196
|
+
if (hasModifications) {
|
|
197
|
+
if (!serverName) {
|
|
198
|
+
logger.error('Missing required argument: "server-name" when passing modification flags.');
|
|
199
|
+
process.exitCode = 1;
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const targetGroup = requireTargetServerGroup(serverName, { global: isGlobal, cwd });
|
|
203
|
+
if (!targetGroup) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const parsedEnv = options.env !== void 0 ? parseKeyValueList(options.env, "=") : void 0;
|
|
207
|
+
const parsedHeaders = options.header !== void 0 ? parseKeyValueList(options.header, ":") : void 0;
|
|
208
|
+
let deltaResult;
|
|
209
|
+
try {
|
|
210
|
+
deltaResult = applyServerConfigDelta(targetGroup.config, {
|
|
211
|
+
command: options.command,
|
|
212
|
+
args: options.args,
|
|
213
|
+
clearArgs: options.clearArgs,
|
|
214
|
+
env: parsedEnv,
|
|
215
|
+
clearEnv: options.clearEnv,
|
|
216
|
+
url: options.url,
|
|
217
|
+
transport: resolveTransport(options.transport),
|
|
218
|
+
headers: parsedHeaders,
|
|
219
|
+
clearHeaders: options.clearHeaders
|
|
220
|
+
});
|
|
221
|
+
} catch (error) {
|
|
222
|
+
logger.error(toErrorMessage(error));
|
|
223
|
+
process.exitCode = 1;
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (deltaResult.ignoredFlags.length > 0) {
|
|
227
|
+
const isRemote = deltaResult.protocol === "remote";
|
|
228
|
+
const hint = isRemote ? options.url !== void 0 ? "When configuring a remote server, stdio flags are ignored." : "Use --command to switch to stdio mode." : options.command !== void 0 ? "When configuring a stdio server, remote flags are ignored." : "Use --url to switch to remote mode.";
|
|
229
|
+
logger.warn(
|
|
230
|
+
`Server "${serverName}" is a ${isRemote ? "remote" : "stdio"} server. The following ${isRemote ? "stdio" : "remote"} flags will be ignored: ${deltaResult.ignoredFlags.join(", ")}. ${hint}`
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
const incomingDelta = deltaResult.config;
|
|
234
|
+
let targetAgents = targetGroup.agents;
|
|
235
|
+
if (options.agent !== void 0) {
|
|
236
|
+
const parsed = parseMcpAgentList(options.agent);
|
|
237
|
+
if (!parsed || parsed.length === 0) {
|
|
238
|
+
logger.error(`No valid agents recognized from: "${options.agent.join(", ")}".`);
|
|
239
|
+
process.exitCode = 1;
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
targetAgents = parsed;
|
|
243
|
+
}
|
|
244
|
+
const updateResult = updateMcpServer({
|
|
245
|
+
serverName,
|
|
246
|
+
config: incomingDelta,
|
|
247
|
+
previousConfig: targetGroup.config,
|
|
248
|
+
agents: targetAgents,
|
|
249
|
+
global: isGlobal,
|
|
250
|
+
cwd
|
|
251
|
+
});
|
|
252
|
+
for (const item of updateResult.incompatible) {
|
|
253
|
+
logger.warn(`Skipping ${pc3.cyan(item.agent)}: ${item.reason}`);
|
|
254
|
+
}
|
|
255
|
+
const attemptedResults = updateResult.results.filter(
|
|
256
|
+
(r) => !updateResult.incompatible.some((i) => i.agent === r.agent)
|
|
257
|
+
);
|
|
258
|
+
if (attemptedResults.length === 0) {
|
|
259
|
+
const requestedTransport = updateResult.config.url ? updateResult.config.type ?? "http" : "stdio";
|
|
260
|
+
logger.error(
|
|
261
|
+
`None of the target agents support ${requestedTransport} transport. Update aborted.`
|
|
262
|
+
);
|
|
263
|
+
process.exitCode = 1;
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
logger.info(
|
|
267
|
+
`Updating ${pc3.bold(serverName)} across ${pc3.cyan(String(attemptedResults.length))} agent(s)...`
|
|
268
|
+
);
|
|
269
|
+
let allSuccess = true;
|
|
270
|
+
for (const res of attemptedResults) {
|
|
271
|
+
if (res.success) {
|
|
272
|
+
logger.success(`${pc3.cyan(res.agent)}: Successfully updated in ${pc3.dim(res.path)}`);
|
|
273
|
+
logCoHostedNotice("configured", res.coConfiguredAgents);
|
|
274
|
+
} else {
|
|
275
|
+
allSuccess = false;
|
|
276
|
+
logger.error(`${pc3.cyan(res.agent)}: Update failed - ${res.error}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!allSuccess) {
|
|
280
|
+
process.exitCode = 1;
|
|
281
|
+
}
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (!isInteractive) {
|
|
285
|
+
if (!serverName) {
|
|
286
|
+
logger.error(
|
|
287
|
+
'Missing required argument: "server-name" for non-interactive manage command. Specify a server name or use interactive terminal.'
|
|
288
|
+
);
|
|
289
|
+
process.exitCode = 1;
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const targetGroup = requireTargetServerGroup(serverName, { global: isGlobal, cwd });
|
|
293
|
+
if (!targetGroup) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
displayServerDetails({
|
|
297
|
+
serverName,
|
|
298
|
+
config: targetGroup.config,
|
|
299
|
+
agents: targetGroup.agents,
|
|
300
|
+
global: isGlobal,
|
|
301
|
+
hasDivergence: targetGroup.hasDivergence
|
|
302
|
+
});
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
await wizardManage({
|
|
306
|
+
global: options.global,
|
|
307
|
+
serverName
|
|
308
|
+
});
|
|
309
|
+
} catch (error) {
|
|
310
|
+
if (error && typeof error === "object" && "name" in error && error.name === "ExitPromptError") {
|
|
311
|
+
process.exit(0);
|
|
312
|
+
}
|
|
313
|
+
logger.error(toErrorMessage(error));
|
|
314
|
+
process.exitCode = 1;
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// src/cli/remove.ts
|
|
319
|
+
import { Command as Command4 } from "commander";
|
|
320
|
+
import pc4 from "picocolors";
|
|
321
|
+
var mcpRemoveCommand = new Command4("remove").alias("rm").description("Remove an MCP server from agent configs").argument("[name]", "Server name").option("-g, --global", "Remove from global scope").option("-a, --agent <agents...>", "Filter by specific agents (use '*' for all)").option("-y, --yes", "Skip confirmation prompts").action(async (name, options) => {
|
|
153
322
|
try {
|
|
154
323
|
const isInteractive = Boolean(process.stdin.isTTY && !options.yes);
|
|
155
324
|
if (!name) {
|
|
@@ -172,16 +341,17 @@ var mcpRemoveCommand = new Command3("remove").alias("rm").description("Remove an
|
|
|
172
341
|
cwd: process.cwd()
|
|
173
342
|
});
|
|
174
343
|
if (results.length === 0) {
|
|
175
|
-
logger.warn(`No agent config contained ${
|
|
344
|
+
logger.warn(`No agent config contained ${pc4.bold(name)}`);
|
|
176
345
|
return;
|
|
177
346
|
}
|
|
178
347
|
for (const record of results) {
|
|
179
348
|
if (record.removed) {
|
|
180
349
|
logger.success(
|
|
181
|
-
`${
|
|
350
|
+
`${pc4.cyan(record.agent)} removed ${pc4.bold(name)} ${pc4.dim(record.path)}`
|
|
182
351
|
);
|
|
352
|
+
logCoHostedNotice("affected", record.coAffectedAgents);
|
|
183
353
|
} else {
|
|
184
|
-
logger.error(`${
|
|
354
|
+
logger.error(`${pc4.cyan(record.agent)}: ${record.error ?? "not found"}`);
|
|
185
355
|
}
|
|
186
356
|
}
|
|
187
357
|
} catch (error) {
|
|
@@ -191,10 +361,10 @@ var mcpRemoveCommand = new Command3("remove").alias("rm").description("Remove an
|
|
|
191
361
|
});
|
|
192
362
|
|
|
193
363
|
// src/cli.ts
|
|
194
|
-
var VERSION = "0.1.0
|
|
364
|
+
var VERSION = "0.1.0";
|
|
195
365
|
process.on("SIGINT", () => process.exit(0));
|
|
196
366
|
process.on("SIGTERM", () => process.exit(0));
|
|
197
|
-
var program = new
|
|
367
|
+
var program = new Command5().name("mcps").description("Install, list, and remove MCP servers across AI coding agents").version(VERSION, "-v, --version", "display the version number");
|
|
198
368
|
program.addCommand(mcpAddCommand);
|
|
199
369
|
program.addCommand(mcpListCommand);
|
|
200
370
|
program.addCommand(mcpManageCommand);
|