@tronsfey/ucli 0.5.1 → 0.5.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.
package/README.zh.md CHANGED
@@ -20,7 +20,7 @@
20
20
  - **发现** 注册在 ucli 服务端上的 OpenAPI 服务
21
21
  - **执行** API 操作,无需直接处理凭据
22
22
  - **本地缓存** 规范,减少网络请求
23
- - **调用** MCP 服务器工具,使用 `ucli mcp run`
23
+ - **调用** MCP 服务器工具,使用 `ucli mcp <server> invoketool <tool>`
24
24
 
25
25
  认证凭据(Bearer Token、API 密钥、OAuth2 密钥、MCP 请求头/环境变量)在服务端加密存储,运行时以环境变量或请求头方式注入——**永不落盘**,也不会出现在进程列表中。
26
26
 
@@ -37,7 +37,7 @@ sequenceDiagram
37
37
  Agent->>CLI: ucli configure --server URL --token JWT
38
38
  CLI->>CLI: 保存配置(OS 配置目录)
39
39
 
40
- Agent->>CLI: ucli services list
40
+ Agent->>CLI: ucli listoas
41
41
  CLI->>Cache: 检查本地缓存(TTL)
42
42
  alt 缓存未命中
43
43
  CLI->>Server: GET /api/v1/oas(Bearer JWT)
@@ -47,7 +47,7 @@ sequenceDiagram
47
47
  Cache-->>CLI: OAS 列表
48
48
  CLI-->>Agent: 表格 / JSON 输出
49
49
 
50
- Agent->>CLI: ucli run --service payments --operation createPayment --params '{...}'
50
+ Agent->>CLI: ucli oas payments invokeapi createPayment --data '{...}'
51
51
  CLI->>Server: GET /api/v1/oas/payments(Bearer JWT)
52
52
  Server-->>CLI: OAS 规范 + 解密认证配置(TLS)
53
53
  CLI->>CLI: 将认证配置注入 ENV 变量
@@ -55,7 +55,7 @@ sequenceDiagram
55
55
  API-->>CLI: HTTP 响应
56
56
  CLI-->>Agent: 格式化输出(JSON / 表格 / YAML)
57
57
 
58
- Agent->>CLI: ucli mcp run my-server get_weather --city Beijing
58
+ Agent->>CLI: ucli mcp my-server invoketool get_weather --data '{"city":"Beijing"}'
59
59
  CLI->>Server: GET /api/v1/mcp/my-server(Bearer JWT)
60
60
  Server-->>CLI: McpEntry + 解密认证配置(TLS)
61
61
  CLI->>CLI: 将认证信息注入 mcp2cli 配置(headers/env)
@@ -79,13 +79,13 @@ pnpm add -g @tronsfey/ucli
79
79
  ucli configure --server http://localhost:3000 --token <group-jwt>
80
80
 
81
81
  # 2. 列出可用服务
82
- ucli services list
82
+ ucli listoas
83
83
 
84
84
  # 3. 查看服务的操作列表
85
- ucli services info payments
85
+ ucli oas payments listapi
86
86
 
87
87
  # 4. 执行操作
88
- ucli run --service payments --operation getPetById --params '{"petId": 42}'
88
+ ucli oas payments invokeapi getPetById --params '{"petId": 42}'
89
89
  ```
90
90
 
91
91
  ## 命令参考
@@ -109,12 +109,12 @@ ucli configure --server <url> --token <jwt>
109
109
 
110
110
  ---
111
111
 
112
- ### `services list`
112
+ ### `listoas`
113
113
 
114
114
  列出当前群组可访问的所有 OpenAPI 服务。
115
115
 
116
116
  ```bash
