@modeltoolsprotocol/mtpcli 1.1.0 → 1.2.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/README.md +8 -12
- package/dist/index.js +328 -335
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# mtpcli
|
|
2
2
|
|
|
3
|
-
The command-line interface for the [Model Tools Protocol](https://github.com/modeltoolsprotocol/modeltoolsprotocol) (MTP). Discover, authenticate, and bridge tools that implement the `--describe` convention.
|
|
3
|
+
The command-line interface for the [Model Tools Protocol](https://github.com/modeltoolsprotocol/modeltoolsprotocol) (MTP). Discover, authenticate, and bridge tools that implement the `--mtp-describe` convention.
|
|
4
4
|
|
|
5
|
-
CLI tools are composable but not LLM-discoverable. MCP tools are discoverable but not composable. MTP bridges the gap with a single `--describe` flag. See the [protocol README](https://github.com/modeltoolsprotocol/modeltoolsprotocol) for the full rationale.
|
|
5
|
+
CLI tools are composable but not LLM-discoverable. MCP tools are discoverable but not composable. MTP bridges the gap with a single `--mtp-describe` flag. **mtpcli** turns any `--mtp-describe` CLI into an MCP server, turns any MCP server into a composable CLI, and handles discovery, auth, and validation along the way. See the [protocol README](https://github.com/modeltoolsprotocol/modeltoolsprotocol) for the full rationale.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -10,15 +10,11 @@ CLI tools are composable but not LLM-discoverable. MCP tools are discoverable bu
|
|
|
10
10
|
npm install -g @modeltoolsprotocol/mtpcli
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
## What it does
|
|
14
|
-
|
|
15
|
-
**mtpcli** bridges the gap between CLI tools and MCP servers. It turns any `--describe` CLI into an MCP server, turns any MCP server into a composable CLI, and handles discovery, auth, and validation along the way.
|
|
16
|
-
|
|
17
13
|
## Usage
|
|
18
14
|
|
|
19
15
|
### Serve CLI tools over MCP
|
|
20
16
|
|
|
21
|
-
Any CLI that supports `--describe` becomes an MCP server:
|
|
17
|
+
Any CLI that supports `--mtp-describe` becomes an MCP server:
|
|
22
18
|
|
|
23
19
|
```bash
|
|
24
20
|
$ mtpcli serve --tool atlasctl --tool mytool
|
|
@@ -31,7 +27,7 @@ mtpcli serve: serving 6 tool(s) from 2 CLI tool(s)
|
|
|
31
27
|
...
|
|
32
28
|
```
|
|
33
29
|
|
|
34
|
-
Drop it into your Claude Desktop config and it works like any other MCP server. The bridge reads `--describe`, translates commands to MCP tools, and shells out to the real CLI when the host calls a tool.
|
|
30
|
+
Drop it into your Claude Desktop config and it works like any other MCP server. The bridge reads `--mtp-describe`, translates commands to MCP tools, and shells out to the real CLI when the host calls a tool.
|
|
35
31
|
|
|
36
32
|
### Wrap an MCP server as a CLI
|
|
37
33
|
|
|
@@ -39,7 +35,7 @@ Atlassian ships an MCP server at `mcp.atlassian.com`. With `mtpcli wrap`, it's a
|
|
|
39
35
|
|
|
40
36
|
```bash
|
|
41
37
|
# Discover what tools the server offers
|
|
42
|
-
$ mtpcli wrap --url "https://mcp.atlassian.com/v1/mcp" --describe
|
|
38
|
+
$ mtpcli wrap --url "https://mcp.atlassian.com/v1/mcp" --mtp-describe
|
|
43
39
|
|
|
44
40
|
# Fetch a Confluence page
|
|
45
41
|
$ mtpcli wrap --url "https://mcp.atlassian.com/v1/mcp" \
|
|
@@ -51,7 +47,7 @@ $ mtpcli wrap --url "https://mcp.atlassian.com/v1/mcp" \
|
|
|
51
47
|
| jq -r '.body'
|
|
52
48
|
|
|
53
49
|
# Works with stdio servers too
|
|
54
|
-
$ mtpcli wrap --server "npx @mcp/server-github" --describe
|
|
50
|
+
$ mtpcli wrap --server "npx @mcp/server-github" --mtp-describe
|
|
55
51
|
```
|
|
56
52
|
|
|
57
53
|
The 2,500+ MCP servers people have built? They're all CLI tools now. Pipe their output, use them in scripts, compose them with other tools.
|
|
@@ -90,7 +86,7 @@ mtpcli auth logout mytool
|
|
|
90
86
|
|
|
91
87
|
See [AUTH.md](AUTH.md) for details on token storage, usage patterns, and bridge integration.
|
|
92
88
|
|
|
93
|
-
### Validate a tool's --describe output
|
|
89
|
+
### Validate a tool's --mtp-describe output
|
|
94
90
|
|
|
95
91
|
```bash
|
|
96
92
|
# Validate a tool against the MTP spec
|
|
@@ -120,7 +116,7 @@ mtpcli completions fish mytool | source
|
|
|
120
116
|
|
|
121
117
|
```bash
|
|
122
118
|
# mtpcli is itself an MTP-compliant tool
|
|
123
|
-
mtpcli --describe
|
|
119
|
+
mtpcli --mtp-describe
|
|
124
120
|
```
|
|
125
121
|
|
|
126
122
|
## Development
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,6 @@ 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);
|
|
31
30
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
32
31
|
|
|
33
32
|
// node_modules/commander/lib/error.js
|
|
@@ -2123,25 +2122,6 @@ var require_commander = __commonJS((exports) => {
|
|
|
2123
2122
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
2124
2123
|
});
|
|
2125
2124
|
|
|
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
|
-
|
|
2145
2125
|
// node_modules/zod/v3/helpers/util.js
|
|
2146
2126
|
var util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
2147
2127
|
const t = typeof data;
|
|
@@ -6108,119 +6088,6 @@ var init_zod = __esm(() => {
|
|
|
6108
6088
|
init_external();
|
|
6109
6089
|
});
|
|
6110
6090
|
|
|
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
|
-
|
|
6224
6091
|
// node_modules/jaro-winkler/index.js
|
|
6225
6092
|
var require_jaro_winkler = __commonJS((exports, module) => {
|
|
6226
6093
|
(function(root) {
|
|
@@ -6561,8 +6428,8 @@ function jsonRpcSuccess(id, result) {
|
|
|
6561
6428
|
function jsonRpcError(id, code, message) {
|
|
6562
6429
|
return { jsonrpc: "2.0", id, error: { code, message } };
|
|
6563
6430
|
}
|
|
6564
|
-
var ExampleSchema2, ArgSchema2, IoDescriptorSchema2, CommandAuthSchema2, CommandSchema2, AuthProviderSchema2, AuthConfigSchema2, ToolSchemaSchema2, StoredTokenSchema2, JsonRpcErrorSchema2, JsonRpcRequestSchema2, JsonRpcResponseSchema2, McpToolDefSchema2;
|
|
6565
|
-
var
|
|
6431
|
+
var ExampleSchema2, ArgSchema2, IoDescriptorSchema2, CommandAuthSchema2, CommandSchema2, AuthProviderSchema2, AuthConfigSchema2, MTP_SPEC_VERSION2 = "2026-02-07", ToolSchemaSchema2, StoredTokenSchema2, JsonRpcErrorSchema2, JsonRpcRequestSchema2, JsonRpcResponseSchema2, McpToolDefSchema2;
|
|
6432
|
+
var init_models = __esm(() => {
|
|
6566
6433
|
init_zod();
|
|
6567
6434
|
ExampleSchema2 = exports_external.object({
|
|
6568
6435
|
description: exports_external.string().optional(),
|
|
@@ -6612,6 +6479,7 @@ var init_models2 = __esm(() => {
|
|
|
6612
6479
|
providers: exports_external.array(AuthProviderSchema2)
|
|
6613
6480
|
});
|
|
6614
6481
|
ToolSchemaSchema2 = exports_external.object({
|
|
6482
|
+
specVersion: exports_external.string(),
|
|
6615
6483
|
name: exports_external.string(),
|
|
6616
6484
|
version: exports_external.string(),
|
|
6617
6485
|
description: exports_external.string(),
|
|
@@ -6705,7 +6573,7 @@ async function getToolSchema(toolName) {
|
|
|
6705
6573
|
return null;
|
|
6706
6574
|
}
|
|
6707
6575
|
try {
|
|
6708
|
-
const { stdout } = await execFileAsync(toolPath, ["--describe"], {
|
|
6576
|
+
const { stdout } = await execFileAsync(toolPath, ["--mtp-describe"], {
|
|
6709
6577
|
timeout: 5000
|
|
6710
6578
|
});
|
|
6711
6579
|
return ToolSchemaSchema2.parse(JSON.parse(stdout.trim()));
|
|
@@ -6803,7 +6671,7 @@ async function loadSchemas(toolNames) {
|
|
|
6803
6671
|
writeCache(schema.name, schema);
|
|
6804
6672
|
schemas.push(schema);
|
|
6805
6673
|
} else {
|
|
6806
|
-
process.stderr.write(`warning: could not get --describe from '${name}'
|
|
6674
|
+
process.stderr.write(`warning: could not get --mtp-describe from '${name}'
|
|
6807
6675
|
`);
|
|
6808
6676
|
}
|
|
6809
6677
|
}
|
|
@@ -6811,7 +6679,7 @@ async function loadSchemas(toolNames) {
|
|
|
6811
6679
|
}
|
|
6812
6680
|
var import_jaro_winkler, import_which, execFileAsync;
|
|
6813
6681
|
var init_search = __esm(() => {
|
|
6814
|
-
|
|
6682
|
+
init_models();
|
|
6815
6683
|
import_jaro_winkler = __toESM(require_jaro_winkler(), 1);
|
|
6816
6684
|
import_which = __toESM(require_lib(), 1);
|
|
6817
6685
|
execFileAsync = promisify(execFile);
|
|
@@ -7457,7 +7325,7 @@ async function getToolSchema2(toolName) {
|
|
|
7457
7325
|
return null;
|
|
7458
7326
|
}
|
|
7459
7327
|
try {
|
|
7460
|
-
const { stdout } = await execFileAsync6(toolPath, ["--describe"], {
|
|
7328
|
+
const { stdout } = await execFileAsync6(toolPath, ["--mtp-describe"], {
|
|
7461
7329
|
timeout: 5000
|
|
7462
7330
|
});
|
|
7463
7331
|
return ToolSchemaSchema2.parse(JSON.parse(stdout.trim()));
|
|
@@ -7467,7 +7335,7 @@ async function getToolSchema2(toolName) {
|
|
|
7467
7335
|
}
|
|
7468
7336
|
var import_jaro_winkler2, import_which2, execFileAsync6;
|
|
7469
7337
|
var init_search2 = __esm(() => {
|
|
7470
|
-
|
|
7338
|
+
init_models();
|
|
7471
7339
|
import_jaro_winkler2 = __toESM(require_jaro_winkler(), 1);
|
|
7472
7340
|
import_which2 = __toESM(require_lib(), 1);
|
|
7473
7341
|
execFileAsync6 = promisify8(execFile8);
|
|
@@ -8825,9 +8693,12 @@ function readResponse(rl) {
|
|
|
8825
8693
|
});
|
|
8826
8694
|
}
|
|
8827
8695
|
var init_mcp = __esm(() => {
|
|
8828
|
-
|
|
8696
|
+
init_models();
|
|
8829
8697
|
});
|
|
8830
8698
|
|
|
8699
|
+
// src/version.ts
|
|
8700
|
+
var VERSION2 = "1.2.0";
|
|
8701
|
+
|
|
8831
8702
|
// src/serve.ts
|
|
8832
8703
|
var exports_serve = {};
|
|
8833
8704
|
__export(exports_serve, {
|
|
@@ -8886,12 +8757,12 @@ function commandToMcpTool(toolName, cmd) {
|
|
|
8886
8757
|
if (cmd.stdin.description && typeof prop === "object" && prop !== null) {
|
|
8887
8758
|
prop.description = cmd.stdin.description;
|
|
8888
8759
|
}
|
|
8889
|
-
properties
|
|
8760
|
+
properties["mtp:stdin"] = prop;
|
|
8890
8761
|
} else {
|
|
8891
8762
|
const prop = { type: "string" };
|
|
8892
8763
|
if (cmd.stdin.description)
|
|
8893
8764
|
prop.description = cmd.stdin.description;
|
|
8894
|
-
properties
|
|
8765
|
+
properties["mtp:stdin"] = prop;
|
|
8895
8766
|
}
|
|
8896
8767
|
}
|
|
8897
8768
|
const inputSchema = {
|
|
@@ -8950,8 +8821,8 @@ function buildCliCommand(toolName, commandName, arguments_, commandSchema) {
|
|
|
8950
8821
|
}
|
|
8951
8822
|
function invokeCliTool(toolName, commandName, arguments_, commandSchema, authEnv) {
|
|
8952
8823
|
const argsForCli = { ...arguments_ };
|
|
8953
|
-
const stdinData = argsForCli
|
|
8954
|
-
delete argsForCli
|
|
8824
|
+
const stdinData = argsForCli["mtp:stdin"];
|
|
8825
|
+
delete argsForCli["mtp:stdin"];
|
|
8955
8826
|
const stdinStr = stdinData !== undefined ? typeof stdinData === "string" ? stdinData : JSON.stringify(stdinData) : undefined;
|
|
8956
8827
|
const cmd = buildCliCommand(toolName, commandName, argsForCli, commandSchema);
|
|
8957
8828
|
return new Promise((resolve) => {
|
|
@@ -9020,7 +8891,7 @@ async function handleRequest(state, req) {
|
|
|
9020
8891
|
return jsonRpcSuccess(id, {
|
|
9021
8892
|
protocolVersion: "2024-11-05",
|
|
9022
8893
|
capabilities: { tools: {} },
|
|
9023
|
-
serverInfo: { name: "mtpcli-serve", version:
|
|
8894
|
+
serverInfo: { name: "mtpcli-serve", version: VERSION2 }
|
|
9024
8895
|
});
|
|
9025
8896
|
case "notifications/initialized":
|
|
9026
8897
|
return null;
|
|
@@ -9062,7 +8933,7 @@ async function run(toolNames) {
|
|
|
9062
8933
|
for (const name of toolNames) {
|
|
9063
8934
|
const schema = await getToolSchema2(name);
|
|
9064
8935
|
if (!schema)
|
|
9065
|
-
throw new Error(`could not get --describe from '${name}'`);
|
|
8936
|
+
throw new Error(`could not get --mtp-describe from '${name}'`);
|
|
9066
8937
|
if (schema.auth)
|
|
9067
8938
|
allAuth.set(name, schema.auth);
|
|
9068
8939
|
for (const cmd of schema.commands) {
|
|
@@ -9110,12 +8981,11 @@ async function run(toolNames) {
|
|
|
9110
8981
|
}
|
|
9111
8982
|
}
|
|
9112
8983
|
var execFileAsync7, TOOL_TIMEOUT_MS = 60000, MAX_OUTPUT_BYTES;
|
|
9113
|
-
var init_serve = __esm(
|
|
8984
|
+
var init_serve = __esm(() => {
|
|
9114
8985
|
init_auth();
|
|
9115
8986
|
init_mcp();
|
|
9116
|
-
|
|
8987
|
+
init_models();
|
|
9117
8988
|
init_search2();
|
|
9118
|
-
await init_src();
|
|
9119
8989
|
execFileAsync7 = promisify9(execFile9);
|
|
9120
8990
|
MAX_OUTPUT_BYTES = 1024 * 1024 * 1024;
|
|
9121
8991
|
});
|
|
@@ -9567,8 +9437,8 @@ function mcpToolToCommand(tool) {
|
|
|
9567
9437
|
...inputSchema.properties ?? {}
|
|
9568
9438
|
};
|
|
9569
9439
|
const requiredFields = (inputSchema.required ?? []).filter((v) => typeof v === "string");
|
|
9570
|
-
const stdinProp = allProperties
|
|
9571
|
-
delete allProperties
|
|
9440
|
+
const stdinProp = allProperties["mtp:stdin"];
|
|
9441
|
+
delete allProperties["mtp:stdin"];
|
|
9572
9442
|
let stdin;
|
|
9573
9443
|
if (stdinProp) {
|
|
9574
9444
|
const propType = stdinProp.type;
|
|
@@ -9684,7 +9554,7 @@ class McpClient {
|
|
|
9684
9554
|
client.sendRequest("initialize", {
|
|
9685
9555
|
protocolVersion: "2024-11-05",
|
|
9686
9556
|
capabilities: {},
|
|
9687
|
-
clientInfo: { name: "mtpcli-wrap", version:
|
|
9557
|
+
clientInfo: { name: "mtpcli-wrap", version: VERSION2 }
|
|
9688
9558
|
});
|
|
9689
9559
|
await client.readResponse();
|
|
9690
9560
|
client.sendNotification("notifications/initialized", {});
|
|
@@ -9745,7 +9615,7 @@ class HttpMcpClient {
|
|
|
9745
9615
|
const initResult = await client.sendRequest("initialize", {
|
|
9746
9616
|
protocolVersion: "2025-11-25",
|
|
9747
9617
|
capabilities: {},
|
|
9748
|
-
clientInfo: { name: "mtpcli-wrap", version:
|
|
9618
|
+
clientInfo: { name: "mtpcli-wrap", version: VERSION2 }
|
|
9749
9619
|
});
|
|
9750
9620
|
client.protocolVersion = initResult.protocolVersion ?? "2025-11-25";
|
|
9751
9621
|
await client.sendNotification("notifications/initialized", {});
|
|
@@ -9943,6 +9813,7 @@ async function run2(serverCmd, serverUrl, describeMode, toolName, toolArgs = [],
|
|
|
9943
9813
|
const mcpTools = await client.listTools();
|
|
9944
9814
|
const commands = mcpTools.map(mcpToolToCommand);
|
|
9945
9815
|
const schema = {
|
|
9816
|
+
specVersion: MTP_SPEC_VERSION2,
|
|
9946
9817
|
name: serverName,
|
|
9947
9818
|
version: "0.1.0",
|
|
9948
9819
|
description: `CLI wrapper for MCP server: ${serverName}`,
|
|
@@ -9966,9 +9837,9 @@ async function run2(serverCmd, serverUrl, describeMode, toolName, toolArgs = [],
|
|
|
9966
9837
|
const stdinData = Buffer.concat(chunks).toString("utf-8");
|
|
9967
9838
|
if (stdinData) {
|
|
9968
9839
|
try {
|
|
9969
|
-
parsed
|
|
9840
|
+
parsed["mtp:stdin"] = JSON.parse(stdinData);
|
|
9970
9841
|
} catch {
|
|
9971
|
-
parsed
|
|
9842
|
+
parsed["mtp:stdin"] = stdinData;
|
|
9972
9843
|
}
|
|
9973
9844
|
}
|
|
9974
9845
|
}
|
|
@@ -9987,9 +9858,9 @@ async function run2(serverCmd, serverUrl, describeMode, toolName, toolArgs = [],
|
|
|
9987
9858
|
client.stop();
|
|
9988
9859
|
}
|
|
9989
9860
|
}
|
|
9990
|
-
var init_wrap = __esm(
|
|
9861
|
+
var init_wrap = __esm(() => {
|
|
9991
9862
|
init_mcp();
|
|
9992
|
-
|
|
9863
|
+
init_models();
|
|
9993
9864
|
});
|
|
9994
9865
|
|
|
9995
9866
|
// src/validate.ts
|
|
@@ -10080,7 +9951,7 @@ function crossReferenceHelp(schema, helpText) {
|
|
|
10080
9951
|
}
|
|
10081
9952
|
helpFlags.delete("--help");
|
|
10082
9953
|
helpFlags.delete("--version");
|
|
10083
|
-
helpFlags.delete("--describe");
|
|
9954
|
+
helpFlags.delete("--mtp-describe");
|
|
10084
9955
|
const declaredFlags = new Set;
|
|
10085
9956
|
for (const cmd of schema.commands) {
|
|
10086
9957
|
for (const arg of cmd.args) {
|
|
@@ -10094,7 +9965,7 @@ function crossReferenceHelp(schema, helpText) {
|
|
|
10094
9965
|
diags.push({
|
|
10095
9966
|
level: "info",
|
|
10096
9967
|
code: "HELP_ARG_MISMATCH",
|
|
10097
|
-
message: `Flag "${flag}" in --describe but not found in --help`
|
|
9968
|
+
message: `Flag "${flag}" in --mtp-describe but not found in --help`
|
|
10098
9969
|
});
|
|
10099
9970
|
}
|
|
10100
9971
|
}
|
|
@@ -10103,7 +9974,7 @@ function crossReferenceHelp(schema, helpText) {
|
|
|
10103
9974
|
diags.push({
|
|
10104
9975
|
level: "info",
|
|
10105
9976
|
code: "HELP_ARG_MISMATCH",
|
|
10106
|
-
message: `Flag "${flag}" in --help but not found in --describe`
|
|
9977
|
+
message: `Flag "${flag}" in --help but not found in --mtp-describe`
|
|
10107
9978
|
});
|
|
10108
9979
|
}
|
|
10109
9980
|
}
|
|
@@ -10124,7 +9995,7 @@ async function validateTool(toolName, opts) {
|
|
|
10124
9995
|
}
|
|
10125
9996
|
let describeOutput;
|
|
10126
9997
|
try {
|
|
10127
|
-
const { stdout } = await execFileAsync8(toolPath, ["--describe"], {
|
|
9998
|
+
const { stdout } = await execFileAsync8(toolPath, ["--mtp-describe"], {
|
|
10128
9999
|
timeout: 1e4
|
|
10129
10000
|
});
|
|
10130
10001
|
describeOutput = stdout.trim();
|
|
@@ -10132,7 +10003,7 @@ async function validateTool(toolName, opts) {
|
|
|
10132
10003
|
diags.push({
|
|
10133
10004
|
level: "error",
|
|
10134
10005
|
code: "DESCRIBE_FAILED",
|
|
10135
|
-
message: `"${toolName} --describe" produced empty output`
|
|
10006
|
+
message: `"${toolName} --mtp-describe" produced empty output`
|
|
10136
10007
|
});
|
|
10137
10008
|
return buildResult(toolName, diags);
|
|
10138
10009
|
}
|
|
@@ -10140,7 +10011,7 @@ async function validateTool(toolName, opts) {
|
|
|
10140
10011
|
diags.push({
|
|
10141
10012
|
level: "error",
|
|
10142
10013
|
code: "DESCRIBE_FAILED",
|
|
10143
|
-
message: `"${toolName} --describe" failed: ${e instanceof Error ? e.message : e}`
|
|
10014
|
+
message: `"${toolName} --mtp-describe" failed: ${e instanceof Error ? e.message : e}`
|
|
10144
10015
|
});
|
|
10145
10016
|
return buildResult(toolName, diags);
|
|
10146
10017
|
}
|
|
@@ -10213,7 +10084,7 @@ function printHuman(result) {
|
|
|
10213
10084
|
}
|
|
10214
10085
|
var import_which3, execFileAsync8, VALID_ARG_TYPES;
|
|
10215
10086
|
var init_validate = __esm(() => {
|
|
10216
|
-
|
|
10087
|
+
init_models();
|
|
10217
10088
|
import_which3 = __toESM(require_lib(), 1);
|
|
10218
10089
|
execFileAsync8 = promisify10(execFile10);
|
|
10219
10090
|
VALID_ARG_TYPES = new Set([
|
|
@@ -10590,7 +10461,7 @@ async function run4(shell, toolName) {
|
|
|
10590
10461
|
}
|
|
10591
10462
|
const schema = await getToolSchema2(toolName);
|
|
10592
10463
|
if (!schema) {
|
|
10593
|
-
process.stderr.write(`error: could not get --describe from "${toolName}"
|
|
10464
|
+
process.stderr.write(`error: could not get --mtp-describe from "${toolName}"
|
|
10594
10465
|
`);
|
|
10595
10466
|
process.exit(1);
|
|
10596
10467
|
}
|
|
@@ -10600,16 +10471,148 @@ var init_completions = __esm(() => {
|
|
|
10600
10471
|
init_search2();
|
|
10601
10472
|
});
|
|
10602
10473
|
|
|
10474
|
+
// node_modules/commander/esm.mjs
|
|
10475
|
+
var import__ = __toESM(require_commander(), 1);
|
|
10476
|
+
var {
|
|
10477
|
+
program,
|
|
10478
|
+
createCommand,
|
|
10479
|
+
createArgument,
|
|
10480
|
+
createOption,
|
|
10481
|
+
CommanderError,
|
|
10482
|
+
InvalidArgumentError,
|
|
10483
|
+
InvalidOptionArgumentError,
|
|
10484
|
+
Command,
|
|
10485
|
+
Argument,
|
|
10486
|
+
Option,
|
|
10487
|
+
Help
|
|
10488
|
+
} = import__.default;
|
|
10489
|
+
|
|
10490
|
+
// src/models.ts
|
|
10491
|
+
init_zod();
|
|
10492
|
+
var ExampleSchema = exports_external.object({
|
|
10493
|
+
description: exports_external.string().optional(),
|
|
10494
|
+
command: exports_external.string(),
|
|
10495
|
+
output: exports_external.string().optional()
|
|
10496
|
+
});
|
|
10497
|
+
var ArgSchema = exports_external.object({
|
|
10498
|
+
name: exports_external.string(),
|
|
10499
|
+
type: exports_external.string(),
|
|
10500
|
+
description: exports_external.string().optional(),
|
|
10501
|
+
required: exports_external.boolean().default(false),
|
|
10502
|
+
default: exports_external.any().optional(),
|
|
10503
|
+
values: exports_external.array(exports_external.string()).optional()
|
|
10504
|
+
});
|
|
10505
|
+
var IoDescriptorSchema = exports_external.object({
|
|
10506
|
+
contentType: exports_external.string().optional(),
|
|
10507
|
+
description: exports_external.string().optional(),
|
|
10508
|
+
schema: exports_external.any().optional()
|
|
10509
|
+
});
|
|
10510
|
+
var CommandAuthSchema = exports_external.object({
|
|
10511
|
+
required: exports_external.boolean().default(false),
|
|
10512
|
+
scopes: exports_external.array(exports_external.string()).optional()
|
|
10513
|
+
});
|
|
10514
|
+
var CommandSchema = exports_external.object({
|
|
10515
|
+
name: exports_external.string(),
|
|
10516
|
+
description: exports_external.string(),
|
|
10517
|
+
args: exports_external.array(ArgSchema).default([]),
|
|
10518
|
+
stdin: IoDescriptorSchema.optional(),
|
|
10519
|
+
stdout: IoDescriptorSchema.optional(),
|
|
10520
|
+
examples: exports_external.array(ExampleSchema).default([]),
|
|
10521
|
+
auth: CommandAuthSchema.optional()
|
|
10522
|
+
});
|
|
10523
|
+
var AuthProviderSchema = exports_external.object({
|
|
10524
|
+
id: exports_external.string(),
|
|
10525
|
+
type: exports_external.string(),
|
|
10526
|
+
displayName: exports_external.string().optional(),
|
|
10527
|
+
authorizationUrl: exports_external.string().optional(),
|
|
10528
|
+
tokenUrl: exports_external.string().optional(),
|
|
10529
|
+
scopes: exports_external.array(exports_external.string()).optional(),
|
|
10530
|
+
clientId: exports_external.string().optional(),
|
|
10531
|
+
registrationUrl: exports_external.string().optional(),
|
|
10532
|
+
instructions: exports_external.string().optional()
|
|
10533
|
+
});
|
|
10534
|
+
var AuthConfigSchema = exports_external.object({
|
|
10535
|
+
required: exports_external.boolean().default(false),
|
|
10536
|
+
envVar: exports_external.string(),
|
|
10537
|
+
providers: exports_external.array(AuthProviderSchema)
|
|
10538
|
+
});
|
|
10539
|
+
var MTP_SPEC_VERSION = "2026-02-07";
|
|
10540
|
+
var ToolSchemaSchema = exports_external.object({
|
|
10541
|
+
specVersion: exports_external.string(),
|
|
10542
|
+
name: exports_external.string(),
|
|
10543
|
+
version: exports_external.string(),
|
|
10544
|
+
description: exports_external.string(),
|
|
10545
|
+
auth: AuthConfigSchema.optional(),
|
|
10546
|
+
commands: exports_external.array(CommandSchema)
|
|
10547
|
+
});
|
|
10548
|
+
var StoredTokenSchema = exports_external.object({
|
|
10549
|
+
access_token: exports_external.string(),
|
|
10550
|
+
token_type: exports_external.string().optional(),
|
|
10551
|
+
refresh_token: exports_external.string().optional(),
|
|
10552
|
+
expires_at: exports_external.string().optional(),
|
|
10553
|
+
scopes: exports_external.array(exports_external.string()).optional(),
|
|
10554
|
+
provider_id: exports_external.string(),
|
|
10555
|
+
created_at: exports_external.string()
|
|
10556
|
+
});
|
|
10557
|
+
var JsonRpcErrorSchema = exports_external.object({
|
|
10558
|
+
code: exports_external.number(),
|
|
10559
|
+
message: exports_external.string(),
|
|
10560
|
+
data: exports_external.any().optional()
|
|
10561
|
+
});
|
|
10562
|
+
var JsonRpcRequestSchema = exports_external.object({
|
|
10563
|
+
jsonrpc: exports_external.string(),
|
|
10564
|
+
id: exports_external.any().optional(),
|
|
10565
|
+
method: exports_external.string(),
|
|
10566
|
+
params: exports_external.any().default({})
|
|
10567
|
+
});
|
|
10568
|
+
var JsonRpcResponseSchema = exports_external.object({
|
|
10569
|
+
jsonrpc: exports_external.string(),
|
|
10570
|
+
id: exports_external.any().optional(),
|
|
10571
|
+
result: exports_external.any().optional(),
|
|
10572
|
+
error: JsonRpcErrorSchema.optional()
|
|
10573
|
+
});
|
|
10574
|
+
var McpToolDefSchema = exports_external.object({
|
|
10575
|
+
name: exports_external.string(),
|
|
10576
|
+
description: exports_external.string(),
|
|
10577
|
+
inputSchema: exports_external.any()
|
|
10578
|
+
});
|
|
10579
|
+
function cleanJson(obj) {
|
|
10580
|
+
if (obj === null || obj === undefined)
|
|
10581
|
+
return;
|
|
10582
|
+
if (Array.isArray(obj)) {
|
|
10583
|
+
return obj.map(cleanJson);
|
|
10584
|
+
}
|
|
10585
|
+
if (typeof obj === "object") {
|
|
10586
|
+
const out = {};
|
|
10587
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
10588
|
+
if (v === undefined)
|
|
10589
|
+
continue;
|
|
10590
|
+
if (Array.isArray(v) && v.length === 0)
|
|
10591
|
+
continue;
|
|
10592
|
+
const cleaned = cleanJson(v);
|
|
10593
|
+
if (cleaned !== undefined) {
|
|
10594
|
+
out[k] = cleaned;
|
|
10595
|
+
}
|
|
10596
|
+
}
|
|
10597
|
+
return out;
|
|
10598
|
+
}
|
|
10599
|
+
return obj;
|
|
10600
|
+
}
|
|
10601
|
+
|
|
10602
|
+
// src/version.ts
|
|
10603
|
+
var VERSION = "1.2.0";
|
|
10604
|
+
|
|
10603
10605
|
// src/index.ts
|
|
10604
10606
|
function selfDescribe() {
|
|
10605
10607
|
const schema = {
|
|
10608
|
+
specVersion: MTP_SPEC_VERSION,
|
|
10606
10609
|
name: "mtpcli",
|
|
10607
10610
|
version: VERSION,
|
|
10608
|
-
description: "Unified CLI for discovering, authenticating, and bridging --describe-compatible tools",
|
|
10611
|
+
description: "Unified CLI for discovering, authenticating, and bridging --mtp-describe-compatible tools",
|
|
10609
10612
|
commands: [
|
|
10610
10613
|
{
|
|
10611
10614
|
name: "search",
|
|
10612
|
-
description: "Search across --describe-compatible tools for commands matching a query",
|
|
10615
|
+
description: "Search across --mtp-describe-compatible tools for commands matching a query",
|
|
10613
10616
|
args: [
|
|
10614
10617
|
{
|
|
10615
10618
|
name: "query",
|
|
@@ -10806,7 +10809,7 @@ function selfDescribe() {
|
|
|
10806
10809
|
name: "--tool",
|
|
10807
10810
|
type: "array",
|
|
10808
10811
|
required: true,
|
|
10809
|
-
description: "Tool name(s) to serve (must support --describe)"
|
|
10812
|
+
description: "Tool name(s) to serve (must support --mtp-describe)"
|
|
10810
10813
|
}
|
|
10811
10814
|
],
|
|
10812
10815
|
examples: [
|
|
@@ -10822,7 +10825,7 @@ function selfDescribe() {
|
|
|
10822
10825
|
},
|
|
10823
10826
|
{
|
|
10824
10827
|
name: "wrap",
|
|
10825
|
-
description: "Wrap an MCP server as a --describe-compatible CLI",
|
|
10828
|
+
description: "Wrap an MCP server as a --mtp-describe-compatible CLI",
|
|
10826
10829
|
args: [
|
|
10827
10830
|
{
|
|
10828
10831
|
name: "--server",
|
|
@@ -10845,9 +10848,9 @@ function selfDescribe() {
|
|
|
10845
10848
|
description: "Pre-registered OAuth client ID (for servers without dynamic registration)"
|
|
10846
10849
|
},
|
|
10847
10850
|
{
|
|
10848
|
-
name: "--describe",
|
|
10851
|
+
name: "--mtp-describe",
|
|
10849
10852
|
type: "boolean",
|
|
10850
|
-
description: "Output --describe JSON"
|
|
10853
|
+
description: "Output --mtp-describe JSON"
|
|
10851
10854
|
},
|
|
10852
10855
|
{
|
|
10853
10856
|
name: "tool_name",
|
|
@@ -10858,7 +10861,7 @@ function selfDescribe() {
|
|
|
10858
10861
|
examples: [
|
|
10859
10862
|
{
|
|
10860
10863
|
description: "Describe a stdio MCP server",
|
|
10861
|
-
command: 'mtpcli wrap --server "npx @mcp/server-github" --describe'
|
|
10864
|
+
command: 'mtpcli wrap --server "npx @mcp/server-github" --mtp-describe'
|
|
10862
10865
|
},
|
|
10863
10866
|
{
|
|
10864
10867
|
description: "Call a tool on a stdio server",
|
|
@@ -10866,7 +10869,7 @@ function selfDescribe() {
|
|
|
10866
10869
|
},
|
|
10867
10870
|
{
|
|
10868
10871
|
description: "Describe an HTTP MCP server",
|
|
10869
|
-
command: "mtpcli wrap --url http://localhost:3000/mcp --describe"
|
|
10872
|
+
command: "mtpcli wrap --url http://localhost:3000/mcp --mtp-describe"
|
|
10870
10873
|
},
|
|
10871
10874
|
{
|
|
10872
10875
|
description: "Call a tool on an HTTP server",
|
|
@@ -10876,7 +10879,7 @@ function selfDescribe() {
|
|
|
10876
10879
|
},
|
|
10877
10880
|
{
|
|
10878
10881
|
name: "validate",
|
|
10879
|
-
description: "Validate a tool's --describe output against the MTP spec",
|
|
10882
|
+
description: "Validate a tool's --mtp-describe output against the MTP spec",
|
|
10880
10883
|
args: [
|
|
10881
10884
|
{
|
|
10882
10885
|
name: "tool",
|
|
@@ -10919,7 +10922,7 @@ function selfDescribe() {
|
|
|
10919
10922
|
},
|
|
10920
10923
|
{
|
|
10921
10924
|
name: "completions",
|
|
10922
|
-
description: "Generate shell completions for a --describe-compatible tool",
|
|
10925
|
+
description: "Generate shell completions for a --mtp-describe-compatible tool",
|
|
10923
10926
|
args: [
|
|
10924
10927
|
{
|
|
10925
10928
|
name: "shell",
|
|
@@ -10954,126 +10957,122 @@ function selfDescribe() {
|
|
|
10954
10957
|
};
|
|
10955
10958
|
console.log(JSON.stringify(cleanJson(schema), null, 2));
|
|
10956
10959
|
}
|
|
10957
|
-
var
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
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"
|
|
10960
|
+
var program2 = new Command().name("mtpcli").version(VERSION).description("Unified CLI for discovering, authenticating, and bridging --mtp-describe-compatible tools").option("--mtp-describe", "Print self-describing JSON (MTP spec)").action(async (opts) => {
|
|
10961
|
+
if (opts.mtpDescribe) {
|
|
10962
|
+
selfDescribe();
|
|
10963
|
+
return;
|
|
10964
|
+
}
|
|
10965
|
+
program2.help();
|
|
10966
|
+
});
|
|
10967
|
+
program2.command("search").description("Search across --mtp-describe-compatible tools").argument("<query>", "Search query").option("--json", "Output as JSON", false).option("--scan-path", "Scan PATH for --mtp-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) => {
|
|
10968
|
+
const { search: search2, loadSchemas: loadSchemas2, scanPath: scanPath2 } = await Promise.resolve().then(() => (init_search(), exports_search));
|
|
10969
|
+
const schemas = opts.scanPath ? await scanPath2(parseInt(opts.jobs, 10)) : await loadSchemas2(tools);
|
|
10970
|
+
if (schemas.length === 0) {
|
|
10971
|
+
process.stderr.write(`no tools found. Try: mtpcli search --scan-path "query"
|
|
10973
10972
|
`);
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10973
|
+
return;
|
|
10974
|
+
}
|
|
10975
|
+
const results = search2(query, schemas);
|
|
10976
|
+
if (results.length === 0) {
|
|
10977
|
+
process.stderr.write(`no results for "${query}"
|
|
10979
10978
|
`);
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
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;
|
|
10979
|
+
return;
|
|
10980
|
+
}
|
|
10981
|
+
if (opts.json) {
|
|
10982
|
+
console.log(JSON.stringify(results, null, 2));
|
|
10983
|
+
} else {
|
|
10984
|
+
for (const r of results) {
|
|
10985
|
+
console.log(`${r.score.toFixed(1).padStart(6)} ${r.tool} ${r.command} ${r.description}`);
|
|
10996
10986
|
}
|
|
10997
|
-
|
|
10998
|
-
|
|
10987
|
+
}
|
|
10988
|
+
});
|
|
10989
|
+
var authCmd = program2.command("auth").description("Manage authentication for tools");
|
|
10990
|
+
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) => {
|
|
10991
|
+
if (opts.url) {
|
|
10992
|
+
const { mcpOAuthFlow: mcpOAuthFlow3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
|
|
10993
|
+
await mcpOAuthFlow3(opts.url, "", opts.clientId);
|
|
10994
|
+
return;
|
|
10995
|
+
}
|
|
10996
|
+
if (!tool) {
|
|
10997
|
+
process.stderr.write(`error: tool name is required (or use --url)
|
|
10999
10998
|
`);
|
|
11000
|
-
|
|
11001
|
-
|
|
11002
|
-
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
|
|
11010
|
-
|
|
10999
|
+
process.exit(1);
|
|
11000
|
+
}
|
|
11001
|
+
const { runLogin: runLogin3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
|
|
11002
|
+
await runLogin3(tool, opts.provider, opts.token);
|
|
11003
|
+
});
|
|
11004
|
+
authCmd.command("logout").description("Log out from a tool").argument("[tool]", "Tool name").option("--url <url>", "HTTP MCP server URL").action(async (tool, opts) => {
|
|
11005
|
+
if (opts.url) {
|
|
11006
|
+
const { mcpAuthLogout: mcpAuthLogout3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
|
|
11007
|
+
const deleted = mcpAuthLogout3(opts.url);
|
|
11008
|
+
if (deleted) {
|
|
11009
|
+
process.stderr.write(`Logged out from ${opts.url}
|
|
11011
11010
|
`);
|
|
11012
|
-
|
|
11013
|
-
|
|
11011
|
+
} else {
|
|
11012
|
+
process.stderr.write(`No tokens found for ${opts.url}
|
|
11014
11013
|
`);
|
|
11015
|
-
}
|
|
11016
|
-
return;
|
|
11017
11014
|
}
|
|
11018
|
-
|
|
11019
|
-
|
|
11015
|
+
return;
|
|
11016
|
+
}
|
|
11017
|
+
if (!tool) {
|
|
11018
|
+
process.stderr.write(`error: tool name is required (or use --url)
|
|
11020
11019
|
`);
|
|
11021
|
-
|
|
11022
|
-
|
|
11023
|
-
|
|
11024
|
-
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
|
|
11028
|
-
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
|
|
11032
|
-
|
|
11033
|
-
|
|
11020
|
+
process.exit(1);
|
|
11021
|
+
}
|
|
11022
|
+
const { runLogout: runLogout3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
|
|
11023
|
+
await runLogout3(tool);
|
|
11024
|
+
});
|
|
11025
|
+
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) => {
|
|
11026
|
+
if (opts.url) {
|
|
11027
|
+
const { mcpAuthStatus: mcpAuthStatus3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
|
|
11028
|
+
console.log(JSON.stringify(mcpAuthStatus3(opts.url), null, 2));
|
|
11029
|
+
return;
|
|
11030
|
+
}
|
|
11031
|
+
if (!tool) {
|
|
11032
|
+
process.stderr.write(`error: tool name is required (or use --url)
|
|
11034
11033
|
`);
|
|
11035
|
-
|
|
11036
|
-
|
|
11037
|
-
|
|
11038
|
-
|
|
11039
|
-
|
|
11040
|
-
|
|
11041
|
-
|
|
11042
|
-
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
|
|
11034
|
+
process.exit(1);
|
|
11035
|
+
}
|
|
11036
|
+
const { runStatus: runStatus3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
|
|
11037
|
+
await runStatus3(tool);
|
|
11038
|
+
});
|
|
11039
|
+
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) => {
|
|
11040
|
+
if (opts.url) {
|
|
11041
|
+
const { mcpAuthToken: mcpAuthToken3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
|
|
11042
|
+
const t = await mcpAuthToken3(opts.url);
|
|
11043
|
+
if (!t) {
|
|
11044
|
+
throw new Error(`no valid token for '${opts.url}'. Run: mtpcli auth login --url ${opts.url}`);
|
|
11045
|
+
}
|
|
11046
|
+
console.log(t);
|
|
11047
|
+
return;
|
|
11048
|
+
}
|
|
11049
|
+
if (!tool) {
|
|
11050
|
+
process.stderr.write(`error: tool name is required (or use --url)
|
|
11052
11051
|
`);
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
|
|
11052
|
+
process.exit(1);
|
|
11053
|
+
}
|
|
11054
|
+
const { runToken: runToken3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
|
|
11055
|
+
await runToken3(tool);
|
|
11056
|
+
});
|
|
11057
|
+
authCmd.command("env").description("Print shell export statement for eval").argument("<tool>", "Tool name").action(async (tool) => {
|
|
11058
|
+
const { runEnv: runEnv3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
|
|
11059
|
+
await runEnv3(tool);
|
|
11060
|
+
});
|
|
11061
|
+
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) => {
|
|
11062
|
+
if (opts.url) {
|
|
11063
|
+
const { mcpAuthRefresh: mcpAuthRefresh3 } = await Promise.resolve().then(() => (init_mcp_oauth(), exports_mcp_oauth));
|
|
11064
|
+
await mcpAuthRefresh3(opts.url);
|
|
11065
|
+
return;
|
|
11066
|
+
}
|
|
11067
|
+
if (!tool) {
|
|
11068
|
+
process.stderr.write(`error: tool name is required (or use --url)
|
|
11070
11069
|
`);
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11075
|
-
|
|
11076
|
-
|
|
11070
|
+
process.exit(1);
|
|
11071
|
+
}
|
|
11072
|
+
const { runRefresh: runRefresh3 } = await Promise.resolve().then(() => (init_auth2(), exports_auth2));
|
|
11073
|
+
await runRefresh3(tool);
|
|
11074
|
+
});
|
|
11075
|
+
program2.command("serve").description("Serve CLI tools as an MCP server (cli2mcp bridge)").requiredOption("--tool <names...>", "Tool(s) to serve").addHelpText("after", `
|
|
11077
11076
|
This command is meant to be used as an MCP server, not run directly.
|
|
11078
11077
|
Add it to your MCP client config (e.g. ~/.claude.json):
|
|
11079
11078
|
|
|
@@ -11087,12 +11086,12 @@ Add it to your MCP client config (e.g. ~/.claude.json):
|
|
|
11087
11086
|
}
|
|
11088
11087
|
}
|
|
11089
11088
|
|
|
11090
|
-
Any CLI tool on your PATH that supports --describe can be served.
|
|
11089
|
+
Any CLI tool on your PATH that supports --mtp-describe can be served.
|
|
11091
11090
|
Multiple tools can be combined into a single MCP server:
|
|
11092
11091
|
|
|
11093
11092
|
mtpcli serve --tool tool1 --tool tool2`).action(async (opts) => {
|
|
11094
|
-
|
|
11095
|
-
|
|
11093
|
+
if (process.stdin.isTTY) {
|
|
11094
|
+
process.stderr.write(`Error: 'mtpcli serve' is an MCP server and should not be run directly.
|
|
11096
11095
|
` + `Add it to your MCP client config instead. For example, in ~/.claude.json:
|
|
11097
11096
|
|
|
11098
11097
|
` + ` {
|
|
@@ -11107,57 +11106,51 @@ Multiple tools can be combined into a single MCP server:
|
|
|
11107
11106
|
|
|
11108
11107
|
` + `Run 'mtpcli serve --help' for more details.
|
|
11109
11108
|
`);
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11116
|
-
|
|
11117
|
-
|
|
11118
|
-
`);
|
|
11119
|
-
process.exit(1);
|
|
11120
|
-
}
|
|
11121
|
-
if (!opts.server && !opts.url) {
|
|
11122
|
-
process.stderr.write(`error: one of --server or --url is required
|
|
11109
|
+
process.exit(1);
|
|
11110
|
+
}
|
|
11111
|
+
const { run: run5 } = await Promise.resolve().then(() => (init_serve(), exports_serve));
|
|
11112
|
+
await run5(opts.tool);
|
|
11113
|
+
});
|
|
11114
|
+
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("--mtp-describe", "Output --mtp-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) => {
|
|
11115
|
+
if (opts.server && opts.url) {
|
|
11116
|
+
process.stderr.write(`error: --server and --url are mutually exclusive
|
|
11123
11117
|
`);
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
|
|
11118
|
+
process.exit(1);
|
|
11119
|
+
}
|
|
11120
|
+
if (!opts.server && !opts.url) {
|
|
11121
|
+
process.stderr.write(`error: one of --server or --url is required
|
|
11128
11122
|
`);
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11123
|
+
process.exit(1);
|
|
11124
|
+
}
|
|
11125
|
+
if (opts.header && !opts.url) {
|
|
11126
|
+
process.stderr.write(`error: --header requires --url
|
|
11133
11127
|
`);
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
|
|
11137
|
-
|
|
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}
|
|
11128
|
+
process.exit(1);
|
|
11129
|
+
}
|
|
11130
|
+
if (opts.clientId && !opts.url) {
|
|
11131
|
+
process.stderr.write(`error: --client-id requires --url
|
|
11155
11132
|
`);
|
|
11156
11133
|
process.exit(1);
|
|
11157
11134
|
}
|
|
11135
|
+
const { run: run5 } = await Promise.resolve().then(() => (init_wrap(), exports_wrap));
|
|
11136
|
+
await run5(opts.server, opts.url, opts.mtpDescribe, toolName, args, opts.header ?? [], opts.clientId);
|
|
11158
11137
|
});
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11138
|
+
program2.command("validate").description("Validate a tool's --mtp-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) => {
|
|
11139
|
+
const { run: run5 } = await Promise.resolve().then(() => (init_validate(), exports_validate));
|
|
11140
|
+
await run5(tool, {
|
|
11141
|
+
json: opts.json,
|
|
11142
|
+
stdin: opts.stdin,
|
|
11143
|
+
skipHelp: opts.skipHelp
|
|
11144
|
+
});
|
|
11145
|
+
});
|
|
11146
|
+
program2.command("completions").description("Generate shell completions from --mtp-describe output").argument("<shell>", "Shell type (bash, zsh, fish)").argument("<tool>", "Tool name").action(async (shell, tool) => {
|
|
11147
|
+
const { run: run5 } = await Promise.resolve().then(() => (init_completions(), exports_completions));
|
|
11148
|
+
await run5(shell, tool);
|
|
11149
|
+
});
|
|
11150
|
+
try {
|
|
11151
|
+
await program2.parseAsync(process.argv);
|
|
11152
|
+
} catch (e) {
|
|
11153
|
+
process.stderr.write(`error: ${e instanceof Error ? e.message : e}
|
|
11154
|
+
`);
|
|
11155
|
+
process.exit(1);
|
|
11156
|
+
}
|