@aiwerk/mcp-bridge 2.8.6 → 2.8.8

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.
@@ -3,6 +3,7 @@ import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
3
3
  import { join, dirname, resolve, extname } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import { homedir } from "os";
6
+ import { execFileSync, execSync } from "child_process";
6
7
  import { loadConfig, initConfigDir, warnDeprecatedBundledRecipes, recipeToServerConfig, collectRequiredEnvVars } from "../src/config.js";
7
8
  import { StandaloneServer } from "../src/standalone-server.js";
8
9
  import { PACKAGE_VERSION } from "../src/protocol.js";
@@ -193,28 +194,109 @@ Options:
193
194
  All logs go to stderr. Stdout is reserved for the MCP protocol (stdio mode).
194
195
  `);
195
196
  }
197
+ function whichCmd(name) {
198
+ try {
199
+ execSync(`which ${name}`, { stdio: "ignore" });
200
+ return true;
201
+ }
202
+ catch {
203
+ return false;
204
+ }
205
+ }
196
206
  function cmdInit(logger) {
197
207
  initConfigDir(logger);
198
- // Check if installed globally
199
- const isGlobal = __dirname.includes("node_modules") && !__dirname.includes(homedir());
200
- process.stdout.write(`
201
- Next step: add mcp-bridge to your MCP client.
208
+ const isGlobal = __dirname.includes("node_modules") && (__dirname.includes("/lib/node_modules/") || __dirname.includes("\\lib\\node_modules\\"));
209
+ const bridgeCmd = isGlobal ? "mcp-bridge" : "node";
210
+ const bridgeArgs = isGlobal ? ["serve"] : [join(__dirname, "..", "bin", "mcp-bridge.js"), "serve"];
211
+ // Auto-detect and register with known clients
212
+ let registered = false;
213
+ // Claude Code
214
+ if (whichCmd("claude")) {
215
+ try {
216
+ const addArgs = ["mcp", "add", "-s", "user", "mcp-bridge", "--", bridgeCmd, ...bridgeArgs];
217
+ execFileSync("claude", addArgs, { stdio: "pipe" });
218
+ process.stdout.write("✓ Registered with Claude Code (user scope)\n");
219
+ registered = true;
220
+ }
221
+ catch {
222
+ process.stdout.write("⚠ Claude Code detected but registration failed. Manual setup:\n");
223
+ process.stdout.write(` claude mcp add -s user mcp-bridge -- ${bridgeCmd} ${bridgeArgs.join(" ")}\n\n`);
224
+ }
225
+ }
226
+ // Cursor
227
+ const cursorConfigPath = join(homedir(), ".cursor", "mcp.json");
228
+ if (existsSync(join(homedir(), ".cursor"))) {
229
+ try {
230
+ let cursorConfig = {};
231
+ if (existsSync(cursorConfigPath)) {
232
+ cursorConfig = JSON.parse(readFileSync(cursorConfigPath, "utf-8"));
233
+ }
234
+ if (!cursorConfig.mcpServers)
235
+ cursorConfig.mcpServers = {};
236
+ if (!cursorConfig.mcpServers["mcp-bridge"]) {
237
+ cursorConfig.mcpServers["mcp-bridge"] = { command: bridgeCmd, args: bridgeArgs };
238
+ writeFileSync(cursorConfigPath, JSON.stringify(cursorConfig, null, 2) + "\n", "utf-8");
239
+ process.stdout.write("✓ Registered with Cursor\n");
240
+ registered = true;
241
+ }
242
+ else {
243
+ process.stdout.write("✓ Cursor already configured\n");
244
+ registered = true;
245
+ }
246
+ }
247
+ catch {
248
+ process.stdout.write("⚠ Cursor detected but registration failed.\n");
249
+ }
250
+ }
251
+ // Windsurf
252
+ const windsurfConfigPath = join(homedir(), ".windsurf", "mcp.json");
253
+ if (existsSync(join(homedir(), ".windsurf"))) {
254
+ try {
255
+ let wsConfig = {};
256
+ if (existsSync(windsurfConfigPath)) {
257
+ wsConfig = JSON.parse(readFileSync(windsurfConfigPath, "utf-8"));
258
+ }
259
+ if (!wsConfig.mcpServers)
260
+ wsConfig.mcpServers = {};
261
+ if (!wsConfig.mcpServers["mcp-bridge"]) {
262
+ wsConfig.mcpServers["mcp-bridge"] = { command: bridgeCmd, args: bridgeArgs };
263
+ writeFileSync(windsurfConfigPath, JSON.stringify(wsConfig, null, 2) + "\n", "utf-8");
264
+ process.stdout.write("✓ Registered with Windsurf\n");
265
+ registered = true;
266
+ }
267
+ else {
268
+ process.stdout.write("✓ Windsurf already configured\n");
269
+ registered = true;
270
+ }
271
+ }
272
+ catch {
273
+ process.stdout.write("⚠ Windsurf detected but registration failed.\n");
274
+ }
275
+ }
276
+ if (!registered) {
277
+ const cmd = isGlobal ? "mcp-bridge" : `node ${join(__dirname, "..", "bin", "mcp-bridge.js")}`;
278
+ process.stdout.write(`
279
+ No supported MCP client detected. Add manually:
280
+
281
+ Claude Code: claude mcp add -s user mcp-bridge -- ${cmd} serve
282
+ Cursor: Add to ~/.cursor/mcp.json
283
+ Claude Desktop: Add to claude_desktop_config.json
284
+ OpenClaw: openclaw plugins install @aiwerk/openclaw-mcp-bridge
202
285
 
203
- Add this to your client's MCP server config:
286
+ JSON config block (Cursor/Claude Desktop/Windsurf):
204
287
 
205
288
  {
206
289
  "mcp-bridge": {
207
290
  "command": "${isGlobal ? "mcp-bridge" : "node"}",
208
- "args": ${isGlobal ? '["serve"]' : `["${join(__dirname, "..", "bin", "mcp-bridge.js")}", "serve"]`}
291
+ "args": ${JSON.stringify(bridgeArgs)}
209
292
  }
210
293
  }
211
-
212
- Supported clients: Claude Code (~/.claude/settings.json),
213
- Cursor (~/.cursor/mcp.json), Claude Desktop, Windsurf, OpenClaw, etc.
214
- ${!isGlobal ? "\nTip: Install globally for a cleaner setup:\n npm install -g @aiwerk/mcp-bridge\n" : ""}
215
- After adding, restart your client. The bridge will appear as an 'mcp' tool
216
- with search, install, and catalog actions to discover and add MCP servers.
217
294
  `);
295
+ }
296
+ if (!isGlobal) {
297
+ process.stdout.write("\nTip: Install globally for a cleaner setup:\n npm install -g @aiwerk/mcp-bridge\n");
298
+ }
299
+ 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");
218
300
  }
219
301
  function cmdCatalog(logger) {
220
302
  const catalogPath = join(PACKAGE_ROOT, "servers", "index.json");
@@ -599,6 +681,11 @@ async function cmdAuth(args, logger) {
599
681
  process.stdout.write(`Authentication successful for ${serverName}. Token stored.\n`);
600
682
  }
601
683
  async function cmdServe(args, logger) {
684
+ // Auto-create config if missing (don't crash on first run)
685
+ const configPath = resolveConfigPath(args.configPath);
686
+ if (!existsSync(configPath)) {
687
+ initConfigDir(logger);
688
+ }
602
689
  let config;
603
690
  try {
604
691
  config = loadConfig({ configPath: args.configPath, logger });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwerk/mcp-bridge",
3
- "version": "2.8.6",
3
+ "version": "2.8.8",
4
4
  "description": "Standalone MCP server that multiplexes multiple MCP servers into one interface",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",