117
- ucli services list [--format table|json|yaml] [--refresh]
117
+ ucli listoas [--format table|json|yaml] [--refresh]
118
118
  ```
119
119
 
120
120
  | 参数 | 默认值 | 说明 |
@@ -122,119 +122,150 @@ ucli services list [--format table|json|yaml] [--refresh]
122
122
  | `--format` | `table` | 输出格式:`table`、`json` 或 `yaml` |
123
123
  | `--refresh` | `false` | 绕过本地缓存,从服务器重新拉取 |
124
124
 
125
- **示例输出(table):**
125
+ ---
126
126
 
127
- ```
128
- NAME DESCRIPTION CACHE TTL
129
- payments 支付服务 API 3600s
130
- inventory 库存管理 1800s
131
- crm CRM 操作 7200s
132
- ```
127
+ ### `oas <service> info`
133
128
 
134
- **示例输出(json):**
129
+ 显示指定服务的详细信息。
135
130
 
136
- ```json
137
- [
138
- { "name": "payments", "description": "支付服务 API", "cacheTtl": 3600 },
139
- { "name": "inventory", "description": "库存管理", "cacheTtl": 1800 }
140
- ]
131
+ ```bash
132
+ ucli oas <service> info [--format json|table|yaml]
141
133
  ```
142
134
 
143
135
  ---
144
136
 
145
- ### `services info <name>`
137
+ ### `oas <service> listapi`
146
138
 
147
- 显示指定服务的详细信息(包括可用操作列表)。
139
+ 列出指定服务的所有可用 API 操作。
148
140
 
149
141
  ```bash
150
- ucli services info <service-name> [--format table|json|yaml]
142
+ ucli oas <service> listapi [--format json|table|yaml]
151
143
  ```
152
144
 
153
- | 参数 | 说明 |
154
- |------|------|
155
- | `<name>` | 服务名称(来自 `services list`) |
156
- | `--format` | 输出格式(默认 `table`) |
145
+ ---
146
+
147
+ ### `oas <service> apiinfo <api>`
148
+
149
+ 显示指定 API 操作的详细输入输出参数信息。
150
+
151
+ ```bash
152
+ ucli oas <service> apiinfo <api>
153
+ ```
157
154
 
158
155
  ---
159
156
 
160
- ### `run`
157
+ ### `oas <service> invokeapi <api>`
161
158
 
162
159
  执行 OpenAPI 规范中定义的单个 API 操作。
163
160
 
164
161
  ```bash
165
- ucli run --service <name> --operation <operationId> [选项]
162
+ ucli oas <service> invokeapi <api> [选项]
166
163
  ```
167
164
 
168
165
  | 参数 | 必填 | 说明 |
169
166
  |------|------|------|
170
- | `--service` | | 服务名称(来自 `services list`) |
171
- | `--operation` | | OpenAPI 规范中的 `operationId` |
172
- | `--params` | 否 | JSON 字符串(路径参数、查询参数、请求体合并传入) |
167
+ | `--data` | | 请求体(JSON 字符串或 @文件名) |
168
+ | `--params` | | JSON 字符串(路径参数、查询参数合并传入) |
173
169
  | `--format` | 否 | 输出格式:`json`(默认)、`table`、`yaml` |
174
170
  | `--query` | 否 | JMESPath 表达式,用于过滤响应 |
171
+ | `--machine` | 否 | 结构化 JSON 信封输出(Agent 友好模式) |
172
+ | `--dry-run` | 否 | 预览 HTTP 请求但不执行(隐含 `--machine`) |
175
173
 
176
174
  **示例:**
177
175
 
