@modeltoolsprotocol/mtpcli 0.3.1 → 0.3.3

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +339 -293
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -20,7 +20,7 @@ LLM agents need to discover and use tools. Right now there are two worlds:
20
20
  | **Scriptable without an LLM** | Yes, that's the whole point of CLIs | Not really, designed for LLM interaction |
21
21
  | **Adoption cost** | One flag/decorator | New protocol, server scaffolding, SDK |
22
22
 
23
- The gap is discovery. `mtpcli` fills it.
23
+ The gap for CLIs is discovery. `mtpcli` fills it.
24
24
 
25
25
  ## Install
26
26
 
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ var __export = (target, all) => {
27
27
  });
28
28
  };
29
29
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
30
+ var __promiseAll = (args) => Promise.all(args);
30
31
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
31
32
 
32
33
  // node_modules/commander/lib/error.js
@@ -2122,6 +2123,25 @@ var require_commander = __commonJS((exports) => {
2122
2123
  exports.InvalidOptionArgumentError = InvalidArgumentError;
2123
2124
  });
2124
2125
 
2126
+ // node_modules/commander/esm.mjs
2127
+ var import__, program, createCommand, createArgument, createOption, CommanderError, InvalidArgumentError, InvalidOptionArgumentError, Command, Argument, Option, Help;
2128
+ var init_esm = __esm(() => {
2129
+ import__ = __toESM(require_commander(), 1);
2130
+ ({
2131
+ program,
2132
+ createCommand,
2133
+ createArgument,
2134
+ createOption,
2135
+ CommanderError,
2136
+ InvalidArgumentError,
2137
+ InvalidOptionArgumentError,
2138
+ Command,
2139
+ Argument,
2140
+ Option,
2141
+ Help
2142
+ } = import__.default);
2143
+ });
2144
+
2125
2145
  // node_modules/zod/v3/helpers/util.js
