@aiwerk/mcp-bridge 2.8.24 → 2.8.25
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 +17 -2
- package/dist/bin/mcp-bridge.js +2 -1
- package/dist/src/mcp-router.d.ts +5 -0
- package/dist/src/mcp-router.js +35 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -417,9 +417,24 @@ Returns promoted tools (sorted by frequency) and full usage stats. All tracking
|
|
|
417
417
|
| Mode | Tools exposed | Best for |
|
|
418
418
|
|------|--------------|----------|
|
|
419
419
|
| `router` (default) | Single `mcp` meta-tool | 3+ servers, token-conscious agents |
|
|
420
|
-
| `direct` | All tools individually |
|
|
420
|
+
| `direct` | All tools individually | Clients with deferred/lazy tool loading (Claude Code), few servers |
|
|
421
421
|
|
|
422
|
-
|
|
422
|
+
Switch modes via CLI or config:
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
mcp-bridge init --mode direct # all tools exposed individually
|
|
426
|
+
mcp-bridge init --mode router # single mcp meta-tool (default)
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Or set in `~/.mcp-bridge/config.json`:
|
|
430
|
+
|
|
431
|
+
```json
|
|
432
|
+
{ "mode": "direct" }
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Router mode** — the agent calls `mcp(server="todoist", action="list")` to discover, then `mcp(server="todoist", tool="find-tasks", params={...})` to execute. Best when you have many servers and want minimal token usage.
|
|
436
|
+
|
|
437
|
+
**Direct mode** — all tools from all servers are registered individually as `todoist_find_tasks`, `github_list_repos`, etc. The bridge still provides unified config, catalog install, OAuth2, security, retries, and reconnection. Ideal for clients that support deferred/lazy tool loading, where tools are registered but not loaded into context until needed.
|
|
423
438
|
|
|
424
439
|
### Multi-Server Tool Resolution
|
|
425
440
|
|
package/dist/bin/mcp-bridge.js
CHANGED
|
@@ -221,7 +221,7 @@ function whichCmd(name) {
|
|
|
221
221
|
}
|
|
222
222
|
function cmdInit(logger, register, mode) {
|
|
223
223
|
initConfigDir(logger);
|
|
224
|
-
// Apply --mode
|
|
224
|
+
// Apply --mode to config
|
|
225
225
|
if (mode) {
|
|
226
226
|
const configPath = join(homedir(), ".mcp-bridge", "config.json");
|
|
227
227
|
if (existsSync(configPath)) {
|
|
@@ -236,6 +236,7 @@ function cmdInit(logger, register, mode) {
|
|
|
236
236
|
catch { /* ignore parse errors */ }
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
|
+
// If --register is specified, do both mode + register
|
|
239
240
|
const isGlobal = __dirname.includes("node_modules") && (__dirname.includes("/lib/node_modules/") || __dirname.includes("\\lib\\node_modules\\"));
|
|
240
241
|
const bridgeCmd = isGlobal ? "mcp-bridge" : "node";
|
|
241
242
|
const bridgeArgs = isGlobal ? ["serve"] : [join(__dirname, "..", "bin", "mcp-bridge.js"), "serve"];
|
package/dist/src/mcp-router.d.ts
CHANGED
|
@@ -110,6 +110,11 @@ export type RouterDispatchResponse = {
|
|
|
110
110
|
message: string;
|
|
111
111
|
missingEnvVars?: string[];
|
|
112
112
|
credentialsUrl?: string;
|
|
113
|
+
} | {
|
|
114
|
+
action: "set-mode";
|
|
115
|
+
mode: string;
|
|
116
|
+
message: string;
|
|
117
|
+
requiresRestart?: boolean;
|
|
113
118
|
} | {
|
|
114
119
|
action: "intent";
|
|
115
120
|
intent: string;
|
package/dist/src/mcp-router.js
CHANGED
|
@@ -77,7 +77,7 @@ export class McpRouter {
|
|
|
77
77
|
return desc ? `${name} (${desc})` : name;
|
|
78
78
|
})
|
|
79
79
|
.join(", ");
|
|
80
|
-
return `MCP server multiplexer with ${serverNames.length} connected servers: ${serverList}. Actions: 'call' to execute a tool, 'list' to discover tools on a server, 'batch' for multiple calls in one round-trip, 'status' to check connections, 'refresh' to re-discover tools. To add new MCP servers, always use this tool first (not npm install): 'search' to find servers in the verified catalog (100+ signed, security-audited recipes), 'install' to add a server by name. If the user mentions a specific tool by name, the call action auto-connects and works without listing first.`;
|
|
80
|
+
return `MCP server multiplexer with ${serverNames.length} connected servers: ${serverList}. Actions: 'call' to execute a tool, 'list' to discover tools on a server, 'batch' for multiple calls in one round-trip, 'status' to check connections, 'refresh' to re-discover tools. To add new MCP servers, always use this tool first (not npm install): 'search' to find servers in the verified catalog (100+ signed, security-audited recipes), 'install' to add a server by name. Use 'set-mode' with params.mode='direct' to expose all tools individually (requires restart). If the user mentions a specific tool by name, the call action auto-connects and works without listing first.`;
|
|
81
81
|
}
|
|
82
82
|
async dispatch(server, action = "call", tool, params) {
|
|
83
83
|
try {
|
|
@@ -340,8 +340,41 @@ export class McpRouter {
|
|
|
340
340
|
return this.error("connection_failed", `Failed to connect to ${server}: ${error instanceof Error ? error.message : String(error)}`);
|
|
341
341
|
}
|
|
342
342
|
}
|
|
343
|
+
// Set mode (persists to config, requires bridge restart to take effect)
|
|
344
|
+
if (normalizedAction === "set-mode") {
|
|
345
|
+
const newMode = params?.mode;
|
|
346
|
+
if (newMode !== "router" && newMode !== "direct") {
|
|
347
|
+
return this.error("invalid_params", "mode must be 'router' or 'direct'");
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
const os = await import("os");
|
|
351
|
+
const fs = await import("fs");
|
|
352
|
+
const path = await import("path");
|
|
353
|
+
const configPath = path.join(os.homedir(), ".mcp-bridge", "config.json");
|
|
354
|
+
if (fs.existsSync(configPath)) {
|
|
355
|
+
const raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
356
|
+
const oldMode = raw.mode || "router";
|
|
357
|
+
if (oldMode === newMode) {
|
|
358
|
+
return { action: "set-mode", mode: newMode, message: `Already in "${newMode}" mode.` };
|
|
359
|
+
}
|
|
360
|
+
raw.mode = newMode;
|
|
361
|
+
fs.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
|
|
362
|
+
this.logger.info(`Mode changed from "${oldMode}" to "${newMode}" in ${configPath}`);
|
|
363
|
+
return {
|
|
364
|
+
action: "set-mode",
|
|
365
|
+
mode: newMode,
|
|
366
|
+
message: `Mode changed to "${newMode}". Restart the bridge for changes to take effect.`,
|
|
367
|
+
requiresRestart: true,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
return this.error("mcp_error", "Config file not found");
|
|
371
|
+
}
|
|
372
|
+
catch (err) {
|
|
373
|
+
return this.error("mcp_error", `Failed to set mode: ${err instanceof Error ? err.message : String(err)}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
343
376
|
if (normalizedAction !== "call") {
|
|
344
|
-
return this.error("invalid_params", `action must be one of: list, call, batch, refresh, schema, intent, status, promotions, search, catalog, install`);
|
|
377
|
+
return this.error("invalid_params", `action must be one of: list, call, batch, refresh, schema, intent, status, promotions, search, catalog, install, set-mode`);
|
|
345
378
|
}
|
|
346
379
|
if (!tool) {
|
|
347
380
|
return this.error("invalid_params", "tool is required for action=call");
|