178
176
  ```bash
179
177
  # GET 带路径参数
180
- ucli run --service petstore --operation getPetById \
181
- --params '{"petId": 42}'
178
+ ucli oas petstore invokeapi getPetById --params '{"petId": 42}'
182
179
 
183
180
  # POST 带请求体
184
- ucli run --service payments --operation createPayment \
185
- --params '{"amount": 100, "currency": "CNY", "recipient": "acct_123"}' \
186
- --format json
181
+ ucli oas payments invokeapi createPayment \
182
+ --data '{"amount": 100, "currency": "CNY", "recipient": "acct_123"}'
187
183
 
188
184
  # 使用 JMESPath 过滤结果
189
- ucli run --service inventory --operation listProducts \
185
+ ucli oas inventory invokeapi listProducts \
190
186
  --params '{"category": "electronics"}' \
191
187
  --query 'items[?price < `500`].name'
192
188
 
193
- # 从文件读取参数
194
- ucli run --service crm --operation createContact \
195
- --params "@./contact.json"
189
+ # Agent 友好结构化输出
190
+ ucli oas payments invokeapi listTransactions --machine
191
+
192
+ # 预览请求但不执行
193
+ ucli oas payments invokeapi createPayment --dry-run \
194
+ --data '{"amount": 5000, "currency": "CNY"}'
196
195
  ```
197
196
 
198
197
  ---
199
198
 
200
- ### `mcp list`
199
+ ### `listmcp`
201
200
 
202
201
  列出当前群组可访问的所有 MCP 服务器。
203
202
 
204
203
  ```bash
205
- ucli mcp list [--format table|json|yaml]
204
+ ucli listmcp [--format table|json|yaml]
206
205
  ```
207
206
 
208
207
  ---
209
208
 
210
- ### `mcp tools <server>`
209
+ ### `mcp <server> listtool`
211
210
 
212
211
  列出指定 MCP 服务器上的可用工具。
213
212
 
214
213
  ```bash
215
- ucli mcp tools <server-name> [--format table|json]
214
+ ucli mcp <server> listtool [--format table|json|yaml]
216
215
  ```
217
216
 
218
217
  ---
219
218
 
220
- ### `mcp run <server> <tool> [args...]`
219
+ ### `mcp <server> toolinfo <tool>`
220
+
221
+ 查看 MCP 服务器上指定工具的详细参数模式。
222
+
223
+ ```bash
224
+ ucli mcp <server> toolinfo <tool> [--json]
225
+ ```
226
+
227
+ | 参数 | 说明 |
228
+ |------|------|
229
+ | `<server>` | MCP 服务器名称(来自 `listmcp`) |
230
+ | `<tool>` | 工具名称(来自 `mcp <server> listtool`) |
231
+ | `--json` | 以 JSON 格式输出完整模式(适合 Agent 消费) |
232
+
233
+ **示例:**
234
+
235
+ ```bash
236
+ # 人类可读的工具描述
237
+ ucli mcp weather toolinfo get_forecast
238
+
239
+ # JSON 模式(适合 Agent 内省)
240
+ ucli mcp weather toolinfo get_forecast --json
241
+ ```
242
+
243
+ ---
244
+
245
+ ### `mcp <server> invoketool <tool>`
221
246
 
222
247
  在 MCP 服务器上执行指定工具。
223
248
 
224
249
  ```bash
225
- ucli mcp run <server-name> <tool-name> [args...]
250
+ ucli mcp <server> invoketool <tool> [--data <json>] [--json]
226
251
  ```
227
252
 
228
- 参数以 `key=value` 形式传入。
253
+ | 参数 | 说明 |
254
+ |------|------|
255
+ | `--data` | 以 JSON 对象形式传入工具参数 |
256
+ | `--json` | 结构化 JSON 输出 |
229
257
 
230
258
  **示例:**
231
259
 
232
260
  ```bash
233
261
  # 调用天气工具
234
- ucli mcp run weather get_forecast location="北京" units=metric
262
+ ucli mcp weather invoketool get_forecast --data '{"location": "北京", "units": "metric"}'
235
263
 
236
264
  # 调用搜索工具
237
- ucli mcp run search-server web_search query="ucli MCP" limit=5
265
+ ucli mcp search-server invoketool web_search --data '{"query": "ucli MCP", "limit": 5}'
266
+
267
+ # 获取结构化 JSON 输出
268
+ ucli mcp weather invoketool get_forecast --json --data '{"location": "北京"}'
238
269
  ```
