aai-gateway 0.4.3 → 0.5.2

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 CHANGED
@@ -4,55 +4,48 @@
4
4
 
5
5
  AAI Gateway turns many apps, agents, skills, and MCP servers into one MCP server.
6
6
 
7
- You connect your AI tool once. AAI Gateway handles discovery, import, routing, and exposure control behind that single entrypoint.
7
+ ## 核心价值
8
8
 
9
- Why this matters:
9
+ ### 价值 1:自然语言驱动的工具接入
10
10
 
11
- - One MCP connection instead of one MCP per app
12
- - Smaller context through progressive disclosure — AAI Gateway never exposes raw tool definitions upfront
11
+ 安装 AAI Gateway MCP 之后,你可以通过自然语言描述快速接入其他任意 MCP、技能,并操控其他 AI Agent 工具(包括 Claude Code、Codex、OpenCode 等)。
13
12
 
14
- **App-level exposure, not tool-level.** Tools are grouped into apps and only the app interface is visible initially. Users interact through `app:<id>` guides instead of seeing dozens of individual tools.
13
+ AAI Gateway 还集成搜索工具,可以帮助你从权威、主流的网站上搜索官方、安全的 MCP 和技能,并实现一句话安装。
15
14
 
16
- **Two app interfaces, user chooses:**
15
+ ### 价值 2:渐进式披露策略
17
16
 
18
- - `summary` — a natural language description; good for automatic triggering
19
- - `keywords` — a compact keyword set; further reduces context overhead when users reference tools explicitly
17
+ AAI Gateway 不会一次性向大模型上下文中塞入所有工具的描述,而是采用渐进式披露策略:
20
18
 
21
- Both modes keep the full tool capability available downstream it just stays hidden until actually needed.
19
+ **MCP Server 级别**:先只暴露 MCP Server 的整体描述。当大模型发现需要使用某个具体工具时,会先返回工具使用指导,然后 Agent 根据指导调用统一的 `aai:exec` 去执行。`aai:exec` 接受 `appId`、`tool`、`tool args` 作为参数。
22
20
 
23
- - A cleaner path to mix MCP servers, skills, ACP agents, and CLI-backed apps
21
+ **MCP / 技能 描述级别**:提供两个层级的披露策略:
24
22
 
25
- AAI Gateway is for one goal: make tool ecosystems feel smaller, sharper, and easier for agents to use.
23
+ - `summary` 自然语言描述,适合自动触发
24
+ - `keywords` — 紧凑的关键词集合,进一步简化上下文占用
26
25
 
27
- ## How To Use
26
+ 这让 OpenCode 这种需要大量工具和技能的场景下依然能良好运行。
28
27
 
29
- ### 1. Connect Your AI Tool To AAI Gateway
28
+ ## 使用方案
30
29
 
31
- You do not need to preinstall `aai-gateway`.
30
+ ### 1. 安装 AAI Gateway MCP
32
31
 
33
- Use the same style users already know from mainstream MCP setups: launch it through `npx`.
32
+ 你不需要预装 `aai-gateway`。只需将其注册为用户级 MCP 服务器,通过 `npx` 启动即可。
34
33
 
35
- ### Claude Code
36
-
37
- Official docs: <https://code.claude.com/docs/en/mcp>
34
+ #### Claude Code
38
35
 
39
36
  ```bash
40
- claude mcp add --transport stdio aai-gateway -- npx -y aai-gateway
37
+ claude mcp add --scope user --transport stdio aai-gateway -- npx -y aai-gateway
41
38
  ```
42
39
 
43
- ### Codex
44
-
45
- Official docs: <https://developers.openai.com/learn/docs-mcp>
40
+ #### Codex
46
41
 
47
42
  ```bash
48
43
  codex mcp add aai-gateway -- npx -y aai-gateway
49
44
  ```
50
45
 
51
- ### OpenCode
46
+ #### OpenCode
52
47
 
53
- Official docs: <https://opencode.ai/docs/config> and <https://opencode.ai/docs/mcp-servers/>
54
-
55
- Add this to `~/.config/opencode/opencode.json` or your project `opencode.json`:
48
+ `~/.config/opencode/opencode.json` 中添加:
56
49
 
