@agiflowai/one-mcp 0.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/LICENSE +661 -0
- package/README.md +500 -0
- package/dist/cli.cjs +497 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +498 -0
- package/dist/http-B1EDyxR_.mjs +1211 -0
- package/dist/http-B5WVqLzz.cjs +1277 -0
- package/dist/index.cjs +6 -0
- package/dist/index.d.cts +172 -0
- package/dist/index.d.mts +172 -0
- package/dist/index.mjs +3 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
# @agiflowai/one-mcp
|
|
2
|
+
|
|
3
|
+
A unified MCP (Model Context Protocol) proxy server that enables **progressive tool discovery** to dramatically reduce token usage when working with multiple MCP servers.
|
|
4
|
+
|
|
5
|
+
## The Problem: MCP Token Bloat
|
|
6
|
+
|
|
7
|
+
When connecting to multiple MCP servers directly, AI agents must load ALL tools from ALL servers into their context window at startup. This creates massive token overhead:
|
|
8
|
+
|
|
9
|
+
**Example: 10 MCP Servers**
|
|
10
|
+
```
|
|
11
|
+
Server 1: 20 tools × 200 tokens = 4,000 tokens
|
|
12
|
+
Server 2: 15 tools × 200 tokens = 3,000 tokens
|
|
13
|
+
Server 3: 30 tools × 200 tokens = 6,000 tokens
|
|
14
|
+
...
|
|
15
|
+
Total: ~40,000+ tokens consumed BEFORE you even start coding
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This consumes a significant portion of your context window with tool descriptions you may never use in that session.
|
|
19
|
+
|
|
20
|
+
## The Solution: Progressive Discovery
|
|
21
|
+
|
|
22
|
+
one-mcp acts as a **smart proxy** that only loads tool descriptions when needed:
|
|
23
|
+
|
|
24
|
+
1. **Initial Connection**: Agent sees only 2 meta-tools (`describe_tools` and `use_tool`)
|
|
25
|
+
- Token cost: ~400 tokens (vs 40,000+ tokens)
|
|
26
|
+
|
|
27
|
+
2. **Discovery on Demand**: Agent calls `describe_tools` only for servers/tools it needs
|
|
28
|
+
- Example: `describe_tools(["filesystem"])` loads only filesystem server tools
|
|
29
|
+
- Token cost: ~4,000 tokens (only what you need, when you need it)
|
|
30
|
+
|
|
31
|
+
3. **Tool Execution**: Agent calls `use_tool` to execute tools through the proxy
|
|
32
|
+
- one-mcp routes the call to the correct server
|
|
33
|
+
- No token overhead - just execution
|
|
34
|
+
|
|
35
|
+
**Result: 90%+ reduction in initial token usage**
|
|
36
|
+
|
|
37
|
+
## How It Works
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Traditional Approach (High Token Cost):
|
|
41
|
+
┌─────────────────┐
|
|
42
|
+
│ AI Agent │ ← Loads ALL tools from ALL servers (40,000+ tokens)
|
|
43
|
+
├─────────────────┤
|
|
44
|
+
│ MCP Server 1 │ → 20 tools
|
|
45
|
+
│ MCP Server 2 │ → 15 tools
|
|
46
|
+
│ MCP Server 3 │ → 30 tools
|
|
47
|
+
│ ... │
|
|
48
|
+
└─────────────────┘
|
|
49
|
+
|
|
50
|
+
Progressive Discovery (Low Token Cost):
|
|
51
|
+
┌─────────────────┐
|
|
52
|
+
│ AI Agent │ ← Loads only 2 meta-tools (400 tokens)
|
|
53
|
+
├─────────────────┤
|
|
54
|
+
│ one-mcp │ ← Proxies to servers on-demand
|
|
55
|
+
│ (2 tools) │
|
|
56
|
+
└────────┬────────┘
|
|
57
|
+
│ Connects to servers as needed
|
|
58
|
+
┌────┴─────┬──────────┬─────────┐
|
|
59
|
+
│ Server 1 │ Server 2 │ Server 3│
|
|
60
|
+
└──────────┴──────────┴─────────┘
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Key Benefits
|
|
64
|
+
|
|
65
|
+
- **Massive Token Savings** - 90%+ reduction in initial context usage
|
|
66
|
+
- **Faster Startup** - Agent ready in milliseconds, not seconds
|
|
67
|
+
- **Scale Infinitely** - Add 100+ MCP servers without bloating context
|
|
68
|
+
- **Pay-as-you-go** - Only load tools when actually needed
|
|
69
|
+
- **Better Context Budget** - Save tokens for actual code and conversation
|
|
70
|
+
- **Centralized Config** - Manage all servers from one YAML/JSON file
|
|
71
|
+
|
|
72
|
+
## Installation
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install -g @agiflowai/one-mcp
|
|
76
|
+
# or
|
|
77
|
+
pnpm add -g @agiflowai/one-mcp
|
|
78
|
+
# or
|
|
79
|
+
yarn global add @agiflowai/one-mcp
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
84
|
+
### 1. Initialize Configuration
|
|
85
|
+
|
|
86
|
+
Create an MCP configuration file:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npx @agiflowai/one-mcp init
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This creates a `mcp-config.yaml` file with example servers:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
mcpServers:
|
|
96
|
+
filesystem:
|
|
97
|
+
command: npx
|
|
98
|
+
args:
|
|
99
|
+
- -y
|
|
100
|
+
- "@modelcontextprotocol/server-filesystem"
|
|
101
|
+
- "${HOME}/Documents"
|
|
102
|
+
config:
|
|
103
|
+
instruction: "Access files in the Documents folder"
|
|
104
|
+
|
|
105
|
+
web-search:
|
|
106
|
+
url: https://example.com/mcp/search
|
|
107
|
+
type: sse
|
|
108
|
+
headers:
|
|
109
|
+
Authorization: "Bearer ${API_KEY}"
|
|
110
|
+
config:
|
|
111
|
+
instruction: "Search the web for information"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 2. Configure Your Agent
|
|
115
|
+
|
|
116
|
+
Add one-mcp to your AI coding tool's MCP configuration:
|
|
117
|
+
|
|
118
|
+
**For Claude Code:**
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"mcpServers": {
|
|
123
|
+
"one-mcp": {
|
|
124
|
+
"command": "npx",
|
|
125
|
+
"args": ["-y", "@agiflowai/one-mcp", "mcp-serve", "--config", "./mcp-config.yaml"]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**For Cursor:**
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"mcpServers": {
|
|
136
|
+
"one-mcp": {
|
|
137
|
+
"command": "npx",
|
|
138
|
+
"args": ["-y", "@agiflowai/one-mcp", "mcp-serve", "--config", "./mcp-config.yaml"]
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 3. Start Using Tools
|
|
145
|
+
|
|
146
|
+
Your agent now has access to all tools from all configured servers through the single one-mcp connection!
|
|
147
|
+
|
|
148
|
+
## Configuration
|
|
149
|
+
|
|
150
|
+
### Config File Format
|
|
151
|
+
|
|
152
|
+
one-mcp supports the standard Claude Code MCP configuration format:
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
mcpServers:
|
|
156
|
+
# Stdio server (local command)
|
|
157
|
+
server-name:
|
|
158
|
+
command: npx
|
|
159
|
+
args:
|
|
160
|
+
- -y
|
|
161
|
+
- "@modelcontextprotocol/server-example"
|
|
162
|
+
env:
|
|
163
|
+
API_KEY: "${MY_API_KEY}"
|
|
164
|
+
config:
|
|
165
|
+
instruction: "Custom instruction for this server"
|
|
166
|
+
# Optional: Block specific tools from being listed or executed
|
|
167
|
+
toolBlacklist:
|
|
168
|
+
- dangerous_tool
|
|
169
|
+
- another_blocked_tool
|
|
170
|
+
|
|
171
|
+
# HTTP/SSE server (remote)
|
|
172
|
+
remote-server:
|
|
173
|
+
url: https://api.example.com/mcp
|
|
174
|
+
type: sse # or http
|
|
175
|
+
headers:
|
|
176
|
+
Authorization: "Bearer ${TOKEN}"
|
|
177
|
+
config:
|
|
178
|
+
instruction: "Remote server instruction"
|
|
179
|
+
toolBlacklist:
|
|
180
|
+
- risky_operation
|
|
181
|
+
|
|
182
|
+
# Disabled server (will be skipped)
|
|
183
|
+
disabled-server:
|
|
184
|
+
command: node
|
|
185
|
+
args: ["server.js"]
|
|
186
|
+
disabled: true
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Environment Variable Interpolation
|
|
190
|
+
|
|
191
|
+
Use `${VAR_NAME}` syntax to interpolate environment variables:
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
mcpServers:
|
|
195
|
+
api-server:
|
|
196
|
+
command: npx
|
|
197
|
+
args:
|
|
198
|
+
- "@mycompany/mcp-server"
|
|
199
|
+
- "${HOME}/data" # Expands to /Users/username/data
|
|
200
|
+
env:
|
|
201
|
+
API_KEY: "${MY_API_KEY}" # Reads from environment
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Tool Blacklisting
|
|
205
|
+
|
|
206
|
+
Control which tools from an MCP server are accessible by using the `toolBlacklist` configuration. Blacklisted tools will:
|
|
207
|
+
- Not appear in `list-tools` output
|
|
208
|
+
- Not be shown in `describe_tools` responses
|
|
209
|
+
- Raise an error if attempted to be executed via `use_tool`
|
|
210
|
+
|
|
211
|
+
This is useful for:
|
|
212
|
+
- **Security**: Block dangerous operations (e.g., `write_file`, `delete_file`)
|
|
213
|
+
- **Compliance**: Restrict tools that don't meet your policies
|
|
214
|
+
- **Simplification**: Hide tools you don't want agents to use
|
|
215
|
+
|
|
216
|
+
**Example:**
|
|
217
|
+
|
|
218
|
+
```yaml
|
|
219
|
+
mcpServers:
|
|
220
|
+
filesystem:
|
|
221
|
+
command: npx
|
|
222
|
+
args:
|
|
223
|
+
- -y
|
|
224
|
+
- "@modelcontextprotocol/server-filesystem"
|
|
225
|
+
- "/workspace"
|
|
226
|
+
config:
|
|
227
|
+
instruction: "File system access (read-only)"
|
|
228
|
+
toolBlacklist:
|
|
229
|
+
- write_file
|
|
230
|
+
- create_directory
|
|
231
|
+
- move_file
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Behavior:**
|
|
235
|
+
- Agents will only see read-only tools like `read_file`, `list_directory`
|
|
236
|
+
- Attempting to call `write_file` will return an error: `Tool "write_file" is blacklisted on server "filesystem" and cannot be executed.`
|
|
237
|
+
|
|
238
|
+
### Tool Description Formatting
|
|
239
|
+
|
|
240
|
+
Control how tool information is displayed by using the `omitToolDescription` configuration flag. This helps reduce token usage when full descriptions aren't needed.
|
|
241
|
+
|
|
242
|
+
**Default behavior (omitToolDescription: false or not set):**
|
|
243
|
+
```
|
|
244
|
+
server-name:
|
|
245
|
+
- tool_name1: Full description of what this tool does...
|
|
246
|
+
- tool_name2: Another detailed description...
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Compact mode (omitToolDescription: true):**
|
|
250
|
+
```
|
|
251
|
+
server-name:
|
|
252
|
+
tool_name1, tool_name2, tool_name3
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
256
|
+
|
|
257
|
+
```yaml
|
|
258
|
+
mcpServers:
|
|
259
|
+
filesystem:
|
|
260
|
+
command: npx
|
|
261
|
+
args:
|
|
262
|
+
- -y
|
|
263
|
+
- "@modelcontextprotocol/server-filesystem"
|
|
264
|
+
- "/workspace"
|
|
265
|
+
config:
|
|
266
|
+
instruction: "File system access"
|
|
267
|
+
omitToolDescription: true # Show only tool names, not descriptions
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Benefits:**
|
|
271
|
+
- **Reduced Token Usage**: Save context window space by omitting verbose descriptions
|
|
272
|
+
- **Faster Discovery**: Quickly scan available tool names without reading full descriptions
|
|
273
|
+
- **Cleaner Output**: More compact tool listings for familiar servers
|
|
274
|
+
|
|
275
|
+
**When to use:**
|
|
276
|
+
- You're already familiar with the server's tools
|
|
277
|
+
- Working with servers that have many tools with long descriptions
|
|
278
|
+
- Trying to conserve context window tokens
|
|
279
|
+
- Need a quick overview of available tool names
|
|
280
|
+
|
|
281
|
+
## CLI Commands
|
|
282
|
+
|
|
283
|
+
### `mcp-serve`
|
|
284
|
+
|
|
285
|
+
Start the MCP server:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
npx @agiflowai/one-mcp mcp-serve [options]
|
|
289
|
+
|
|
290
|
+
Options:
|
|
291
|
+
-c, --config <path> Path to local config file (YAML or JSON)
|
|
292
|
+
--no-cache Force reload configuration from source, bypassing cache
|
|
293
|
+
-t, --type <type> Transport mode: stdio (default), http, sse
|
|
294
|
+
-p, --port <number> Port for HTTP/SSE transport (default: 3000)
|
|
295
|
+
--host <host> Host to bind to (HTTP/SSE only, default: localhost)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### `init`
|
|
299
|
+
|
|
300
|
+
Initialize an MCP configuration file:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
npx @agiflowai/one-mcp init [options]
|
|
304
|
+
|
|
305
|
+
Options:
|
|
306
|
+
-o, --output <path> Output file path (default: mcp-config.yaml)
|
|
307
|
+
--json Generate JSON config instead of YAML
|
|
308
|
+
-f, --force Overwrite existing config file
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### `list-tools`
|
|
312
|
+
|
|
313
|
+
List all available tools from configured servers:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
npx @agiflowai/one-mcp list-tools --config ./mcp-config.yaml
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### `describe-tools`
|
|
320
|
+
|
|
321
|
+
Get detailed information about specific tools:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
npx @agiflowai/one-mcp describe-tools \
|
|
325
|
+
--config ./mcp-config.yaml \
|
|
326
|
+
--tools tool1,tool2
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### `use-tool`
|
|
330
|
+
|
|
331
|
+
Execute a tool directly from CLI:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npx @agiflowai/one-mcp use-tool \
|
|
335
|
+
--config ./mcp-config.yaml \
|
|
336
|
+
--tool-name read_file \
|
|
337
|
+
--args '{"path": "/path/to/file"}'
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## MCP Tools
|
|
341
|
+
|
|
342
|
+
When running as an MCP server, one-mcp provides these tools:
|
|
343
|
+
|
|
344
|
+
### `mcp__one-mcp__describe_tools`
|
|
345
|
+
|
|
346
|
+
Get detailed information about available tools from connected servers.
|
|
347
|
+
|
|
348
|
+
**Input:**
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"toolNames": ["tool1", "tool2"],
|
|
352
|
+
"serverName": "optional-server-name"
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### `mcp__one-mcp__use_tool`
|
|
357
|
+
|
|
358
|
+
Execute a tool from any connected server.
|
|
359
|
+
|
|
360
|
+
**Input:**
|
|
361
|
+
```json
|
|
362
|
+
{
|
|
363
|
+
"toolName": "read_file",
|
|
364
|
+
"toolArgs": {
|
|
365
|
+
"path": "/path/to/file"
|
|
366
|
+
},
|
|
367
|
+
"serverName": "optional-server-name"
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Use Cases
|
|
372
|
+
|
|
373
|
+
### 1. Simplify Multi-Server Setup
|
|
374
|
+
|
|
375
|
+
Instead of configuring 10+ MCP servers individually in your agent:
|
|
376
|
+
|
|
377
|
+
**Before:**
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"mcpServers": {
|
|
381
|
+
"filesystem": { "command": "npx", "args": ["..."] },
|
|
382
|
+
"database": { "command": "npx", "args": ["..."] },
|
|
383
|
+
"web-search": { "command": "npx", "args": ["..."] },
|
|
384
|
+
// ... 7 more servers
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**After:**
|
|
390
|
+
```json
|
|
391
|
+
{
|
|
392
|
+
"mcpServers": {
|
|
393
|
+
"one-mcp": {
|
|
394
|
+
"command": "npx",
|
|
395
|
+
"args": ["-y", "@agiflowai/one-mcp", "mcp-serve", "--config", "./mcp-config.yaml"]
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### 2. Centralized Configuration Management
|
|
402
|
+
|
|
403
|
+
Manage all MCP servers from a single YAML/JSON file that can be:
|
|
404
|
+
- Version controlled
|
|
405
|
+
- Shared across teams
|
|
406
|
+
- Hosted remotely
|
|
407
|
+
- Environment-specific
|
|
408
|
+
|
|
409
|
+
### 3. Mix Local and Remote Servers
|
|
410
|
+
|
|
411
|
+
```yaml
|
|
412
|
+
mcpServers:
|
|
413
|
+
# Local development tools
|
|
414
|
+
filesystem:
|
|
415
|
+
command: npx
|
|
416
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}/dev"]
|
|
417
|
+
|
|
418
|
+
# Company-wide remote tools
|
|
419
|
+
company-apis:
|
|
420
|
+
url: https://mcp.company.com/api
|
|
421
|
+
type: sse
|
|
422
|
+
headers:
|
|
423
|
+
Authorization: "Bearer ${COMPANY_TOKEN}"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### 4. Dynamic Configuration
|
|
427
|
+
|
|
428
|
+
Load different configs based on environment:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
# Development
|
|
432
|
+
npx @agiflowai/one-mcp mcp-serve --config ./mcp-dev.yaml
|
|
433
|
+
|
|
434
|
+
# Production
|
|
435
|
+
npx @agiflowai/one-mcp mcp-serve --config ./mcp-prod.yaml
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
## Development
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
# Install dependencies
|
|
442
|
+
pnpm install
|
|
443
|
+
|
|
444
|
+
# Build
|
|
445
|
+
pnpm build
|
|
446
|
+
|
|
447
|
+
# Run tests
|
|
448
|
+
pnpm test
|
|
449
|
+
|
|
450
|
+
# Run in development mode
|
|
451
|
+
pnpm dev
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Architecture
|
|
455
|
+
|
|
456
|
+
```
|
|
457
|
+
┌─────────────────┐
|
|
458
|
+
│ AI Agent │
|
|
459
|
+
│ (Claude/etc) │
|
|
460
|
+
└────────┬────────┘
|
|
461
|
+
│ Single MCP Connection
|
|
462
|
+
│
|
|
463
|
+
┌────────▼────────────────────────────┐
|
|
464
|
+
│ │
|
|
465
|
+
│ @agiflowai/one-mcp │
|
|
466
|
+
│ │
|
|
467
|
+
│ ┌─────────────────────────────┐ │
|
|
468
|
+
│ │ ConfigFetcherService │ │
|
|
469
|
+
│ │ - Load YAML/JSON configs │ │
|
|
470
|
+
│ │ - Merge strategies │ │
|
|
471
|
+
│ │ - Environment interpolation│ │
|
|
472
|
+
│ └─────────────────────────────┘ │
|
|
473
|
+
│ │
|
|
474
|
+
│ ┌─────────────────────────────┐ │
|
|
475
|
+
│ │ McpClientManagerService │ │
|
|
476
|
+
│ │ - Connect to MCP servers │ │
|
|
477
|
+
│ │ - Manage connections │ │
|
|
478
|
+
│ │ - Route tool calls │ │
|
|
479
|
+
│ └─────────────────────────────┘ │
|
|
480
|
+
│ │
|
|
481
|
+
└──────┬──────┬───────┬──────────────┘
|
|
482
|
+
│ │ │
|
|
483
|
+
│ │ │ Multiple MCP Connections
|
|
484
|
+
│ │ │
|
|
485
|
+
┌───▼──┐ ┌─▼────┐ ┌▼─────────┐
|
|
486
|
+
│ MCP │ │ MCP │ │ MCP │
|
|
487
|
+
│Server│ │Server│ │ Server │
|
|
488
|
+
│ 1 │ │ 2 │ │ 3 │
|
|
489
|
+
└──────┘ └──────┘ └──────────┘
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## License
|
|
493
|
+
|
|
494
|
+
AGPL-3.0 © AgiflowIO
|
|
495
|
+
|
|
496
|
+
## Related Packages
|
|
497
|
+
|
|
498
|
+
- [@agiflowai/scaffold-mcp](../scaffold-mcp) - Scaffolding and templates
|
|
499
|
+
- [@agiflowai/architect-mcp](../architect-mcp) - Architecture patterns and code review
|
|
500
|
+
- [@agiflowai/aicode-toolkit](../../apps/aicode-toolkit) - Unified CLI toolkit
|