239
270
 
240
271
  ---
@@ -275,7 +306,7 @@ ucli help
275
306
  - OAS 条目以 JSON 文件形式缓存到 OS 临时目录(`ucli/` 子目录)
276
307
  - 每个条目的缓存 TTL 由服务端管理员通过 `cacheTtl` 字段设置(单位:秒)
277
308
  - 过期条目在下次访问时自动重新拉取
278
- - 强制刷新:`ucli refresh` 或在 `services list` 时添加 `--refresh`
309
+ - 强制刷新:`ucli refresh` 或在 `listoas` 时添加 `--refresh`
279
310
 
280
311
  ## 认证处理
281
312
 
@@ -300,28 +331,43 @@ AI 智能体将 `ucli` 作为技能使用时,推荐的工作流程:
300
331
 
301
332
  ```bash
302
333
  # 第一步:发现可用服务
303
- ucli services list --format json
334
+ ucli listoas --format json
304
335
 
305
336
  # 第二步:查看服务支持的操作
306
- ucli services info <service-name> --format json
337
+ ucli oas <service-name> listapi --format json
338
+
339
+ # 第三步:查看具体 API 的详细参数
340
+ ucli oas <service-name> apiinfo <api>
307
341
 
308
- # 第三步:执行操作
309
- ucli run --service <name> --operation <operationId> \
310
- --params '{ ... }' --format json
342
+ # 第四步:预览请求(dry-run,不执行)
343
+ ucli oas <service-name> invokeapi <api> --dry-run \
344
+ --data '{ ... }'
311
345
 
312
- # 第四步:用 JMESPath 过滤结果
313
- ucli run --service inventory --operation listProducts \
346
+ # 第五步:执行操作并获取结构化输出
347
+ ucli oas <service-name> invokeapi <api> \
348
+ --data '{ ... }' --machine
349
+
350
+ # 第六步:用 JMESPath 过滤结果
351
+ ucli oas inventory invokeapi listProducts \
314
352
  --query 'items[?inStock == `true`] | [0:5]'
315
353
 
316
- # 第五步:链式操作(将前一个结果作为下一个的输入)
317
- PRODUCT_ID=$(ucli run --service inventory --operation listProducts \
354
+ # 第七步:链式操作(将前一个结果作为下一个的输入)
355
+ PRODUCT_ID=$(ucli oas inventory invokeapi listProducts \
318
356
  --query 'items[0].id' | tr -d '"')
319
- ucli run --service orders --operation createOrder \
320
- --params "{\"productId\": \"$PRODUCT_ID\", \"quantity\": 1}"
357
+ ucli oas orders invokeapi createOrder \
358
+ --data "{\"productId\": \"$PRODUCT_ID\", \"quantity\": 1}"
359
+
360
+ # 第八步:MCP — 查看工具参数模式,然后以 JSON 输入调用
361
+ ucli mcp weather toolinfo get_forecast --json
362
+ ucli mcp weather invoketool get_forecast --data '{"location": "北京", "units": "metric"}'
321
363
  ```
322
364
 
323
365
  **智能体使用建议:**
324
- - 始终先运行 `services list` 发现可用服务
366
+ - 始终先运行 `ucli listoas` 发现可用服务
367
+ - 使用 `--machine` 获取结构化信封输出
368
+ - 使用 `--dry-run` 预览请求,避免误操作
369
+ - 使用 `ucli mcp <server> toolinfo <tool> --json` 发现工具参数模式
370
+ - 使用 `--data` 传入 JSON 输入(适合复杂或嵌套参数)
325
371
  - 使用 `--format json` 方便程序解析
326
372
  - 使用 `--query` 配合 JMESPath 提取特定字段
327
373
  - 注意列表操作的分页字段(`nextPage`、`totalCount`)