57
50
  ```json
58
51
  {
@@ -67,38 +60,47 @@ Add this to `~/.config/opencode/opencode.json` or your project `opencode.json`:
67
60
  }
68
61
  ```
69
62
 
70
- ### What You Get After Connecting
63
+ ### 2. 搜索并安装 MCP 或技能
64
+
65
+ 如果你不知道该安装哪个 MCP 或技能,可以让 AI 工具调用 `import:search`。
66
+
67
+ `import:search` 会:
68
+
69
+ - 将用户请求转换为搜索关键词
70
+ - 推荐更安全的权威来源优先搜索
71
+ - 将搜索结果规范化为候选列表
72
+ - 为每个候选项生成临时 ID 供用户确认
73
+ - 将确认的项目路由到 `mcp:import` 或 `skill:import` 流程
74
+
75
+ **推荐的搜索来源顺序**:
71
76
 
72
- Once connected, your AI tool can use AAI Gateway tools such as:
77
+ 1. 官方目录:`modelcontextprotocol/registry`、`modelcontextprotocol/servers`、`openai/skills`
78
+ 2. 社区精选列表:`punkpeye/awesome-mcp-servers`、`ComposioHQ/awesome-claude-skills`
79
+ 3. 高审查来源:如 ClawHub 等开放市场(需额外谨慎)
73
80
 
74
- - `remote:discover`
75
- - `aai:exec`
76
- - `mcp:import`
77
- - `skill:import`
78
- - `mcp:refresh`
79
- - `import:config`
81
+ > 注意:推荐列表是首选起点,而非硬性白名单。请勿随意推荐来自不知名小网站工具。对于市场平台,请额外检查维护者身份、仓库活跃度、README 质量和许可证是否可见。
80
82
 
81
- ### 2. Import An MCP Server
83
+ ### 3. 导入 MCP Server
82
84
 
83
- The main workflow is: copy a mainstream MCP config snippet into your AI tool and ask it to import that server through AAI Gateway.
85
+ 主流程:复制主流 MCP 配置片段到 AI 工具,让它通过 AAI Gateway 导入。
84
86
 
85
- The AI tool should:
87
+ AI 工具会:
86
88
 
87
- 1. read the MCP config you pasted
88
- 2. ask you to choose an exposure mode
89
- 3. call `mcp:import`
89
+ 1. 读取你粘贴的 MCP 配置
90
+ 2. 询问你选择暴露模式
91
+ 3. 调用 `mcp:import`
90
92
 
91
- AAI Gateway keeps the import parameters close to normal MCP config shapes:
93
+ AAI Gateway 保持导入参数与标准 MCP 配置格式一致:
92
94
 
93
- - stdio MCP: `command`, `args`, `env`, `cwd`
94
- - remote MCP: `url`, optional `transport`, optional `headers`
95
+ - stdio MCP:`command`、`args`、`env`、`cwd`
96
+ - remote MCP:`url`、可选 `transport`、可选 `headers`
95
97
 
96
- Before import, the AI tool should ask you to choose:
98
+ 导入前请选择暴露模式:
97
99
 
98
- - `summary`: easier automatic triggering
99
- - `keywords`: leaves room for more tools, but usually needs more explicit keyword mentions
100
+ - `summary`:更容易自动触发
101
+ - `keywords`:为更多工具留出空间,但通常需要更明确的关键词提及
100
102
 
101
- Example: import a normal stdio MCP config
103
+ **stdio MCP 示例**:
102
104
 
103
105
  ```json
104
106
  {
@@ -107,7 +109,7 @@ Example: import a normal stdio MCP config
107
109
  }
108
110
  ```
109
111
 
110
- Example: import a normal remote Streamable HTTP MCP config
112
+ **Remote Streamable HTTP MCP 示例**:
111
113
 
112
114
  ```json
113
115
  {
@@ -115,7 +117,7 @@ Example: import a normal remote Streamable HTTP MCP config
115
117
  }
116
118
  ```
117
119
 
118
- Example: import a normal remote SSE MCP config
120
+ **Remote SSE MCP 示例**:
119
121
 
120
122
  ```json
121
123
  {
@@ -124,29 +126,23 @@ Example: import a normal remote SSE MCP config
124
126
  }
125
127
  ```