2126
2146
  var util, objectUtil, ZodParsedType, getParsedType = (data) => {
2127
2147
  const t = typeof data;
@@ -6088,6 +6108,119 @@ var init_zod = __esm(() => {
6088
6108
  init_external();
6089
6109
  });
6090
6110
 
6111
+ // src/models.ts
6112
+ function cleanJson(obj) {
6113
+ if (obj === null || obj === undefined)
6114
+ return;
6115
+ if (Array.isArray(obj)) {
6116
+ return obj.map(cleanJson);
6117
+ }
6118
+ if (typeof obj === "object") {
6119
+ const out = {};
6120
+ for (const [k, v] of Object.entries(obj)) {
6121
+ if (v === undefined)
6122
+ continue;
6123
+ if (Array.isArray(v) && v.length === 0)
6124
+ continue;
6125
+ const cleaned = cleanJson(v);
6126
+ if (cleaned !== undefined) {
6127
+ out[k] = cleaned;
6128
+ }
6129
+ }
6130
+ return out;
6131
+ }
6132
+ return obj;
6133
+ }
6134
+ var ExampleSchema, ArgSchema, IoDescriptorSchema, CommandAuthSchema, CommandSchema, AuthProviderSchema, AuthConfigSchema, ToolSchemaSchema, StoredTokenSchema, JsonRpcErrorSchema, JsonRpcRequestSchema, JsonRpcResponseSchema, McpToolDefSchema;
6135
+ var init_models = __esm(() => {
6136
+ init_zod();
6137
+ ExampleSchema = exports_external.object({
6138
+ description: exports_external.string().optional(),
6139
+ command: exports_external.string(),
6140
+ output: exports_external.string().optional()
6141
+ });
6142
+ ArgSchema = exports_external.object({
6143
+ name: exports_external.string(),
6144
+ type: exports_external.string(),
6145
+ description: exports_external.string().optional(),
6146
+ required: exports_external.boolean().default(false),
6147
+ default: exports_external.any().optional(),
6148
+ values: exports_external.array(exports_external.string()).optional()
6149
+ });
6150
+ IoDescriptorSchema = exports_external.object({
6151
+ contentType: exports_external.string().optional(),
6152
+ description: exports_external.string().optional(),
6153
+ schema: exports_external.any().optional()
6154
+ });
6155
+ CommandAuthSchema = exports_external.object({
6156
+ required: exports_external.boolean().default(false),
6157
+ scopes: exports_external.array(exports_external.string()).optional()
6158
+ });
6159
+ CommandSchema = exports_external.object({
6160
+ name: exports_external.string(),
6161
+ description: exports_external.string(),
6162
+ args: exports_external.array(ArgSchema).default([]),
6163
+ stdin: IoDescriptorSchema.optional(),
6164
+ stdout: IoDescriptorSchema.optional(),
6165
+ examples: exports_external.array(ExampleSchema).default([]),
6166
+ auth: CommandAuthSchema.optional()
6167
+ });
6168
+ AuthProviderSchema = exports_external.object({
6169
+ id: exports_external.string(),
6170
+ type: exports_external.string(),
6171
+ displayName: exports_external.string().optional(),
6172
+ authorizationUrl: exports_external.string().optional(),
6173
+ tokenUrl: exports_external.string().optional(),
6174
+ scopes: exports_external.array(exports_external.string()).optional(),
6175
+ clientId: exports_external.string().optional(),
6176
+ registrationUrl: exports_external.string().optional(),
6177
+ instructions: exports_external.string().optional()
6178
+ });
6179
+ AuthConfigSchema = exports_external.object({
6180
+ required: exports_external.boolean().default(false),
6181
+ envVar: exports_external.string(),
6182
+ providers: exports_external.array(AuthProviderSchema)
6183
+ });
6184
+ ToolSchemaSchema = exports_external.object({
6185
+ name: exports_external.string(),
6186
+ version: exports_external.string(),
6187
+ description: exports_external.string(),
6188
+ auth: AuthConfigSchema.optional(),
6189
+ commands: exports_external.array(CommandSchema)
6190
+ });
6191
+ StoredTokenSchema = exports_external.object({
6192
+ access_token: exports_external.string(),
6193
+ token_type: exports_external.string().optional(),
6194
+ refresh_token: exports_external.string().optional(),
6195
+ expires_at: exports_external.string().optional(),
6196
+ scopes: exports_external.array(exports_external.string()).optional(),
6197
+ provider_id: exports_external.string(),
6198
+ created_at: exports_external.string()
6199
+ });
6200
+ JsonRpcErrorSchema = exports_external.object({
6201
+ code: exports_external.number(),
6202
+ message: exports_external.string(),
6203
+ data: exports_external.any().optional()
6204
+ });
6205
+ JsonRpcRequestSchema = exports_external.object({
6206
+ jsonrpc: exports_external.string(),
6207
+ id: exports_external.any().optional(),
6208
+ method: exports_external.string(),
6209
+ params: exports_external.any().default({})
6210
+ });
6211
+ JsonRpcResponseSchema = exports_external.object({
6212
+ jsonrpc: exports_external.string(),
6213
+ id: exports_external.any().optional(),
6214
+ result: exports_external.any().optional(),
6215
+ error: JsonRpcErrorSchema.optional()
6216
+ });
6217
+ McpToolDefSchema = exports_external.object({
6218
+ name: exports_external.string(),
6219
+ description: exports_external.string(),
6220
+ inputSchema: exports_external.any()
6221
+ });
6222
+ });
6223
+
6091
6224
  // node_modules/jaro-winkler/index.js
6092
6225
  var require_jaro_winkler = __commonJS((exports, module) => {
6093
6226
  (function(root) {
@@ -6429,7 +6562,7 @@ function jsonRpcError(id, code, message) {
6429
6562
  return { jsonrpc: "2.0", id, error: { code, message } };
6430
6563
  }
6431
6564
  var ExampleSchema2, ArgSchema2, IoDescriptorSchema2, CommandAuthSchema2, CommandSchema2, AuthProviderSchema2, AuthConfigSchema2, ToolSchemaSchema2, StoredTokenSchema2, JsonRpcErrorSchema2, JsonRpcRequestSchema2, JsonRpcResponseSchema2, McpToolDefSchema2;
6432
- var init_models = __esm(() => {
6565
+ var init_models2 = __esm(() => {
6433
6566
  init_zod();
6434
6567
  ExampleSchema2 = exports_external.object({
6435
6568
  description: exports_external.string().optional(),
@@ -6678,7 +6811,7 @@ async function loadSchemas(toolNames) {
6678
6811
  }
6679
6812
  var import_jaro_winkler, import_which, execFileAsync;
6680
6813
  var init_search = __esm(() => {
6681
- init_models();
6814
+ init_models2();
6682
6815
  import_jaro_winkler = __toESM(require_jaro_winkler(), 1);
6683
6816
  import_which = __toESM(require_lib(), 1);
6684
6817
  execFileAsync = promisify(execFile);
@@ -7334,7 +7467,7 @@ async function getToolSchema2(toolName) {
7334
7467
  }
7335
7468
  var import_jaro_winkler2, import_which2, execFileAsync6;
7336
7469
  var init_search2 = __esm(() => {
7337
- init_models();
7470
+ init_models2();
7338
7471
  import_jaro_winkler2 = __toESM(require_jaro_winkler(), 1);
7339
7472
  import_which2 = __toESM(require_lib(), 1);
7340
7473
  execFileAsync6 = promisify8(execFile8);
@@ -8692,7 +8825,7 @@ function readResponse(rl) {
8692
8825
  });
8693
8826
  }
8694
8827
  var init_mcp = __esm(() => {
8695
- init_models();
8828
+ init_models2();
8696
8829
  });
8697
8830
 
8698
8831
  // src/serve.ts
@@ -8738,7 +8871,7 @@ function argToJsonSchema(arg) {
8738
8871
  return schema;
8739
8872
  }
8740
8873
  function commandToMcpTool(toolName, cmd) {
8741
- const mcpName = cmd.name === "_root" ? toolName : `${toolName}__${cmd.name}`;
8874
+ const mcpName = cmd.name === "_root" ? toolName : `${toolName}__${cmd.name.replace(/ /g, "_")}`;
8742
8875
  const properties = {};
8743
8876
  const required = [];
8744
8877
  for (const arg of cmd.args) {
@@ -8772,7 +8905,7 @@ function commandToMcpTool(toolName, cmd) {
8772
8905
  function buildCliCommand(toolName, commandName, arguments_, commandSchema) {
8773
8906
  const cmd = [toolName];
8774
8907
  if (commandName !== "_root")
8775
- cmd.push(commandName);
8908
+ cmd.push(...commandName.split(" "));
8776
8909
  const argSchemas = new Map;
8777
8910
  for (const a of commandSchema.args) {
8778
8911
  argSchemas.set(a.name.replace(/^-+/, ""), a);
@@ -8826,29 +8959,57 @@ function invokeCliTool(toolName, commandName, arguments_, commandSchema, authEnv
8826
8959
  stdio: [stdinStr !== undefined ? "pipe" : "ignore", "pipe", "pipe"],
8827
8960
  env: { ...process.env, ...authEnv }
8828
8961
  });
8962
+ const timer = setTimeout(() => {
8963
+ child.kill();
8964
+ resolve({
8965
+ content: [{ type: "text", text: `Error: tool timed out after ${TOOL_TIMEOUT_MS / 1000}s` }],
8966
+ isError: true
8967
+ });
8968
+ }, TOOL_TIMEOUT_MS);
8829
8969
  if (stdinStr !== undefined && child.stdin) {
8830
8970
  child.stdin.write(stdinStr);
8831
8971
  child.stdin.end();
8832
8972
  }
8833
8973
  let stdout = "";
8834
8974
  let stderr = "";
8835
- child.stdout?.on("data", (d) => stdout += d);
8836
- child.stderr?.on("data", (d) => stderr += d);
8975
+ let stdoutBytes = 0;
8976
+ let stderrBytes = 0;
8977
+ let truncated = false;
8978
+ child.stdout?.on("data", (d) => {
8979
+ stdoutBytes += d.length;
8980
+ if (stdoutBytes <= MAX_OUTPUT_BYTES) {
8981
+ stdout += d;
8982
+ } else if (!truncated) {
8983
+ truncated = true;
8984
+ child.kill();
8985
+ }
8986
+ });
8987
+ child.stderr?.on("data", (d) => {
8988
+ stderrBytes += d.length;
8989
+ if (stderrBytes <= MAX_OUTPUT_BYTES) {
8990
+ stderr += d;
8991
+ }
8992
+ });
8837
8993
  child.on("error", (e) => {
8994
+ clearTimeout(timer);
8838
8995
  resolve({
8839
8996
  content: [{ type: "text", text: `Error: ${e.message}` }],
8840
8997
  isError: true
8841
8998
  });
8842
8999
  });
8843
9000
  child.on("close", (code) => {
9001
+ clearTimeout(timer);
8844
9002
  const content = [];
9003
+ if (truncated) {
9004
+ content.push({ type: "text", text: `[truncated: output exceeded ${MAX_OUTPUT_BYTES / 1024 / 1024}MB]` });
9005
+ }
8845
9006
  if (stdout.trim())
8846
9007
  content.push({ type: "text", text: stdout.trim() });
8847
9008
  if (stderr.trim())
8848
9009
  content.push({ type: "text", text: `[stderr] ${stderr.trim()}` });
8849
9010
  if (content.length === 0)
8850
9011
  content.push({ type: "text", text: "(no output)" });
8851
- resolve({ content, isError: code !== 0 });
9012
+ resolve({ content, isError: code !== 0 || truncated });
8852
9013
  });
8853
9014
  });
8854
9015
  }
@@ -8948,13 +9109,15 @@ async function run(toolNames) {
8948
9109
  }
8949
9110
  }
8950
9111
  }
8951
- var execFileAsync7, VERSION = "0.1.0";
8952
- var init_serve = __esm(() => {
9112
+ var execFileAsync7, TOOL_TIMEOUT_MS = 60000, MAX_OUTPUT_BYTES;
9113
+ var init_serve = __esm(async () => {
8953
9114
  init_auth();
8954
9115
  init_mcp();
8955
- init_models();
9116
+ init_models2();
8956
9117
  init_search2();
9118
+ await init_src();
8957
9119
  execFileAsync7 = promisify9(execFile9);
9120
+ MAX_OUTPUT_BYTES = 1024 * 1024 * 1024;
8958
9121
  });
8959
9122
 
8960
9123
  // src/mcp-oauth.ts
@@ -9521,7 +9684,7 @@ class McpClient {
9521
9684
  client.sendRequest("initialize", {
9522
9685
  protocolVersion: "2024-11-05",
9523
9686
  capabilities: {},
9524
- clientInfo: { name: "mtpcli-wrap", version: VERSION2 }
9687
+ clientInfo: { name: "mtpcli-wrap", version: VERSION }
9525
9688
  });
9526
9689
  await client.readResponse();
9527
9690
  client.sendNotification("notifications/initialized", {});
@@ -9582,7 +9745,7 @@ class HttpMcpClient {
9582
9745
  const initResult = await client.sendRequest("initialize", {
9583
9746
  protocolVersion: "2025-11-25",
9584
9747
  capabilities: {},
9585
- clientInfo: { name: "mtpcli-wrap", version: VERSION2 }
9748
+ clientInfo: { name: "mtpcli-wrap", version: VERSION }
9586
9749
  });
9587
9750
  client.protocolVersion = initResult.protocolVersion ?? "2025-11-25";
9588
9751
  await client.sendNotification("notifications/initialized", {});
@@ -9824,9 +9987,9 @@ async function run2(serverCmd, serverUrl, describeMode, toolName, toolArgs = [],
9824
9987
  client.stop();
9825
9988
  }
9826
9989
  }
9827
- var VERSION2 = "0.1.0";
9828
- var init_wrap = __esm(() => {
9990
+ var init_wrap = __esm(async () => {
9829
9991
  init_mcp();
9992
+ await init_src();
9830
9993
  });
9831
9994
 
9832
9995
  // src/validate.ts
@@ -10050,7 +10213,7 @@ function printHuman(result) {
10050
10213
  }
10051
10214
  var import_which3, execFileAsync8, VALID_ARG_TYPES;
10052
10215
  var init_validate = __esm(() => {
10053
- init_models();
10216
+ init_models2();
10054
10217
  import_which3 = __toESM(require_lib(), 1);
10055
10218
  execFileAsync8 = promisify10(execFile10);
10056
10219
  VALID_ARG_TYPES = new Set([
@@ -10437,138 +10600,11 @@ var init_completions = __esm(() => {
10437
10600
  init_search2();
10438
10601
  });
10439
10602
 
10440
- // node_modules/commander/esm.mjs
10441
- var import__ = __toESM(require_commander(), 1);
10442
- var {
10443
- program,
10444
- createCommand,
10445
- createArgument,
10446
- createOption,
10447
- CommanderError,
10448
- InvalidArgumentError,
10449
- InvalidOptionArgumentError,
10450
- Command,
10451
- Argument,
10452
- Option,
10453
- Help
10454
- } = import__.default;
10455
-
10456
- // src/models.ts
10457
- init_zod();
10458
- var ExampleSchema = exports_external.object({
10459
- description: exports_external.string().optional(),
10460
- command: exports_external.string(),
10461
- output: exports_external.string().optional()
10462
- });
10463
- var ArgSchema = exports_external.object({
10464
- name: exports_external.string(),
10465
- type: exports_external.string(),
10466
- description: exports_external.string().optional(),
10467
- required: exports_external.boolean().default(false),
10468
- default: exports_external.any().optional(),
10469
- values: exports_external.array(exports_external.string()).optional()
10470
- });
10471
- var IoDescriptorSchema = exports_external.object({
10472
- contentType: exports_external.string().optional(),
10473
- description: exports_external.string().optional(),
10474
- schema: exports_external.any().optional()
10475
- });
10476
- var CommandAuthSchema = exports_external.object({
10477
- required: exports_external.boolean().default(false),
10478
- scopes: exports_external.array(exports_external.string()).optional()
10479
- });
10480
- var CommandSchema = exports_external.object({
10481
- name: exports_external.string(),
10482
- description: exports_external.string(),
10483
- args: exports_external.array(ArgSchema).default([]),
10484
- stdin: IoDescriptorSchema.optional(),
10485
- stdout: IoDescriptorSchema.optional(),
10486
- examples: exports_external.array(ExampleSchema).default([]),
10487
- auth: CommandAuthSchema.optional()
10488
- });
10489
- var AuthProviderSchema = exports_external.object({
10490
- id: exports_external.string(),
10491
- type: exports_external.string(),
10492
- displayName: exports_external.string().optional(),
10493
- authorizationUrl: exports_external.string().optional(),
10494
- tokenUrl: exports_external.string().optional(),
10495
- scopes: exports_external.array(exports_external.string()).optional(),
10496
- clientId: exports_external.string().optional(),
10497
- registrationUrl: exports_external.string().optional(),
10498
- instructions: exports_external.string().optional()
10499
- });
10500
- var AuthConfigSchema = exports_external.object({
10501
- required: exports_external.boolean().default(false),
10502
- envVar: exports_external.string(),
10503
- providers: exports_external.array(AuthProviderSchema)
10504
- });
10505
- var ToolSchemaSchema = exports_external.object({
10506
- name: exports_external.string(),
10507
- version: exports_external.string(),
10508
- description: exports_external.string(),
10509
- auth: AuthConfigSchema.optional(),
10510
- commands: exports_external.array(CommandSchema)
10511
- });
10512
- var StoredTokenSchema = exports_external.object({
10513
- access_token: exports_external.string(),
10514
- token_type: exports_external.string().optional(),
10515
- refresh_token: exports_external.string().optional(),
10516
- expires_at: exports_external.string().optional(),
10517
- scopes: exports_external.array(exports_external.string()).optional(),
10518
- provider_id: exports_external.string(),
10519
- created_at: exports_external.string()
10520
- });
10521
- var JsonRpcErrorSchema = exports_external.object({
10522
- code: exports_external.number(),
10523
- message: exports_external.string(),
10524
- data: exports_external.any().optional()
10525
- });
10526
- var JsonRpcRequestSchema = exports_external.object({
10527
- jsonrpc: exports_external.string(),
10528
- id: exports_external.any().optional(),
10529
- method: exports_external.string(),
10530
- params: exports_external.any().default({})
10531
- });
10532
- var JsonRpcResponseSchema = exports_external.object({
10533
- jsonrpc: exports_external.string(),
10534
- id: exports_external.any().optional(),
10535
- result: exports_external.any().optional(),
10536
- error: JsonRpcErrorSchema.optional()
10537
- });
10538
- var McpToolDefSchema = exports_external.object({
10539
- name: exports_external.string(),
10540
- description: exports_external.string(),
10541
- inputSchema: exports_external.any()
10542
- });
10543
- function cleanJson(obj) {
10544
- if (obj === null || obj === undefined)
10545
- return;
10546
- if (Array.isArray(obj)) {
10547
- return obj.map(cleanJson);
10548
- }
10549
- if (typeof obj === "object") {
10550
- const out = {};
10551
- for (const [k, v] of Object.entries(obj)) {
10552
- if (v === undefined)
10553
- continue;
10554
- if (Array.isArray(v) && v.length === 0)
10555
- continue;
10556
- const cleaned = cleanJson(v);
10557
- if (cleaned !== undefined) {
10558
- out[k] = cleaned;
10559
- }
10560
- }
10561
- return out;
10562
- }
10563
- return obj;
10564
- }
10565
-
10566
10603
  // src/index.ts
10567
- var VERSION3 = "0.3.1";
10568
10604
  function selfDescribe() {
10569
10605
  const schema = {
10570
10606
  name: "mtpcli",
10571
- version: VERSION3,
10607
+ version: VERSION,
10572
10608
  description: "Unified CLI for discovering, authenticating, and bridging --describe-compatible tools",
10573
10609
  commands: [
10574
10610
  {
@@ -10918,122 +10954,126 @@ function selfDescribe() {
10918
10954
  };
10919
10955
  console.log(JSON.stringify(cleanJson(schema), null, 2));
10920
10956
  }
10921
- var program2 = new Command().name("mtpcli").version(VERSION3).description("Unified CLI for discovering, authenticating, and bridging --describe-compatible tools").option("--describe", "Print self-describing JSON (mtpcli spec)").action(async (opts) => {
10922
- if (opts.describe) {
10923
- selfDescribe();
10924
- return;
10925
- }
10926
- program2.help();
10927
- });
10928
- program2.command("search").description("Search across --describe-compatible tools").argument("<query>", "Search query").option("--json", "Output as JSON", false).option("--scan-path", "Scan PATH for --describe-compatible tools", false).option("--jobs <n>", "Number of parallel jobs for --scan-path", "16").argument("[tools...]", "Tool names to search (after --)").action(async (query, tools, opts) => {
10929
- const { search: search2, loadSchemas: loadSchemas2, scanPath: scanPath2 } = await Promise.resolve().then(() => (init_search(), exports_search));
10930
- const schemas = opts.scanPath ? await scanPath2(parseInt(opts.jobs, 10)) : await loadSchemas2(tools);
10931
- if (schemas.length === 0) {
10932
- process.stderr.write(`no tools found. Try: mtpcli search --scan-path "query"
10957
+ var VERSION = "0.3.3", program2, authCmd;
10958
+ var init_src = __esm(async () => {
10959
+ init_esm();
10960
+ init_models();
10961
+ program2 = new Command().name("mtpcli").version(VERSION).description("Unified CLI for discovering, authenticating, and bridging --describe-compatible tools").option("--describe", "Print self-describing JSON (mtpcli spec)").action(async (opts) => {
10962
+ if (opts.describe) {
10963
+ selfDescribe();
10964
+ return;
10965
+ }
10966
+ program2.help();
10967
+ });
10968
+ program2.command("search").description("Search across --describe-compatible tools").argument("<query>", "Search query").option("--json", "Output as JSON", false).option("--scan-path", "Scan PATH for --describe-compatible tools", false).option("--jobs <n>", "Number of parallel jobs for --scan-path", "16").argument("[tools...]", "Tool names to search (after --)").action(async (query, tools, opts) => {
10969
+ const { search: search2, loadSchemas: loadSchemas2, scanPath: scanPath2 } = await Promise.resolve().then(() => (init_search(), exports_search));
10970
+ const schemas = opts.scanPath ? await scanPath2(parseInt(opts.jobs, 10)) : await loadSchemas2(tools);
10971
+ if (schemas.length === 0) {
10972
+ process.stderr.write(`no tools found. Try: mtpcli search --scan-path "query"
10933
10973
  `);
10934
- return;
10935
- }
10936
- const results = search2(query, schemas);
10937
- if (results.length === 0) {
10938
- process.stderr.write(`no results for "${query}"
10974
+ return;
10975
+ }
10976
+ const results = search2(query, schemas);
10977
+ if (results.length === 0) {
10978
+ process.stderr.write(`no results for "${query}"
10939
10979
  `);
10940
- return;
10941
- }
10942
- if (opts.json) {
10943
- console.log(JSON.stringify(results, null, 2));
10944
- } else {
10945
- for (const r of results) {
10946
- console.log(`${r.score.toFixed(1).padStart(6)} ${r.tool} ${r.command} ${r.description}`);
10980
+ return;
10947
10981
  }
10948
- }
10949
- });
10950
- var authCmd = program2.command("auth").description("Manage authentication for tools");
10951
- authCmd.command("login").description("Log in to a tool").argument("[tool]", "Tool name").option("--provider <id>", "Specific provider ID").option("--token <value>", "API key / bearer token (skip OAuth flow)").option("--url <url>", "HTTP MCP server URL (triggers OAuth discovery)").option("--client-id <id>", "Pre-registered OAuth client ID (for --url)").action(async (tool, opts) => {
10952
- if (opts.url) {
10953
- const { mcpOAuthFlow: mcpOAuthFlow3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
10954
- await mcpOAuthFlow3(opts.url, "", opts.clientId);
10955
- return;
10956
- }
10957
- if (!tool) {
10958
- process.stderr.write(`error: tool name is required (or use --url)
10982
+ if (opts.json) {
10983
+ console.log(JSON.stringify(results, null, 2));
10984
+ } else {
10985
+ for (const r of results) {
10986
+ console.log(`${r.score.toFixed(1).padStart(6)} ${r.tool} ${r.command} ${r.description}`);
10987
+ }
10988
+ }
10989
+ });
10990
+ authCmd = program2.command("auth").description("Manage authentication for tools");
10991
+ authCmd.command("login").description("Log in to a tool").argument("[tool]", "Tool name").option("--provider <id>", "Specific provider ID").option("--token <value>", "API key / bearer token (skip OAuth flow)").option("--url <url>", "HTTP MCP server URL (triggers OAuth discovery)").option("--client-id <id>", "Pre-registered OAuth client ID (for --url)").action(async (tool, opts) => {
10992
+ if (opts.url) {
10993
+ const { mcpOAuthFlow: mcpOAuthFlow3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
10994
+ await mcpOAuthFlow3(opts.url, "", opts.clientId);
10995
+ return;
10996
+ }
10997
+ if (!tool) {
10998
+ process.stderr.write(`error: tool name is required (or use --url)
10959
10999
  `);
10960
- process.exit(1);
10961
- }
10962
- const { runLogin: runLogin3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
10963
- await runLogin3(tool, opts.provider, opts.token);
10964
- });
10965
- authCmd.command("logout").description("Log out from a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
10966
- if (opts.url) {
10967
- const { mcpAuthLogout: mcpAuthLogout3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
10968
- const deleted = mcpAuthLogout3(opts.url);
10969
- if (deleted) {
10970
- process.stderr.write(`Logged out from ${opts.url}
11000
+ process.exit(1);
11001
+ }
11002
+ const { runLogin: runLogin3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11003
+ await runLogin3(tool, opts.provider, opts.token);
11004
+ });
11005
+ authCmd.command("logout").description("Log out from a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11006
+ if (opts.url) {
11007
+ const { mcpAuthLogout: mcpAuthLogout3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11008
+ const deleted = mcpAuthLogout3(opts.url);
11009
+ if (deleted) {
11010
+ process.stderr.write(`Logged out from ${opts.url}
10971
11011
  `);
10972
- } else {
10973
- process.stderr.write(`No tokens found for ${opts.url}
11012
+ } else {
11013
+ process.stderr.write(`No tokens found for ${opts.url}
10974
11014
  `);
11015
+ }
11016
+ return;
10975
11017
  }
10976
- return;
10977
- }
10978
- if (!tool) {
10979
- process.stderr.write(`error: tool name is required (or use --url)
11018
+ if (!tool) {
11019
+ process.stderr.write(`error: tool name is required (or use --url)
10980
11020
  `);
10981
- process.exit(1);
10982
- }
10983
- const { runLogout: runLogout3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
10984
- await runLogout3(tool);
10985
- });
10986
- authCmd.command("status").description("Show auth status for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
10987
- if (opts.url) {
10988
- const { mcpAuthStatus: mcpAuthStatus3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
10989
- console.log(JSON.stringify(mcpAuthStatus3(opts.url), null, 2));
10990
- return;
10991
- }
10992
- if (!tool) {
10993
- process.stderr.write(`error: tool name is required (or use --url)
11021
+ process.exit(1);
11022
+ }
11023
+ const { runLogout: runLogout3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11024
+ await runLogout3(tool);
11025
+ });
11026
+ authCmd.command("status").description("Show auth status for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11027
+ if (opts.url) {
11028
+ const { mcpAuthStatus: mcpAuthStatus3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11029
+ console.log(JSON.stringify(mcpAuthStatus3(opts.url), null, 2));
11030
+ return;
11031
+ }
11032
+ if (!tool) {
11033
+ process.stderr.write(`error: tool name is required (or use --url)
10994
11034
  `);
10995
- process.exit(1);
10996
- }
10997
- const { runStatus: runStatus3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
10998
- await runStatus3(tool);
10999
- });
11000
- authCmd.command("token").description("Print the access token for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11001
- if (opts.url) {
11002
- const { mcpAuthToken: mcpAuthToken3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11003
- const t = await mcpAuthToken3(opts.url);
11004
- if (!t) {
11005
- throw new Error(`no valid token for '${opts.url}'. Run: mtpcli auth login --url ${opts.url}`);
11006
- }
11007
- console.log(t);
11008
- return;
11009
- }
11010
- if (!tool) {
11011
- process.stderr.write(`error: tool name is required (or use --url)
11035
+ process.exit(1);
11036
+ }
11037
+ const { runStatus: runStatus3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11038
+ await runStatus3(tool);
11039
+ });
11040
+ authCmd.command("token").description("Print the access token for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11041
+ if (opts.url) {
11042
+ const { mcpAuthToken: mcpAuthToken3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11043
+ const t = await mcpAuthToken3(opts.url);
11044
+ if (!t) {
11045
+ throw new Error(`no valid token for '${opts.url}'. Run: mtpcli auth login --url ${opts.url}`);
11046
+ }
11047
+ console.log(t);
11048
+ return;
11049
+ }
11050
+ if (!tool) {
11051
+ process.stderr.write(`error: tool name is required (or use --url)
11012
11052
  `);
11013
- process.exit(1);
11014
- }
11015
- const { runToken: runToken3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11016
- await runToken3(tool);
11017
- });
11018
- authCmd.command("env").description("Print shell export statement for eval").argument("<tool>", "Tool name").action(async (tool) => {
11019
- const { runEnv: runEnv3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11020
- await runEnv3(tool);
11021
- });
11022
- authCmd.command("refresh").description("Force-refresh the stored OAuth token for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11023
- if (opts.url) {
11024
- const { mcpAuthRefresh: mcpAuthRefresh3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11025
- await mcpAuthRefresh3(opts.url);
11026
- return;
11027
- }
11028
- if (!tool) {
11029
- process.stderr.write(`error: tool name is required (or use --url)
11053
+ process.exit(1);
11054
+ }
11055
+ const { runToken: runToken3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11056
+ await runToken3(tool);
11057
+ });
11058
+ authCmd.command("env").description("Print shell export statement for eval").argument("<tool>", "Tool name").action(async (tool) => {
11059
+ const { runEnv: runEnv3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11060
+ await runEnv3(tool);
11061
+ });
11062
+ authCmd.command("refresh").description("Force-refresh the stored OAuth token for a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
11063
+ if (opts.url) {
11064
+ const { mcpAuthRefresh: mcpAuthRefresh3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
11065
+ await mcpAuthRefresh3(opts.url);
11066
+ return;
11067
+ }
11068
+ if (!tool) {
11069
+ process.stderr.write(`error: tool name is required (or use --url)
11030
11070
  `);
11031
- process.exit(1);
11032
- }
11033
- const { runRefresh: runRefresh3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11034
- await runRefresh3(tool);
11035
- });
11036
- program2.command("serve").description("Serve CLI tools as an MCP server (cli2mcp bridge)").requiredOption("--tool <names...>", "Tool(s) to serve").addHelpText("after", `
11071
+ process.exit(1);
11072
+ }
11073
+ const { runRefresh: runRefresh3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
11074
+ await runRefresh3(tool);
11075
+ });
11076
+ program2.command("serve").description("Serve CLI tools as an MCP server (cli2mcp bridge)").requiredOption("--tool <names...>", "Tool(s) to serve").addHelpText("after", `
11037
11077
  This command is meant to be used as an MCP server, not run directly.
11038
11078
  Add it to your MCP client config (e.g. ~/.claude.json):
11039
11079
 
@@ -11051,8 +11091,8 @@ Any CLI tool on your PATH that supports --describe can be served.
11051
11091
  Multiple tools can be combined into a single MCP server:
11052
11092
 
11053
11093
  mtpcli serve --tool tool1 --tool tool2`).action(async (opts) => {
11054
- if (process.stdin.isTTY) {
11055
- process.stderr.write(`Error: 'mtpcli serve' is an MCP server and should not be run directly.
11094
+ if (process.stdin.isTTY) {
11095
+ process.stderr.write(`Error: 'mtpcli serve' is an MCP server and should not be run directly.
11056
11096
  ` + `Add it to your MCP client config instead. For example, in ~/.claude.json:
11057
11097
 
11058
11098
  ` + ` {
@@ -11067,51 +11107,57 @@ Multiple tools can be combined into a single MCP server:
11067
11107
 
11068
11108
  ` + `Run 'mtpcli serve --help' for more details.
11069
11109
  `);
11070
- process.exit(1);
11071
- }
11072
- const { run: run5 } = await Promise.resolve().then(() => (init_serve(), exports_serve));
11073
- await run5(opts.tool);
11074
- });
11075
- program2.command("wrap").description("Wrap an MCP server as a CLI tool (mcp2cli bridge)").option("--server <cmd>", "MCP server command to run (stdio transport)").option("--url <url>", "MCP server URL (Streamable HTTP / SSE transport)").option("-H, --header <header...>", "HTTP header(s) for --url (e.g. 'Authorization: Bearer tok')").option("--client-id <id>", "Pre-registered OAuth client ID (for --url)").option("--describe", "Output --describe JSON instead of invoking", false).argument("[tool_name]", "Tool name to invoke").argument("[args...]", "Arguments for the tool (after --)").action(async (toolName, args, opts) => {
11076
- if (opts.server && opts.url) {
11077
- process.stderr.write(`error: --server and --url are mutually exclusive
11110
+ process.exit(1);
11111
+ }
11112
+ const { run: run5 } = await init_serve().then(() => exports_serve);
11113
+ await run5(opts.tool);
11114
+ });
11115
+ program2.command("wrap").description("Wrap an MCP server as a CLI tool (mcp2cli bridge)").option("--server <cmd>", "MCP server command to run (stdio transport)").option("--url <url>", "MCP server URL (Streamable HTTP / SSE transport)").option("-H, --header <header...>", "HTTP header(s) for --url (e.g. 'Authorization: Bearer tok')").option("--client-id <id>", "Pre-registered OAuth client ID (for --url)").option("--describe", "Output --describe JSON instead of invoking", false).argument("[tool_name]", "Tool name to invoke").argument("[args...]", "Arguments for the tool (after --)").action(async (toolName, args, opts) => {
11116
+ if (opts.server && opts.url) {
11117
+ process.stderr.write(`error: --server and --url are mutually exclusive
11078
11118
  `);
11079
- process.exit(1);
11080
- }
11081
- if (!opts.server && !opts.url) {
11082
- process.stderr.write(`error: one of --server or --url is required
11119
+ process.exit(1);
11120
+ }
11121
+ if (!opts.server && !opts.url) {
11122
+ process.stderr.write(`error: one of --server or --url is required
11083
11123
  `);
11084
- process.exit(1);
11085
- }
11086
- if (opts.header && !opts.url) {
11087
- process.stderr.write(`error: --header requires --url
11124
+ process.exit(1);
11125
+ }
11126
+ if (opts.header && !opts.url) {
11127
+ process.stderr.write(`error: --header requires --url
11088
11128
  `);
11089
- process.exit(1);
11090
- }
11091
- if (opts.clientId && !opts.url) {
11092
- process.stderr.write(`error: --client-id requires --url
11129
+ process.exit(1);
11130
+ }
11131
+ if (opts.clientId && !opts.url) {
11132
+ process.stderr.write(`error: --client-id requires --url
11133
+ `);
11134
+ process.exit(1);
11135
+ }
11136
+ const { run: run5 } = await init_wrap().then(() => exports_wrap);
11137
+ await run5(opts.server, opts.url, opts.describe, toolName, args, opts.header ?? [], opts.clientId);
11138
+ });
11139
+ program2.command("validate").description("Validate a tool's --describe output against the MTP spec").argument("[tool]", "Tool name to validate").option("--json", "Output as JSON", false).option("--stdin", "Read JSON from stdin", false).option("--skip-help", "Skip --help cross-reference", false).action(async (tool, opts) => {
11140
+ const { run: run5 } = await Promise.resolve().then(() => (init_validate(), exports_validate));
11141
+ await run5(tool, {
11142
+ json: opts.json,
11143
+ stdin: opts.stdin,
11144
+ skipHelp: opts.skipHelp
11145
+ });
11146
+ });
11147
+ program2.command("completions").description("Generate shell completions from --describe output").argument("<shell>", "Shell type (bash, zsh, fish)").argument("<tool>", "Tool name").action(async (shell, tool) => {
11148
+ const { run: run5 } = await Promise.resolve().then(() => (init_completions(), exports_completions));
11149
+ await run5(shell, tool);
11150
+ });
11151
+ try {
11152
+ await program2.parseAsync(process.argv);
11153
+ } catch (e) {
11154
+ process.stderr.write(`error: ${e instanceof Error ? e.message : e}
11093
11155
  `);
11094
11156
  process.exit(1);
11095
11157
  }
11096
- const { run: run5 } = await Promise.resolve().then(() => (init_wrap(), exports_wrap));
11097
- await run5(opts.server, opts.url, opts.describe, toolName, args, opts.header ?? [], opts.clientId);
11098
11158
  });
11099
- program2.command("validate").description("Validate a tool's --describe output against the MTP spec").argument("[tool]", "Tool name to validate").option("--json", "Output as JSON", false).option("--stdin", "Read JSON from stdin", false).option("--skip-help", "Skip --help cross-reference", false).action(async (tool, opts) => {
11100
- const { run: run5 } = await Promise.resolve().then(() => (init_validate(), exports_validate));
11101
- await run5(tool, {
11102
- json: opts.json,
11103
- stdin: opts.stdin,
11104
- skipHelp: opts.skipHelp
11105
- });
11106
- });
11107
- program2.command("completions").description("Generate shell completions from --describe output").argument("<shell>", "Shell type (bash, zsh, fish)").argument("<tool>", "Tool name").action(async (shell, tool) => {
11108
- const { run: run5 } = await Promise.resolve().then(() => (init_completions(), exports_completions));
11109
- await run5(shell, tool);
11110
- });
11111
- try {
11112
- await program2.parseAsync(process.argv);
11113
- } catch (e) {
11114
- process.stderr.write(`error: ${e instanceof Error ? e.message : e}
11115
- `);
11116
- process.exit(1);
11117
- }
11159
+ await init_src();
11160
+
11161
+ export {
11162
+ VERSION
11163
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modeltoolsprotocol/mtpcli",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "bin": {