@@ -332,9 +378,9 @@ ucli run --service orders --operation createOrder \
332
378
  | 错误 | 可能原因 | 解决方法 |
333
379
  |------|---------|---------|
334
380
  | `Unauthorized (401)` | JWT 已过期或被吊销 | 联系管理员获取新令牌 |
335
- | `Service not found` | 服务名拼写错误或不在当前群组 | 运行 `services list` 查看可用服务 |
336
- | `Operation not found` | 无效的 `operationId` | 运行 `services info <name>` 查看有效操作 |
337
- | `MCP server not found` | MCP 服务器名拼写错误或不在当前群组 | 运行 `ucli mcp list` 查看可用服务器 |
338
- | `Tool not found` | 无效的工具名 | 运行 `ucli mcp tools <server>` 查看可用工具 |
381
+ | `Service not found` | 服务名拼写错误或不在当前群组 | 运行 `ucli listoas` 查看可用服务 |
382
+ | `Operation not found` | 无效的 `operationId` | 运行 `ucli oas <service> listapi` 查看有效操作 |
383
+ | `MCP server not found` | MCP 服务器名拼写错误或不在当前群组 | 运行 `ucli listmcp` 查看可用服务器 |
384
+ | `Tool not found` | 无效的工具名 | 运行 `ucli mcp <server> listtool` 查看可用工具 |
339
385
  | `Connection refused` | 服务器未运行或 URL 错误 | 用 `ucli configure` 检查服务器 URL |
340
386
  | `Cache error` | 临时目录权限问题 | 运行 `ucli refresh` 重置缓存 |
@@ -36662,20 +36662,22 @@ var require_streamableHttp = __commonJS({
36662
36662
  }
36663
36663
  });
36664
36664
 