126
128
 
127
- After import, AAI Gateway returns:
129
+ 导入完成后,AAI Gateway 返回:
128
130
 
129
- - the generated app id
130
- - the generated `keywords`
131
- - the generated `summary`
132
- - the guide tool name: `app:<id>`
131
+ - 生成的 app id
132
+ - 生成的 `keywords`
133
+ - 生成的 `summary`
134
+ - 引导工具名称:`app:<id>`
133
135
 
134
- Important:
136
+ > **重要**:导入后需重启 AI 工具才能使用新导入的工具。重启后,导入的应用将显示为 `app:<id>`,使用 `aai:exec` 执行实际操作。
135
137
 
136
- - Restart your AI tool before using the newly imported tool.
137
- - After restart, the imported app will appear as `app:<id>`.
138
- - Use `aai:exec` to actually run the imported app’s operations.
138
+ ### 4. 导入技能 (Skill)
139
139
 
140
- ### 3. Import A Skill
140
+ 技能导入同样通过 AI 工具完成。告诉 AI 工具调用 `skill:import`,然后提供:
141
141
 
142
- Skills are imported through the AI tool as well.
142
+ - 本地技能路径
143
+ - 或暴露 `SKILL.md` 的远程技能根 URL
143
144
 
144
- Ask the AI tool to call `skill:import`, then give it either:
145
-
146
- - a local skill path
147
- - a remote skill root URL that exposes `SKILL.md`
148
-
149
- Examples:
145
+ **本地技能示例**:
150
146
 
151
147
  ```json
152
148
  {
@@ -154,49 +150,155 @@ Examples:
154
150
  }
155
151
  ```
156
152
 
153
+ **远程技能示例**:
154
+
157
155
  ```json
158
156
  {
159
157
  "url": "https://example.com/skill"
160
158
  }
161
159
  ```
162
160
 
163
- Just like MCP import, skill import returns:
161
+ MCP 导入一样,技能导入返回 `app id`、`keywords`、`summary` 和 `app:<id>` 引导工具名称。
164
162
 
165
- - the generated app id
166
- - generated `keywords`
167
- - generated `summary`
168
- - the guide tool name: `app:<id>`
163
+ 导入后需重启 AI 工具。
169
164
 
170
- Then restart your AI tool before using the imported skill.
165
+ ### 5. 支持的 ACP Agents
171
166
 
172
- ### 4. Supported ACP Agents
167
+ AAI Gateway 还能通过 ACP 控制类应用的 Agent。
173
168
 
174
- AAI Gateway can also control app-like agents through ACP.
175
-
176
- Currently supported ACP agent types:
169
+ 当前支持的 ACP Agent 类型:
177
170
 
178
171
  - OpenCode
179
172
  - Claude Code
180
173
  - Codex
181
174
 
182
- ## App Auto Discovery
175
+ ## 原理
183
176
 
184
- AAI Gateway discovers apps from four places:
177
+ ### 架构图
185
178
 
186
- - desktop descriptors
187
- - web descriptors
188
- - gateway-managed imports
189
- - built-in ACP agent descriptors
179
+ ```
180
+ ┌─────────────────────────────────────────────────────────────┐
181
+ │ AI Agent │
182
+ │ (Claude Code / Codex / OpenCode) │
183
+ └────────────────────────┬────────────────────────────────────┘
184
+ │ One MCP Connection
185
+
186
+ ┌─────────────────────────────────────────────────────────────┐
187
+ │ AAI Gateway │
188
+ │ ┌─────────────────────────────────────────────────────────┐│
189
+ │ │ Progressive Disclosure Layer ││
190
+ │ │ - App-level exposure (not tool-level) ││
191
+ │ │ - Summary / Keywords modes ││
192
+ │ │ - Lazy tool loading on demand ││
193
+ │ └─────────────────────────────────────────────────────────┘│
194
+ │ ┌─────────────────────────────────────────────────────────┐│
195
+ │ │ App Registry ││
196
+ │ │ - MCP Servers - Skills ││
197
+ │ │ - ACP Agents - CLI Tools ││
198
+ │ └─────────────────────────────────────────────────────────┘│
199
+ │ ┌─────────────────────────────────────────────────────────┐│
200
+ │ │ Discovery Layer ││
201
+ │ │ - Desktop Descriptors - Web Descriptors ││
202
+ │ │ - Gateway Imports - Built-in Descriptors ││
203
+ │ └─────────────────────────────────────────────────────────┘│
204
+ └────────────────────────┬────────────────────────────────────┘
205
+ │ Native Protocol
206
+
207
+ ┌─────────────────────────────────────────────────────────────┐
208
+ │ External Apps │
209
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
210
+ │ │ MCP │ │ Skill │ │ ACP │ │ CLI │ │
211
+ │ │ Servers │ │ │ │ Agents │ │ Tools │ │
212
+ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
213
+ └─────────────────────────────────────────────────────────────┘
214
+ ```
190
215
 
