@wuyax/mcps 0.1.0-beta.1

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.d.cts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/cli.js ADDED
@@ -0,0 +1,228 @@
1
+ import {
2
+ getMcpAgentTypes,
3
+ installMcpServer,
4
+ listInstalledMcpServers,
5
+ logger,
6
+ mainMenu,
7
+ parseMcpAgentList,
8
+ parseMcpSource,
9
+ removeMcpServer,
10
+ resolveTargetAgents,
11
+ toErrorMessage,
12
+ wizardAdd,
13
+ wizardRemove
14
+ } from "./chunk-XW2KL6W3.js";
15
+
16
+ // src/cli.ts
17
+ import { Command as Command4 } from "commander";
18
+
19
+ // src/cli/add.ts
20
+ import { Command } from "commander";
21
+ import pc from "picocolors";
22
+
23
+ // src/utils/format-agent-list.ts
24
+ var formatAgentList = (agentList, emptyLabel = "(none)") => agentList.length === 0 ? emptyLabel : agentList.join(", ");
25
+
26
+ // src/cli/add.ts
27
+ var parseKeyValueList = (entries, separator) => {
28
+ if (!entries || entries.length === 0) return {};
29
+ const result = {};
30
+ for (const entry of entries) {
31
+ const splitIndex = entry.indexOf(separator);
32
+ if (splitIndex === -1) {
33
+ throw new Error(`Invalid entry "${entry}": expected "${separator}" separator`);
34
+ }
35
+ const key = entry.slice(0, splitIndex).trim();
36
+ const value = entry.slice(splitIndex + separator.length).trim();
37
+ if (!key) throw new Error(`Invalid entry "${entry}": empty key`);
38
+ result[key] = value;
39
+ }
40
+ return result;
41
+ };
42
+ var resolveTransport = (input) => {
43
+ if (!input) return void 0;
44
+ if (input === "http" || input === "sse") return input;
45
+ throw new Error(`Unsupported transport "${input}" (expected: http, sse)`);
46
+ };
47
+ 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) => {
48
+ try {
49
+ const isInteractive = Boolean(process.stdin.isTTY && !options.yes);
50
+ if (!source) {
51
+ if (isInteractive) {
52
+ const success = await wizardAdd({
53
+ name: options.name,
54
+ global: options.global,
55
+ args: options.args,
56
+ transport: resolveTransport(options.transport),
57
+ headers: parseKeyValueList(options.header, ":"),
58
+ env: parseKeyValueList(options.env, "="),
59
+ agents: options.all ? getMcpAgentTypes() : parseMcpAgentList(options.agent)
60
+ });
61
+ if (!success) process.exitCode = 1;
62
+ return;
63
+ }
64
+ logger.error('Missing required argument: "source" (e.g. mcps add @modelcontextprotocol/server-filesystem)');
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+ const parsed = parseMcpSource(source);
69
+ const cwd = process.cwd();
70
+ const isGlobal = Boolean(options.global);
71
+ const explicitTransport = resolveTransport(options.transport);
72
+ const transport = explicitTransport ?? (parsed.type === "remote" ? "http" : "stdio");
73
+ const resolvedTargets = resolveTargetAgents({
74
+ requested: options.agent,
75
+ all: options.all,
76
+ global: isGlobal,
77
+ cwd,
78
+ transport
79
+ });
80
+ if (resolvedTargets.agents.length === 0) {
81
+ const message = resolvedTargets.diagnostic ?? `No ${isGlobal ? "global" : "project"}-installed MCP agents detected. Pass ${pc.cyan("-a <agent>")} (e.g. ${pc.cyan("-a cursor")}) or ${pc.cyan("--all")} to install.`;
82
+ logger.warn(message);
83
+ process.exitCode = 1;
84
+ return;
85
+ }
86
+ if (resolvedTargets.isDetected) {
87
+ logger.info(
88
+ `Detected ${isGlobal ? "global" : "project"} agents: ${pc.cyan(formatAgentList(resolvedTargets.detected, "(none detected)"))}`
89
+ );
90
+ if (resolvedTargets.incompatible.length > 0) {
91
+ const skippedList = resolvedTargets.incompatible.map((item) => `${item.agent} (${item.reason})`).join(", ");
92
+ logger.info(
93
+ `Skipping detected agents incompatible with ${transport}: ${pc.yellow(skippedList)}`
94
+ );
95
+ }
96
+ }
97
+ const targetAgents = resolvedTargets.isDetected ? resolvedTargets.agents : resolvedTargets.allAgents;
98
+ const result = installMcpServer({
99
+ source,
100
+ name: options.name,
101
+ agents: targetAgents,
102
+ args: options.args,
103
+ global: isGlobal,
104
+ cwd,
105
+ transport: explicitTransport,
106
+ headers: parseKeyValueList(options.header, ":"),
107
+ env: parseKeyValueList(options.env, "=")
108
+ });
109
+ logger.info(
110
+ `Installing ${pc.bold(result.serverName)} (${pc.cyan(parsed.type)}) to ${pc.cyan(String(result.results.length))} agent(s)`
111
+ );
112
+ for (const record of result.results) {
113
+ if (record.success) {
114
+ logger.success(`${pc.cyan(record.agent)} ${pc.dim(record.path)}`);
115
+ } else {
116
+ logger.error(`${pc.cyan(record.agent)}: ${record.error}`);
117
+ }
118
+ }
119
+ if (result.results.some((record) => !record.success)) process.exitCode = 1;
120
+ } catch (error) {
121
+ logger.error(toErrorMessage(error));
122
+ process.exitCode = 1;
123
+ }
124
+ });
125
+
126
+ // src/cli/list.ts
127
+ import { Command as Command2 } from "commander";
128
+ import pc2 from "picocolors";
129
+ var mcpListCommand = new Command2("list").alias("ls").description("List installed MCP servers across agents").option("-g, --global", "List global configs instead of project").option("-a, --agent <agents...>", "Filter by specific agents").option("--json", "Output as JSON").action((options) => {
130
+ try {
131
+ const entries = listInstalledMcpServers({
132
+ global: Boolean(options.global),
133
+ cwd: process.cwd(),
134
+ agents: parseMcpAgentList(options.agent)
135
+ });
136
+ if (options.json) {
137
+ console.log(JSON.stringify(entries, null, 2));
138
+ return;
139
+ }
140
+ if (entries.length === 0) {
141
+ logger.warn("No MCP servers installed");
142
+ return;
143
+ }
144
+ const grouped = /* @__PURE__ */ new Map();
145
+ for (const entry of entries) {
146
+ const existing = grouped.get(entry.serverName) ?? [];
147
+ existing.push(entry);
148
+ grouped.set(entry.serverName, existing);
149
+ }
150
+ for (const [serverName, group] of grouped) {
151
+ const agentLabels = group.map((record) => record.agent).join(", ");
152
+ console.log(` ${pc2.bold(serverName)} ${pc2.dim(`[${agentLabels}]`)}`);
153
+ const firstPath = group[0]?.path;
154
+ if (firstPath) console.log(` ${pc2.dim(firstPath)}`);
155
+ }
156
+ } catch (error) {
157
+ logger.error(toErrorMessage(error));
158
+ process.exitCode = 1;
159
+ }
160
+ });
161
+
162
+ // src/cli/remove.ts
163
+ import { Command as Command3 } from "commander";
164
+ import pc3 from "picocolors";
165
+ 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) => {
166
+ try {
167
+ const isInteractive = Boolean(process.stdin.isTTY && !options.yes);
168
+ if (!name) {
169
+ if (isInteractive) {
170
+ const success = await wizardRemove({
171
+ global: options.global,
172
+ agents: parseMcpAgentList(options.agent)
173
+ });
174
+ if (!success) process.exitCode = 1;
175
+ return;
176
+ }
177
+ logger.error('Missing required argument: "name" (e.g. mcps remove server-filesystem)');
178
+ process.exitCode = 1;
179
+ return;
180
+ }
181
+ const results = removeMcpServer({
182
+ name,
183
+ agents: parseMcpAgentList(options.agent),
184
+ global: Boolean(options.global),
185
+ cwd: process.cwd()
186
+ });
187
+ if (results.length === 0) {
188
+ logger.warn(`No agent config contained ${pc3.bold(name)}`);
189
+ return;
190
+ }
191
+ for (const record of results) {
192
+ if (record.removed) {
193
+ logger.success(
194
+ `${pc3.cyan(record.agent)} removed ${pc3.bold(name)} ${pc3.dim(record.path)}`
195
+ );
196
+ } else {
197
+ logger.error(`${pc3.cyan(record.agent)}: ${record.error ?? "not found"}`);
198
+ }
199
+ }
200
+ } catch (error) {
201
+ logger.error(toErrorMessage(error));
202
+ process.exitCode = 1;
203
+ }
204
+ });
205
+
206
+ // src/cli.ts
207
+ var VERSION = "0.1.0-beta.1";
208
+ process.on("SIGINT", () => process.exit(0));
209
+ process.on("SIGTERM", () => process.exit(0));
210
+ 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");
211
+ program.addCommand(mcpAddCommand);
212
+ program.addCommand(mcpListCommand);
213
+ program.addCommand(mcpRemoveCommand);
214
+ var main = async () => {
215
+ if (process.argv.length <= 2 && process.stdin.isTTY) {
216
+ try {
217
+ await mainMenu();
218
+ return;
219
+ } catch (error) {
220
+ if (error?.name === "ExitPromptError") {
221
+ process.exit(0);
222
+ }
223
+ throw error;
224
+ }
225
+ }
226
+ await program.parseAsync();
227
+ };
228
+ main();