@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/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
- wizardAdd,
15
- wizardRemove
16
- } from "./chunk-7V5XL4RI.js";
21
+ updateMcpServer
22
+ } from "./chunk-O3BRJFEC.js";
17
23
 
18
24
  // src/cli.ts
19
- import { Command as Command4 } from "commander";
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/cli/add.ts
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/remove.ts
175
+ // src/cli/manage.ts
150
176
  import { Command as Command3 } from "commander";
151
177
  import pc3 from "picocolors";
152
- var mcpRemoveCommand = new Command3("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) => {
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 ${pc3.bold(name)}`);
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
- `${pc3.cyan(record.agent)} removed ${pc3.bold(name)} ${pc3.dim(record.path)}`
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(`${pc3.cyan(record.agent)}: ${record.error ?? "not found"}`);
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-beta.2";
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 Command4().name("mcps").description("Install, list, and remove MCP servers across AI coding agents").version(VERSION, "-v, --version", "display the version number");
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);