36665
- // ../../node_modules/.pnpm/@tronsfey+mcp2cli@1.0.2_zod@4.3.6/node_modules/@tronsfey/mcp2cli/package.json
36665
+ // ../../node_modules/.pnpm/@tronsfey+mcp2cli@1.3.0_zod@4.3.6/node_modules/@tronsfey/mcp2cli/package.json
36666
36666
  var require_package = __commonJS({
36667
- "../../node_modules/.pnpm/@tronsfey+mcp2cli@1.0.2_zod@4.3.6/node_modules/@tronsfey/mcp2cli/package.json"(exports, module) {
36667
+ "../../node_modules/.pnpm/@tronsfey+mcp2cli@1.3.0_zod@4.3.6/node_modules/@tronsfey/mcp2cli/package.json"(exports, module) {
36668
36668
  module.exports = {
36669
36669
  name: "@tronsfey/mcp2cli",
36670
- version: "1.0.2",
36670
+ version: "1.3.0",
36671
36671
  description: "Command-line proxy for any MCP server \u2014 call tools directly from the terminal",
36672
36672
  main: "dist/index.js",
36673
36673
  bin: {
36674
- mcp2cli: "./bin/mcp2cli"
36674
+ mcp2cli: "./bin/mcp2cli",
36675
+ ucli: "./bin/mcp2cli"
36675
36676
  },
36676
36677
  files: [
36677
36678
  "dist/",
36678
36679
  "bin/",
36680
+ "CLAUDE.md",
36679
36681
  "README.md",
36680
36682
  "LICENSE"
36681
36683
  ],
@@ -36748,9 +36750,9 @@ var require_package = __commonJS({
36748
36750
  }
36749
36751
  });
36750
36752
 
36751
- // ../../node_modules/.pnpm/@tronsfey+mcp2cli@1.0.2_zod@4.3.6/node_modules/@tronsfey/mcp2cli/dist/client/index.js
36753
+ // ../../node_modules/.pnpm/@tronsfey+mcp2cli@1.3.0_zod@4.3.6/node_modules/@tronsfey/mcp2cli/dist/client/index.js
36752
36754
  var require_client3 = __commonJS({
36753
- "../../node_modules/.pnpm/@tronsfey+mcp2cli@1.0.2_zod@4.3.6/node_modules/@tronsfey/mcp2cli/dist/client/index.js"(exports) {
36755
+ "../../node_modules/.pnpm/@tronsfey+mcp2cli@1.3.0_zod@4.3.6/node_modules/@tronsfey/mcp2cli/dist/client/index.js"(exports) {
36754
36756
  Object.defineProperty(exports, "__esModule", { value: true });
36755
36757
  exports.parseCommand = parseCommand;
36756
36758
  exports.isTransportUnsupported = isTransportUnsupported;
@@ -36814,11 +36816,14 @@ var require_client3 = __commonJS({
36814
36816
  ...Object.fromEntries(Object.entries(process.env).filter(([, v]) => v !== void 0)),
36815
36817
  ...config.env ?? {}
36816
36818
  };
36819
+ if (verbose) {
36820
+ console.error(`[debug] Connecting via stdio: ${command} ${args.join(" ")}`);
36821
+ }
36817
36822
  const client2 = makeClient();
36818
36823
  const transport = new stdio_js_1.StdioClientTransport({ command, args, env });
36819
36824
  await client2.connect(transport);
36820
36825
  if (verbose) {
36821
- console.error(`[mcp2cli] Connected via stdio: ${config.command}`);
36826
+ console.error(`[debug] Connected via stdio successfully`);
36822
36827
  }
36823
36828
  return client2;
36824
36829
  }
@@ -36827,6 +36832,9 @@ var require_client3 = __commonJS({
36827
36832
  }
36828
36833
  const serverUrl = new URL(config.url);
36829
36834
  const headers = config.headers ?? {};
36835
+ if (verbose) {
36836
+ console.error(`[debug] Attempting Streamable HTTP connection to ${config.url}`);
36837
+ }
36830
36838
  try {
36831
36839
  const client2 = makeClient();
36832
36840
  const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(serverUrl, {
@@ -36834,28 +36842,34 @@ var require_client3 = __commonJS({
36834
36842
  });
36835
36843
  await client2.connect(transport);
36836
36844
  if (verbose) {
36837
- console.error(`[mcp2cli] Connected via Streamable HTTP: ${config.url}`);
36845
+ console.error(`[debug] Connected via Streamable HTTP successfully`);
36838
36846
  }
36839
36847
  return client2;
36840
36848
  } catch (err) {
36849
+ if (verbose) {
36850
+ console.error(`[debug] Streamable HTTP failed: ${err.message}`);
36851
+ }
36841
36852
  if (!isTransportUnsupported(err)) {
36842
36853
  throw err;
36843
36854
  }
36844
36855
  if (verbose) {
36845
- console.error(`[mcp2cli] Streamable HTTP not supported, falling back to SSE`);
36856
+ console.error(`[debug] Falling back to SSE transport\u2026`);
36846
36857
  }
36847
36858
  }
36859
+ if (verbose) {
36860
+ console.error(`[debug] Attempting SSE connection to ${config.url}`);
36861
+ }
36848
36862
  const client = makeClient();
36849
36863
  const sseTransport = new sse_js_1.SSEClientTransport(serverUrl, {
36850
36864
  requestInit: { headers }
36851
36865
  });
36852
36866
  await client.connect(sseTransport);
36853
36867
  if (verbose) {
36854
- console.error(`[mcp2cli] Connected via SSE: ${config.url}`);
36868
+ console.error(`[debug] Connected via SSE successfully`);
36855
36869
  }
36856
36870
  return client;
36857
36871
  }
36858
36872
  }
36859
36873
  });
36860
36874
  export default require_client3();
36861
- //# sourceMappingURL=client-LCWUZRZX.js.map
36875
+ //# sourceMappingURL=client-Y6NONDCI.js.map