@evantahler/mcpcli 0.7.0 → 0.7.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.
@@ -73,6 +73,7 @@ mcpcli deauth <server> # remove stored auth
73
73
  | Command | Purpose |
74
74
  | -------------------------------------- | --------------------------------- |
75
75
  | `mcpcli` | List all servers and tools |
76
+ | `mcpcli servers` | List servers (name, type, detail) |
76
77
  | `mcpcli -d` | List with descriptions |
77
78
  | `mcpcli info <server>` | Show tools for a server |
78
79
  | `mcpcli info <server> <tool>` | Show tool schema |
package/README.md CHANGED
@@ -52,6 +52,7 @@ mcpcli search -q "manage pull requests"
52
52
  | Command | Description |
53
53
  | -------------------------------------- | -------------------------------------------- |
54
54
  | `mcpcli` | List all configured servers and tools |
55
+ | `mcpcli servers` | List configured servers (name, type, detail) |
55
56
  | `mcpcli info <server>` | Show tools for a server |
56
57
  | `mcpcli info <server> <tool>` | Show tool schema |
57
58
  | `mcpcli search <query>` | Search tools (keyword + semantic) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evantahler/mcpcli",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "A command-line interface for MCP servers. curl for MCP.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.ts CHANGED
@@ -13,6 +13,7 @@ import { registerSkillCommand } from "./commands/skill.ts";
13
13
  import { registerPingCommand } from "./commands/ping.ts";
14
14
  import { registerResourceCommand } from "./commands/resource.ts";
15
15
  import { registerPromptCommand } from "./commands/prompt.ts";
16
+ import { registerServersCommand } from "./commands/servers.ts";
16
17
 
17
18
  declare const BUILD_VERSION: string | undefined;
18
19
 
@@ -41,5 +42,25 @@ registerSkillCommand(program);
41
42
  registerPingCommand(program);
42
43
  registerResourceCommand(program);
43
44
  registerPromptCommand(program);
45
+ registerServersCommand(program);
46
+
47
+ // Detect unknown subcommands before commander misreports them as "too many arguments"
48
+ const knownCommands = new Set(program.commands.map((c) => c.name()));
49
+ const cliArgs = process.argv.slice(2);
50
+ let firstCommand: string | undefined;
51
+ for (let i = 0; i < cliArgs.length; i++) {
52
+ const a = cliArgs[i];
53
+ if (a === "-c" || a === "--config") {
54
+ i++; // skip the config path value
55
+ continue;
56
+ }
57
+ if (a.startsWith("-")) continue;
58
+ firstCommand = a;
59
+ break;
60
+ }
61
+ if (firstCommand && !knownCommands.has(firstCommand)) {
62
+ console.error(`error: unknown command '${firstCommand}'. See 'mcpcli --help'.`);
63
+ process.exit(1);
64
+ }
44
65
 
45
66
  program.parse();
@@ -0,0 +1,58 @@
1
+ import { cyan, dim, green, yellow } from "ansis";
2
+ import type { Command } from "commander";
3
+ import { getContext } from "../context.ts";
4
+ import { isStdioServer } from "../config/schemas.ts";
5
+ import { formatError, isInteractive } from "../output/formatter.ts";
6
+
7
+ export function registerServersCommand(program: Command) {
8
+ program
9
+ .command("servers")
10
+ .description("List configured MCP servers")
11
+ .action(async () => {
12
+ const { manager, config, formatOptions } = await getContext(program);
13
+ try {
14
+ const servers = Object.entries(config.servers.mcpServers);
15
+
16
+ if (!isInteractive(formatOptions)) {
17
+ console.log(
18
+ JSON.stringify(
19
+ servers.map(([name, cfg]) => ({
20
+ name,
21
+ type: isStdioServer(cfg) ? "stdio" : "http",
22
+ ...(isStdioServer(cfg)
23
+ ? { command: cfg.command, args: cfg.args ?? [] }
24
+ : { url: cfg.url }),
25
+ })),
26
+ null,
27
+ 2,
28
+ ),
29
+ );
30
+ return;
31
+ }
32
+
33
+ if (servers.length === 0) {
34
+ console.log(dim("No servers configured"));
35
+ return;
36
+ }
37
+
38
+ const maxName = Math.max(...servers.map(([n]) => n.length));
39
+ const maxType = 5; // "stdio" / "http "
40
+
41
+ for (const [name, cfg] of servers) {
42
+ const n = cyan(name.padEnd(maxName));
43
+ const type = isStdioServer(cfg)
44
+ ? green("stdio".padEnd(maxType))
45
+ : yellow("http ".padEnd(maxType));
46
+ const detail = isStdioServer(cfg)
47
+ ? dim([cfg.command, ...(cfg.args ?? [])].join(" "))
48
+ : dim(cfg.url);
49
+ console.log(`${n} ${type} ${detail}`);
50
+ }
51
+ } catch (err) {
52
+ console.error(formatError(String(err), formatOptions));
53
+ process.exit(1);
54
+ } finally {
55
+ await manager.close();
56
+ }
57
+ });
58
+ }