191
- ### The AAI Descriptor
216
+ ### 统一抽象:Agent App
217
+
218
+ AAI Gateway 将 MCP、技能、ACP Agent、CLI 工具统一抽象为 **Agent App**。
219
+
220
+ 只要提供一个 App 的描述文件 (`aai.json`),即可接入 AAI Gateway。描述文件告诉 AAI Gateway:
221
+
222
+ - App 是什么
223
+ - 如何连接
224
+ - 如何以低上下文成本暴露
225
+
226
+ ### 描述文件示例
227
+
228
+ #### MCP Server 描述文件
229
+
230
+ ```json
231
+ {
232
+ "schemaVersion": "2.0",
233
+ "version": "1.0.0",
234
+ "app": {
235
+ "name": {
236
+ "default": "Filesystem Server"
237
+ }
238
+ },
239
+ "access": {
240
+ "protocol": "mcp",
241
+ "config": {
242
+ "command": "npx",
243
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
244
+ }
245
+ },
246
+ "exposure": {
247
+ "keywords": ["file", "filesystem", "read", "write"],
248
+ "summary": "Use this app when the user wants to read from or write to the local filesystem."
249
+ }
250
+ }
251
+ ```
252
+
253
+ #### Skill 描述文件
254
+
255
+ ```json
256
+ {
257
+ "schemaVersion": "2.0",
258
+ "version": "1.0.0",
259
+ "app": {
260
+ "name": {
261
+ "default": "Git Commit Skill"
262
+ }
263
+ },
264
+ "access": {
265
+ "protocol": "skill",
266
+ "config": {
267
+ "url": "https://github.com/example/git-commit-skill"
268
+ }
269
+ },
270
+ "exposure": {
271
+ "keywords": ["git", "commit", "version control"],
272
+ "summary": "Use this app when the user wants to create git commits with auto-generated messages."
273
+ }
274
+ }
275
+ ```
192
276
 
193
- The descriptor is a small `aai.json` file. It tells AAI Gateway:
277
+ #### ACP Agent 描述文件
194
278
 
195
- - what the app is
196
- - how to connect to it
197
- - how to expose it at low context cost
279
+ ```json
280
+ {
281
+ "schemaVersion": "2.0",
282
+ "version": "1.0.0",
283
+ "app": {
284
+ "name": {
285
+ "default": "Claude Code"
286
+ }
287
+ },
288
+ "access": {
289
+ "protocol": "acp-agent",
290
+ "config": {
291
+ "agentType": "claude-code"
292
+ }
293
+ },
294
+ "exposure": {
295
+ "keywords": ["claude", "code", "coding", "agent"],
296
+ "summary": "Use this app when the user wants Claude Code to perform coding tasks."
297
+ }
298
+ }
299
+ ```
198
300
 
199
- Minimal example:
301
+ #### CLI 工具描述文件
200
302
 
201
303
  ```json
202
304
  {
@@ -204,7 +306,7 @@ Minimal example:
204
306
  "version": "1.0.0",
205
307
  "app": {
206
308
  "name": {
207
- "default": "Example App"
309
+ "default": "Example CLI"
208
310
  }
209
311
  },
210
312
  "access": {
@@ -220,28 +322,53 @@ Minimal example:
220
322
  }
221
323
  ```
222
324
 
223
- Supported `access.protocol` values today:
325
+ ## 如何将更多 App 预置集成到 AAI Gateway
326
+
327
+ ### 提交 Pull Request
328
+
329
+ 如果你希望 AAI Gateway 默认打包某个 App 的描述文件,可以提交 PR。
224
330
 
