@aiwerk/mcp-bridge 2.8.12 → 2.8.14
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/dist/bin/mcp-bridge.js +110 -88
- package/package.json +1 -1
package/dist/bin/mcp-bridge.js
CHANGED
|
@@ -98,6 +98,14 @@ function parseArgs(argv) {
|
|
|
98
98
|
case "--offline":
|
|
99
99
|
args.offline = true;
|
|
100
100
|
break;
|
|
101
|
+
case "--register":
|
|
102
|
+
i++;
|
|
103
|
+
if (!argv[i]) {
|
|
104
|
+
process.stderr.write("Error: --register requires a client name (claude-code, codex, cursor, windsurf)\n");
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
args.register = argv[i];
|
|
108
|
+
break;
|
|
101
109
|
case "--daily":
|
|
102
110
|
i++;
|
|
103
111
|
args.daily = parseInt(argv[i], 10);
|
|
@@ -171,7 +179,7 @@ Usage:
|
|
|
171
179
|
mcp-bridge Start in stdio mode (default)
|
|
172
180
|
mcp-bridge --sse --port 3000 Start as SSE server
|
|
173
181
|
mcp-bridge --http --port 3000 Start as streamable-http server
|
|
174
|
-
mcp-bridge init
|
|
182
|
+
mcp-bridge init [--register <client>] Create config + optionally register with a client
|
|
175
183
|
mcp-bridge install <server> Install a server from the catalog
|
|
176
184
|
mcp-bridge catalog [--offline] List available servers
|
|
177
185
|
mcp-bridge servers List configured servers
|
|
@@ -203,109 +211,123 @@ function whichCmd(name) {
|
|
|
203
211
|
return false;
|
|
204
212
|
}
|
|
205
213
|
}
|
|
206
|
-
function cmdInit(logger) {
|
|
214
|
+
function cmdInit(logger, register) {
|
|
207
215
|
initConfigDir(logger);
|
|
208
216
|
const isGlobal = __dirname.includes("node_modules") && (__dirname.includes("/lib/node_modules/") || __dirname.includes("\\lib\\node_modules\\"));
|
|
209
217
|
const bridgeCmd = isGlobal ? "mcp-bridge" : "node";
|
|
210
218
|
const bridgeArgs = isGlobal ? ["serve"] : [join(__dirname, "..", "bin", "mcp-bridge.js"), "serve"];
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
219
|
+
const cmd = isGlobal ? "mcp-bridge" : `node ${join(__dirname, "..", "bin", "mcp-bridge.js")}`;
|
|
220
|
+
if (register) {
|
|
221
|
+
registerClient(register, bridgeCmd, bridgeArgs, cmd);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const detected = [];
|
|
225
|
+
if (whichCmd("claude"))
|
|
226
|
+
detected.push("claude-code");
|
|
227
|
+
if (whichCmd("codex"))
|
|
228
|
+
detected.push("codex");
|
|
229
|
+
if (existsSync(join(homedir(), ".cursor")))
|
|
230
|
+
detected.push("cursor");
|
|
231
|
+
if (existsSync(join(homedir(), ".windsurf")))
|
|
232
|
+
detected.push("windsurf");
|
|
233
|
+
if (detected.length > 0) {
|
|
234
|
+
process.stdout.write("\nDetected MCP clients. Register with:\n");
|
|
235
|
+
for (const client of detected) {
|
|
236
|
+
process.stdout.write(` mcp-bridge init --register ${client}\n`);
|
|
220
237
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
process.stdout.write(`\nNo supported MCP client detected. Manual setup:\n\n Claude Code: claude mcp add -s user mcp-bridge -- ${cmd} serve\n Codex: codex mcp add mcp-bridge -- ${cmd} serve\n Cursor: Add to ~/.cursor/mcp.json\n Claude Desktop: Add to claude_desktop_config.json\n OpenClaw: openclaw plugins install @aiwerk/openclaw-mcp-bridge\n\nJSON config block (Cursor/Claude Desktop/Windsurf):\n\n {\n "mcp-bridge": {\n "command": "${isGlobal ? "mcp-bridge" : "node"}",\n "args": ${JSON.stringify(bridgeArgs)}\n }\n }\n`);
|
|
241
|
+
}
|
|
242
|
+
if (!isGlobal) {
|
|
243
|
+
process.stdout.write("\nTip: Install globally for a cleaner setup:\n npm install -g @aiwerk/mcp-bridge\n");
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function registerClient(client, bridgeCmd, bridgeArgs, cmd) {
|
|
247
|
+
switch (client) {
|
|
248
|
+
case "claude-code": {
|
|
249
|
+
try {
|
|
250
|
+
execFileSync("claude", ["mcp", "add", "-s", "user", "mcp-bridge", "--", bridgeCmd, ...bridgeArgs], { stdio: "pipe" });
|
|
251
|
+
process.stdout.write("✓ Registered with Claude Code → ~/.claude.json\n Restart Claude Code to activate.\n");
|
|
226
252
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
253
|
+
catch (err) {
|
|
254
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
255
|
+
if (msg.includes("already exists")) {
|
|
256
|
+
process.stdout.write("✓ Claude Code already configured.\n");
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
process.stdout.write(`⚠ Registration failed. Manual setup:\n claude mcp add -s user mcp-bridge -- ${cmd} serve\n`);
|
|
260
|
+
}
|
|
230
261
|
}
|
|
262
|
+
break;
|
|
231
263
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (!cursorConfig.mcpServers["mcp-bridge"]) {
|
|
244
|
-
cursorConfig.mcpServers["mcp-bridge"] = { command: bridgeCmd, args: bridgeArgs };
|
|
245
|
-
writeFileSync(cursorConfigPath, JSON.stringify(cursorConfig, null, 2) + "\n", "utf-8");
|
|
246
|
-
process.stdout.write(`✓ Registered with Cursor → ${cursorConfigPath}\n Restart Cursor to activate.\n`);
|
|
247
|
-
registered = true;
|
|
264
|
+
case "codex": {
|
|
265
|
+
const codexConfigPath = join(homedir(), ".codex", "config.toml");
|
|
266
|
+
try {
|
|
267
|
+
const codexConfig = existsSync(codexConfigPath) ? readFileSync(codexConfigPath, "utf-8") : "";
|
|
268
|
+
if (codexConfig.includes("[mcp_servers.mcp-bridge]") || codexConfig.includes("[mcp_servers.aiwerk-bridge]")) {
|
|
269
|
+
process.stdout.write("✓ Codex already configured.\n");
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
execFileSync("codex", ["mcp", "add", "mcp-bridge", "--", bridgeCmd, ...bridgeArgs], { stdio: "pipe" });
|
|
273
|
+
process.stdout.write(`✓ Registered with Codex → ${codexConfigPath}\n Restart Codex to activate.\n`);
|
|
274
|
+
}
|
|
248
275
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// Silent - already configured
|
|
252
|
-
registered = true;
|
|
276
|
+
catch {
|
|
277
|
+
process.stdout.write(`⚠ Registration failed. Manual setup:\n codex mcp add mcp-bridge -- ${cmd} serve\n`);
|
|
253
278
|
}
|
|
279
|
+
break;
|
|
254
280
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
281
|
+
case "cursor": {
|
|
282
|
+
const configPath = join(homedir(), ".cursor", "mcp.json");
|
|
283
|
+
try {
|
|
284
|
+
let config = {};
|
|
285
|
+
if (existsSync(configPath))
|
|
286
|
+
config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
287
|
+
if (!config.mcpServers)
|
|
288
|
+
config.mcpServers = {};
|
|
289
|
+
if (config.mcpServers["mcp-bridge"]) {
|
|
290
|
+
process.stdout.write("✓ Cursor already configured.\n");
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
config.mcpServers["mcp-bridge"] = { command: bridgeCmd, args: bridgeArgs };
|
|
294
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
295
|
+
process.stdout.write(`✓ Registered with Cursor → ${configPath}\n Restart Cursor to activate.\n`);
|
|
296
|
+
}
|
|
266
297
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
if (!wsConfig.mcpServers["mcp-bridge"]) {
|
|
270
|
-
wsConfig.mcpServers["mcp-bridge"] = { command: bridgeCmd, args: bridgeArgs };
|
|
271
|
-
writeFileSync(windsurfConfigPath, JSON.stringify(wsConfig, null, 2) + "\n", "utf-8");
|
|
272
|
-
process.stdout.write(`✓ Registered with Windsurf → ${windsurfConfigPath}\n Restart Windsurf to activate.\n`);
|
|
273
|
-
registered = true;
|
|
298
|
+
catch {
|
|
299
|
+
process.stdout.write("⚠ Cursor registration failed.\n");
|
|
274
300
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case "windsurf": {
|
|
304
|
+
const configPath = join(homedir(), ".windsurf", "mcp.json");
|
|
305
|
+
try {
|
|
306
|
+
let config = {};
|
|
307
|
+
if (existsSync(configPath))
|
|
308
|
+
config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
309
|
+
if (!config.mcpServers)
|
|
310
|
+
config.mcpServers = {};
|
|
311
|
+
if (config.mcpServers["mcp-bridge"]) {
|
|
312
|
+
process.stdout.write("✓ Windsurf already configured.\n");
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
config.mcpServers["mcp-bridge"] = { command: bridgeCmd, args: bridgeArgs };
|
|
316
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
317
|
+
process.stdout.write(`✓ Registered with Windsurf → ${configPath}\n Restart Windsurf to activate.\n`);
|
|
318
|
+
}
|
|
279
319
|
}
|
|
320
|
+
catch {
|
|
321
|
+
process.stdout.write("⚠ Windsurf registration failed.\n");
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
280
324
|
}
|
|
281
|
-
|
|
282
|
-
|
|
325
|
+
default: {
|
|
326
|
+
const isGlob = bridgeCmd === "mcp-bridge";
|
|
327
|
+
process.stdout.write(`Unknown client "${client}". Generic MCP config (add to your client's MCP settings):\n\n {\n "mcp-bridge": {\n "command": "${isGlob ? "mcp-bridge" : "node"}",\n "args": ${JSON.stringify(bridgeArgs)}\n }\n }\n\nKnown clients with auto-registration: claude-code, codex, cursor, windsurf\n`);
|
|
328
|
+
break;
|
|
283
329
|
}
|
|
284
330
|
}
|
|
285
|
-
if (!registered) {
|
|
286
|
-
const cmd = isGlobal ? "mcp-bridge" : `node ${join(__dirname, "..", "bin", "mcp-bridge.js")}`;
|
|
287
|
-
process.stdout.write(`
|
|
288
|
-
No supported MCP client detected. Add manually:
|
|
289
|
-
|
|
290
|
-
Claude Code: claude mcp add -s user mcp-bridge -- ${cmd} serve
|
|
291
|
-
Cursor: Add to ~/.cursor/mcp.json
|
|
292
|
-
Claude Desktop: Add to claude_desktop_config.json
|
|
293
|
-
OpenClaw: openclaw plugins install @aiwerk/openclaw-mcp-bridge
|
|
294
|
-
|
|
295
|
-
JSON config block (Cursor/Claude Desktop/Windsurf):
|
|
296
|
-
|
|
297
|
-
{
|
|
298
|
-
"mcp-bridge": {
|
|
299
|
-
"command": "${isGlobal ? "mcp-bridge" : "node"}",
|
|
300
|
-
"args": ${JSON.stringify(bridgeArgs)}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
`);
|
|
304
|
-
}
|
|
305
|
-
if (!isGlobal) {
|
|
306
|
-
process.stdout.write("\nTip: Install globally for a cleaner setup:\n npm install -g @aiwerk/mcp-bridge\n");
|
|
307
|
-
}
|
|
308
|
-
process.stdout.write("\nRestart your client. The bridge appears as an 'mcp' tool with\nsearch, install, and catalog actions to discover and add MCP servers.\n");
|
|
309
331
|
}
|
|
310
332
|
function cmdCatalog(logger) {
|
|
311
333
|
const catalogPath = join(PACKAGE_ROOT, "servers", "index.json");
|
|
@@ -742,7 +764,7 @@ async function main() {
|
|
|
742
764
|
printHelp();
|
|
743
765
|
break;
|
|
744
766
|
case "init":
|
|
745
|
-
cmdInit(logger);
|
|
767
|
+
cmdInit(logger, args.register);
|
|
746
768
|
break;
|
|
747
769
|
case "catalog":
|
|
748
770
|
cmdCatalog(logger);
|