botholomew 0.8.5 → 0.8.6

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/commands/mcpx.ts +47 -146
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botholomew",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "An autonomous AI agent for knowledge work — works your task queue while you sleep.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,155 +51,64 @@ function getDir(program: Command): string {
51
51
  return program.opts().dir;
52
52
  }
53
53
 
54
+ // Slice process.argv from the token after "mcpx" so flags (including --help)
55
+ // and positional args flow through to upstream mcpx verbatim.
56
+ function getRawMcpxArgs(): string[] {
57
+ const idx = process.argv.indexOf("mcpx");
58
+ return idx === -1 ? [] : process.argv.slice(idx + 1);
59
+ }
60
+
61
+ const PASSTHROUGH_SUBCOMMANDS: ReadonlyArray<[name: string, desc: string]> = [
62
+ ["servers", "List configured MCP server names"],
63
+ ["info", "Show server overview or schema for a specific tool"],
64
+ ["search", "Search tools by keyword and/or semantic similarity"],
65
+ ["exec", "Execute a tool call"],
66
+ ["add", "Add an MCP server"],
67
+ ["remove", "Remove an MCP server"],
68
+ ["ping", "Check connectivity to MCP servers"],
69
+ ["auth", "Authenticate with an HTTP MCP server"],
70
+ ["deauth", "Remove stored authentication for a server"],
71
+ ["resource", "List resources for a server, or read a specific resource"],
72
+ ["prompt", "List prompts for a server, or get a specific prompt"],
73
+ ["task", "Manage async tool tasks (list, get, result, cancel)"],
74
+ ["index", "Build the search index from all configured servers"],
75
+ ];
76
+
54
77
  export function registerMcpxCommand(program: Command) {
55
78
  const mcpx = program
56
79
  .command("mcpx")
57
80
  .description("Manage MCP servers via MCPX");
58
81
 
59
- // --- servers ---
60
- mcpx
61
- .command("servers")
62
- .description("List configured MCP server names")
63
- .action(async () => {
64
- const out = await runMcpx(getDir(program), ["servers"]);
65
- process.stdout.write(out);
66
- });
67
-
68
- // --- info ---
69
- mcpx
70
- .command("info <first> [second]")
71
- .description(
72
- "Show server overview, or schema for a specific tool (server is optional if tool name is unambiguous)",
73
- )
74
- .action(async (first: string, second?: string) => {
75
- const out = await runMcpx(getDir(program), ["info", first, second]);
76
- process.stdout.write(out);
77
- });
78
-
79
- // --- search ---
80
- mcpx
81
- .command("search <terms...>")
82
- .description("Search tools by keyword and/or semantic similarity")
83
- .action(async (terms: string[]) => {
84
- const out = await runMcpx(getDir(program), ["search", ...terms]);
85
- process.stdout.write(out);
86
- });
82
+ for (const [name, description] of PASSTHROUGH_SUBCOMMANDS) {
83
+ mcpx
84
+ .command(name)
85
+ .description(description)
86
+ .allowUnknownOption(true)
87
+ .helpOption(false)
88
+ .argument("[args...]", "arguments forwarded to mcpx")
89
+ .action(async () => {
90
+ await runMcpx(getDir(program), getRawMcpxArgs(), { inherit: true });
91
+ });
92
+ }
87
93
 
88
- // --- exec ---
94
+ // Upstream mcpx's "list" is the default action when invoked with no
95
+ // subcommand — not a registered subcommand — so we strip the "list"
96
+ // token before forwarding.
89
97
  mcpx
90
- .command("exec <first> [second] [third]")
98
+ .command("list")
91
99
  .description(
92
- "Execute a tool call (server is optional if tool name is unambiguous)",
100
+ "List all tools, resources, and prompts across all configured servers",
93
101
  )
94
- .action(async (first: string, second?: string, third?: string) => {
95
- const out = await runMcpx(getDir(program), [
96
- "exec",
97
- first,
98
- second,
99
- third,
100
- ]);
101
- process.stdout.write(out);
102
- });
103
-
104
- // --- add ---
105
- mcpx
106
- .command("add <name>")
107
- .description("Add an MCP server")
108
- .option("--command <cmd>", "Stdio server command")
109
- .option("--args <args...>", "Stdio server arguments")
110
- .option("--url <url>", "HTTP server URL")
111
- .option("--transport <type>", "HTTP transport: sse or streamable-http")
112
- .option("--env <pairs...>", "Environment variables as KEY=VALUE pairs")
113
- .action(
114
- async (
115
- name: string,
116
- opts: {
117
- command?: string;
118
- args?: string[];
119
- url?: string;
120
- transport?: string;
121
- env?: string[];
122
- },
123
- ) => {
124
- const cliArgs: string[] = ["add", name];
125
- if (opts.command) cliArgs.push("--command", opts.command);
126
- if (opts.args) {
127
- for (const a of opts.args) cliArgs.push("--args", a);
128
- }
129
- if (opts.url) cliArgs.push("--url", opts.url);
130
- if (opts.transport) cliArgs.push("--transport", opts.transport);
131
- if (opts.env) {
132
- for (const e of opts.env) cliArgs.push("--env", e);
133
- }
134
- const out = await runMcpx(getDir(program), cliArgs);
135
- process.stdout.write(out);
136
- },
137
- );
138
-
139
- // --- remove ---
140
- mcpx
141
- .command("remove <name>")
142
- .description("Remove an MCP server")
143
- .action(async (name: string) => {
144
- const out = await runMcpx(getDir(program), ["remove", name]);
145
- process.stdout.write(out);
146
- });
147
-
148
- // --- ping ---
149
- mcpx
150
- .command("ping [servers...]")
151
- .description("Check connectivity to MCP servers")
152
- .action(async (servers: string[]) => {
153
- const out = await runMcpx(getDir(program), ["ping", ...servers]);
154
- process.stdout.write(out);
155
- });
156
-
157
- // --- auth ---
158
- mcpx
159
- .command("auth <server>")
160
- .description("Authenticate with an HTTP MCP server")
161
- .action(async (server: string) => {
162
- await runMcpx(getDir(program), ["auth", server], { inherit: true });
163
- });
164
-
165
- // --- resource ---
166
- mcpx
167
- .command("resource [server] [uri]")
168
- .description("List resources for a server, or read a specific resource")
169
- .action(async (server?: string, uri?: string) => {
170
- const out = await runMcpx(getDir(program), ["resource", server, uri]);
171
- process.stdout.write(out);
172
- });
173
-
174
- // --- prompt ---
175
- mcpx
176
- .command("prompt [server] [name] [args]")
177
- .description("List prompts for a server, or get a specific prompt")
178
- .action(async (server?: string, name?: string, argsJson?: string) => {
179
- const out = await runMcpx(getDir(program), [
180
- "prompt",
181
- server,
182
- name,
183
- argsJson,
184
- ]);
185
- process.stdout.write(out);
186
- });
187
-
188
- // --- task ---
189
- mcpx
190
- .command("task <action> <server> [taskId]")
191
- .description("Manage async tasks (actions: list, get, result, cancel)")
192
- .action(async (action: string, server: string, taskId?: string) => {
193
- const out = await runMcpx(getDir(program), [
194
- "task",
195
- action,
196
- server,
197
- taskId,
198
- ]);
199
- process.stdout.write(out);
102
+ .allowUnknownOption(true)
103
+ .helpOption(false)
104
+ .argument("[args...]", "arguments forwarded to mcpx")
105
+ .action(async () => {
106
+ const raw = getRawMcpxArgs();
107
+ const args = raw[0] === "list" ? raw.slice(1) : raw;
108
+ await runMcpx(getDir(program), args, { inherit: true });
200
109
  });
201
110
 
202
- // --- import-global ---
111
+ // Botholomew-specific: copy system-wide MCPX settings into this project.
203
112
  mcpx
204
113
  .command("import-global")
205
114
  .description("Copy system-wide MCPX settings (~/.mcpx) into this project")
@@ -234,12 +143,4 @@ export function registerMcpxCommand(program: Command) {
234
143
  );
235
144
  }
236
145
  });
237
-
238
- // --- index ---
239
- mcpx
240
- .command("index")
241
- .description("Build the search index from all configured servers")
242
- .action(async () => {
243
- await runMcpx(getDir(program), ["index"], { inherit: true });
244
- });
245
146
  }