225
- - `mcp`
226
- - `skill`
227
- - `acp-agent`
228
- - `cli`
331
+ PR 需要包含:
229
332
 
230
- ### Where To Put `aai.json`
333
+ 1. 描述文件本身
334
+ 2. 安全的发现规则(证明 App 确实已安装)
335
+ 3. 连接配置
336
+ 4. 说明为什么这个集成应该被捆绑
337
+
338
+ 内置 ACP Agent 描述文件位于:
339
+
340
+ - `src/discovery/descriptors/`
341
+
342
+ 它们在以下文件中注册:
343
+
344
+ - `src/discovery/agent-registry.ts`
345
+
346
+ 标准 PR 流程:
347
+
348
+ 1. 添加描述文件
349
+ 2. 添加或更新发现检查
350
+ 3. 在适当的发现源中注册
351
+ 4. 如果新集成面向用户,更新 README
352
+
353
+ 如果你不确定某个集成是否应该被捆绑,请先提交 Issue 讨论。
354
+
355
+ ### 描述文件放置位置
356
+
357
+ AAI Gateway 从以下位置发现 App:
231
358
 
232
359
  #### Web Apps
233
360
 
234
- Publish it at:
361
+ 发布到:
235
362
 
236
- ```text
363
+ ```
237
364
  https://<your-host>/.well-known/aai.json
238
365
  ```
239
366
 
240
- AAI Gateway fetches that path when the user calls `remote:discover`.
367
+ 用户调用 `remote:discover` 时,AAI Gateway 会获取该路径。
241
368
 
242
369
  #### macOS Apps
243
370
 
244
- Recommended locations scanned by the gateway:
371
+ 推荐位置:
245
372
 
246
373
  - `<YourApp>.app/Contents/Resources/aai.json`
247
374
  - `~/Library/Containers/<container>/Data/Library/Application Support/aai.json`
@@ -249,7 +376,7 @@ Recommended locations scanned by the gateway:
249
376
 
250
377
  #### Linux Apps
251
378
 
252
- The gateway scans for `aai.json` under:
379
+ 扫描以下位置:
253
380
 
254
381
  - `/usr/share`
255
382
  - `/usr/local/share`
@@ -257,50 +384,20 @@ The gateway scans for `aai.json` under:
257
384
 
258
385
  #### Windows Apps
259
386
 
260
- The gateway scans for `aai.json` under:
387
+ 扫描以下位置:
261
388
 
262
389
  - `C:\Program Files`
263
390
  - `C:\Program Files (x86)`
264
391
  - `%LOCALAPPDATA%`
265
392
 
266
- ### Descriptor Guidelines
267
-
268
- Keep descriptors small and practical:
269
-
270
- - make `app.name.default` clear
271
- - keep `keywords` short and high-signal
272
- - make `summary` explain when the app should be used
273
- - put detailed capability data in the downstream protocol, not in the descriptor
274
-
275
- If your app already speaks MCP, keep the descriptor minimal and let MCP provide tool detail lazily.
276
-
277
- ## Submit A Pull Request To Preload A Descriptor
278
-
279
- If you want AAI Gateway to ship with a descriptor by default, open a PR.
280
-
281
- What to include:
282
-
283
- - the descriptor itself
284
- - a safe discovery rule that proves the app is actually installed
285
- - the connection config
286
- - a short explanation of why the integration should be bundled
287
-
288
- Today, built-in ACP agent descriptors live in:
289
-
290
- - `src/discovery/descriptors/`
291
-
292
- And they are registered in:
293
-
294
- - `src/discovery/agent-registry.ts`
295
-
296
- For a typical PR:
297
-
298
- 1. Add the descriptor file.
299
- 2. Add or update discovery checks.
300
- 3. Register it in the appropriate discovery source.
301
- 4. Update the README if the new integration is user-facing.
393
+ #### 描述文件编写建议
302
394
 
303
- If you are unsure whether an integration should be bundled, open an issue first.
395
+ - 保持描述文件小而实用
396
+ - `app.name.default` 要清晰
397
+ - `keywords` 要短且高信号
398
+ - `summary` 要解释何时应该使用该 App
399
+ - 详细能力数据放在下游协议中,而非描述文件中
400
+ - 如果你的 App 已使用 MCP,保持描述文件最小化,让 MCP 提供惰性工具详情
304
401
 
305
402
  ## Disclaimer
306
403
 
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as logger, D as createDesktopDiscovery, O as getManagedAppDir, T as AAI_GATEWAY_VERSION, _ as isMcpAccess, a as buildMcpImportConfig, b as getMcpExecutor, c as importSkill, d as upsertSkillRegistryEntry, f as upsertMcpRegistryEntry, i as IMPORT_LIMITS, l as normalizeExposureInput, m as createSecureStorage, n as createGatewayServer, o as buildSkillImportSource, r as EXPOSURE_LIMITS, s as importMcpServer, u as validateImportHeaders, v as isSkillAccess } from "./server-C2U35Fro.js";
2
+ import { A as logger, D as createDesktopDiscovery, O as getManagedAppDir, T as AAI_GATEWAY_VERSION, _ as isMcpAccess, a as buildMcpImportConfig, b as getMcpExecutor, c as importSkill, d as upsertSkillRegistryEntry, f as upsertMcpRegistryEntry, i as IMPORT_LIMITS, l as normalizeExposureInput, m as createSecureStorage, n as createGatewayServer, o as buildSkillImportSource, r as EXPOSURE_LIMITS, s as importMcpServer, u as validateImportHeaders, v as isSkillAccess } from "./server-DQ0nbmQB.js";
3
3
  import { join } from "node:path";
4
4
  import { existsSync, readFileSync } from "node:fs";
5
5
  //#region src/cli.ts
@@ -8,6 +8,11 @@ function parseKeyValue(value, flag) {
8
8
  if (index === -1) throw new Error(`${flag} expects KEY=VALUE`);
9
9
  return [value.slice(0, index), value.slice(index + 1)];
10
10
  }
11
+ function parsePositiveInteger(value, flag) {
12
+ const parsed = Number(value);
13
+ if (!Number.isInteger(parsed) || parsed <= 0) throw new Error(`${flag} expects a positive integer`);
14
+ return parsed;
15
+ }
11
16
  function parseArgs(args) {
12
17
  const dev = args.includes("--dev");
13
18
  if (args.includes("--scan")) return {
@@ -16,9 +21,11 @@ function parseArgs(args) {
16
21
  };
17
22
  if (args[0] === "mcp" && args[1] === "import") {
18
23
  const exposure = parseRequiredExposureArgs(args.slice(2));
24
+ let name;
19
25
  let transport;
20
26
  let url;
21
27
  let launchCommand;
28
+ let timeout;
22
29
  let launchCwd;
23
30
  const launchArgs = [];
24
31
  const launchEnv = {};
@@ -33,6 +40,10 @@ function parseArgs(args) {
33
40
  case "--keyword":
34
41
  i += 1;
35
42
  break;
43
+ case "--name":
44
+ name = next;
45
+ i += 1;
46
+ break;
36
47
  case "--transport":
37
48
  if (next !== "streamable-http" && next !== "sse") throw new Error("--transport must be streamable-http or sse");
38
49
  transport = next;
@@ -46,6 +57,10 @@ function parseArgs(args) {
46
57
  launchCommand = next;
47
58
  i += 1;
48
59
  break;
60
+ case "--timeout":
61
+ timeout = parsePositiveInteger(next, "--timeout");
62
+ i += 1;
63
+ break;
49
64
  case "--arg":
50
65
  launchArgs.push(next);
51
66
  i += 1;
@@ -71,9 +86,11 @@ function parseArgs(args) {
71
86
  "--exposure",
72
87
  "--summary",
73
88
  "--keyword",
89
+ "--name",
74
90
  "--transport",
75
91
  "--url",
76
92
  "--command",
93
+ "--timeout",
77
94
  "--arg",
78
95
  "--env",
79
96
  "--cwd",
@@ -85,9 +102,11 @@ function parseArgs(args) {
85
102
  command: "mcp-import",
86
103
  dev,
87
104
  ...exposure,
105
+ ...name ? { name } : {},
88
106
  transport,
89
107
  url,
90
108
  launchCommand,
109
+ ...timeout !== void 0 ? { timeout } : {},
91
110
  launchArgs,
92
111
  launchEnv,
93
112
  launchCwd,
@@ -136,7 +155,7 @@ function parseArgs(args) {
136
155
  }
137
156
  if (args[0] === "app" && args[1] === "config") {
138
157
  const localId = args[2];
139
- if (!localId) throw new Error("Usage: aai-gateway app config <local-id>");
158
+ if (!localId) throw new Error("Usage: aai-gateway app config <app-id>");
140
159
  let exposure;
141
160
  let summary;
142
161
  const keywords = [];
@@ -223,7 +242,7 @@ Usage:
223
242
  aai-gateway [options]
224
243
  aai-gateway mcp import [options]
225
244
  aai-gateway skill import [options]
226
- aai-gateway app config <local-id> [options]
245
+ aai-gateway app config <app-id> [options]
227
246
 
228
247
  Options:
229
248
  --scan Scan for desktop descriptors and exit
@@ -237,7 +256,9 @@ Shared metadata options:
237
256
  --keyword VALUE Required for import and repeatable, max ${EXPOSURE_LIMITS.keywordCount} items, each max ${EXPOSURE_LIMITS.keywordLength} characters
238
257
 
239
258
  MCP import options:
259
+ --name TEXT Optional app name used for display and app id generation, max ${IMPORT_LIMITS.nameLength} chars
240
260
  --command CMD Import a local stdio MCP server, max ${IMPORT_LIMITS.commandLength} chars
261
+ --timeout MS Optional MCP downstream inactivity timeout in milliseconds, default 60000
241
262
  --arg VALUE Repeatable stdio argument, max ${IMPORT_LIMITS.argCount} items, each max ${IMPORT_LIMITS.argLength} chars
242
263
  --env KEY=VALUE Repeatable stdio environment variable, max ${IMPORT_LIMITS.envCount} entries
243
264
  --cwd DIR Working directory for stdio launch, max ${IMPORT_LIMITS.cwdLength} chars
@@ -277,20 +298,24 @@ async function runMcpImport(options) {
277
298
  transport: options.transport,
278
299
  url: options.url,
279
300
  command: options.launchCommand,
301
+ timeout: options.timeout,
280
302
  args: options.launchArgs,
281
303
  env: options.launchEnv,
282
304
  cwd: options.launchCwd
283
305
  });
284
306
  const result = await importMcpServer(executor, storage, {
307
+ name: options.name,
285
308
  exposureMode: options.exposure,
286
309
  keywords: options.keywords,
287
310
  summary: options.summary,
288
311
  config,
289
312
  headers: options.headers
290
313
  });
291
- console.log(`Imported MCP app: ${result.entry.localId}`);
314
+ console.log(`Imported MCP app: ${result.descriptor.app.name.default}`);
315
+ console.log(`App ID: ${result.entry.localId}`);
292
316
  console.log(`Descriptor: ${result.entry.descriptorPath}`);
293
317
  console.log(`Managed directory: ${getManagedAppDir(result.entry.localId)}`);
318
+ console.log(`Tool name after restart: app:${result.entry.localId}`);
294
319
  console.log(`Keywords: ${result.descriptor.exposure.keywords.join(", ")}`);
295
320
  console.log(`Summary: ${result.descriptor.exposure.summary}`);
296
321
  console.log(`Exposure mode: ${options.exposure}`);
@@ -307,9 +332,11 @@ async function runSkillImport(options) {
307
332
  path: source.path,
308
333
  url: source.url
309
334
  });
310
- console.log(`Imported skill: ${result.localId}`);
335
+ console.log(`Imported skill: ${result.descriptor.app.name.default}`);
336
+ console.log(`App ID: ${result.localId}`);
311
337
  console.log(`Descriptor: ${join(getManagedAppDir(result.localId), "aai.json")}`);
312
338
  console.log(`Skill directory: ${result.managedPath}`);
339
+ console.log(`Tool name after restart: app:${result.localId}`);
313
340
  console.log(`Keywords: ${result.descriptor.exposure.keywords.join(", ")}`);
314
341
  console.log(`Summary: ${result.descriptor.exposure.summary}`);
315
342
  console.log(`Exposure mode: ${options.exposure}`);