@willjackson/claude-code-bridge 0.2.4 → 0.4.1

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/cli.js CHANGED
@@ -1,18 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Bridge,
4
+ BridgeMcpServer,
4
5
  ConnectionState,
5
6
  WebSocketTransport,
6
7
  createLogger,
7
- detectEnvironment,
8
- discoverDdevProjects,
9
- discoverDockerPeers,
10
- discoverDocksalProjects,
11
- discoverLandoProjects,
12
- getDefaultConfig,
13
- getHostGateway,
14
8
  loadConfigSync
15
- } from "./chunk-5HWFDZKH.js";
9
+ } from "./chunk-MHUQYPTB.js";
16
10
 
17
11
  // src/cli/index.ts
18
12
  import { Command as Command7 } from "commander";
@@ -22,6 +16,7 @@ import { Command } from "commander";
22
16
  import * as fs from "fs";
23
17
  import * as path from "path";
24
18
  import * as os from "os";
19
+ import { spawn } from "child_process";
25
20
  import { minimatch } from "minimatch";
26
21
 
27
22
  // src/cli/utils.ts
@@ -303,6 +298,59 @@ function registerHandlers(bridge, config) {
303
298
  };
304
299
  }
305
300
  }
301
+ if (taskData?.action === "list_directory") {
302
+ const dirPath = taskData.path;
303
+ if (!dirPath) {
304
+ return {
305
+ success: false,
306
+ data: { error: "list_directory requires path" }
307
+ };
308
+ }
309
+ const fullPath = path.isAbsolute(dirPath) ? dirPath : path.join(cwd, dirPath);
310
+ const resolvedPath = path.resolve(fullPath);
311
+ const resolvedCwd = path.resolve(cwd);
312
+ if (!resolvedPath.startsWith(resolvedCwd)) {
313
+ return {
314
+ success: false,
315
+ data: { error: "Cannot list directories outside project directory" }
316
+ };
317
+ }
318
+ try {
319
+ if (!fs.existsSync(resolvedPath)) {
320
+ return {
321
+ success: false,
322
+ data: { error: `Directory not found: ${dirPath}` }
323
+ };
324
+ }
325
+ const stats = fs.statSync(resolvedPath);
326
+ if (!stats.isDirectory()) {
327
+ return {
328
+ success: false,
329
+ data: { error: `Not a directory: ${dirPath}` }
330
+ };
331
+ }
332
+ const entries = fs.readdirSync(resolvedPath, { withFileTypes: true });
333
+ const listing = entries.map((entry) => ({
334
+ name: entry.name,
335
+ type: entry.isDirectory() ? "directory" : "file"
336
+ }));
337
+ logger.info({ path: dirPath, count: listing.length }, "Directory listed successfully");
338
+ return {
339
+ success: true,
340
+ data: {
341
+ action: "list_directory",
342
+ path: dirPath,
343
+ entries: listing
344
+ }
345
+ };
346
+ } catch (err) {
347
+ logger.error({ error: err.message, path: dirPath }, "Failed to list directory");
348
+ return {
349
+ success: false,
350
+ data: { error: `Failed to list directory: ${err.message}` }
351
+ };
352
+ }
353
+ }
306
354
  const projectInfo = {
307
355
  cwd,
308
356
  platform: process.platform,
@@ -366,18 +414,6 @@ function registerHandlers(bridge, config) {
366
414
  }
367
415
  function buildBridgeConfig(options, globalOptions) {
368
416
  const fileConfig = loadConfigSync(globalOptions.config);
369
- let envConfig = {};
370
- if (options.auto) {
371
- const env = detectEnvironment();
372
- const defaultEnvConfig = getDefaultConfig(env);
373
- logger.info({ environment: env.type, isContainer: env.isContainer }, "Auto-detected environment");
374
- envConfig = {
375
- mode: defaultEnvConfig.mode,
376
- instanceName: defaultEnvConfig.instanceName,
377
- listen: defaultEnvConfig.listen,
378
- connect: defaultEnvConfig.connect
379
- };
380
- }
381
417
  const cliConfig = {};
382
418
  if (options.port) {
383
419
  cliConfig.listen = {
@@ -398,19 +434,19 @@ function buildBridgeConfig(options, globalOptions) {
398
434
  };
399
435
  }
400
436
  let mode = "peer";
401
- const hasListen = cliConfig.listen || envConfig.listen || fileConfig.listen;
402
- const hasConnect = cliConfig.connect || envConfig.connect || fileConfig.connect;
437
+ const hasListen = cliConfig.listen || fileConfig.listen;
438
+ const hasConnect = cliConfig.connect || fileConfig.connect;
403
439
  if (hasListen && !hasConnect) {
404
440
  mode = "host";
405
441
  } else if (hasConnect && !hasListen) {
406
442
  mode = "client";
407
443
  }
408
444
  const finalConfig = {
409
- mode: cliConfig.mode ?? envConfig.mode ?? fileConfig.mode ?? mode,
410
- instanceName: cliConfig.instanceName ?? envConfig.instanceName ?? fileConfig.instanceName ?? `bridge-${process.pid}`,
445
+ mode: cliConfig.mode ?? fileConfig.mode ?? mode,
446
+ instanceName: cliConfig.instanceName ?? fileConfig.instanceName ?? `bridge-${process.pid}`,
411
447
  listen: {
412
- port: cliConfig.listen?.port ?? envConfig.listen?.port ?? fileConfig.listen.port,
413
- host: cliConfig.listen?.host ?? envConfig.listen?.host ?? fileConfig.listen.host
448
+ port: cliConfig.listen?.port ?? fileConfig.listen.port,
449
+ host: cliConfig.listen?.host ?? fileConfig.listen.host
414
450
  },
415
451
  taskTimeout: fileConfig.interaction.taskTimeout,
416
452
  contextSharing: {
@@ -418,7 +454,7 @@ function buildBridgeConfig(options, globalOptions) {
418
454
  syncInterval: fileConfig.contextSharing.syncInterval
419
455
  }
420
456
  };
421
- const connectUrl = cliConfig.connect?.url ?? envConfig.connect?.url ?? fileConfig.connect?.url;
457
+ const connectUrl = cliConfig.connect?.url ?? fileConfig.connect?.url;
422
458
  if (connectUrl) {
423
459
  finalConfig.connect = {
424
460
  url: connectUrl
@@ -427,10 +463,12 @@ function buildBridgeConfig(options, globalOptions) {
427
463
  return finalConfig;
428
464
  }
429
465
  async function startBridge(options, globalOptions) {
430
- const { running, pid } = isAlreadyRunning();
431
- if (running) {
432
- console.error(`Bridge is already running (PID: ${pid})`);
433
- process.exit(1);
466
+ if (!process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {
467
+ const { running, pid } = isAlreadyRunning();
468
+ if (running) {
469
+ console.error(`Bridge is already running (PID: ${pid})`);
470
+ process.exit(1);
471
+ }
434
472
  }
435
473
  const config = buildBridgeConfig(options, globalOptions);
436
474
  console.log("Starting Claude Code Bridge...");
@@ -442,9 +480,24 @@ async function startBridge(options, globalOptions) {
442
480
  if (config.connect) {
443
481
  console.log(` Connecting to: ${config.connect.url}`);
444
482
  }
445
- if (options.daemon) {
446
- console.log(" Running in daemon mode");
447
- writePidFile(process.pid);
483
+ if (options.daemon && !process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {
484
+ const logFile = path.join(os.homedir(), ".claude-bridge", "bridge.log");
485
+ ensureBridgeDir();
486
+ const args = process.argv.slice(2).filter((arg) => arg !== "-d" && arg !== "--daemon");
487
+ const out = fs.openSync(logFile, "a");
488
+ const err = fs.openSync(logFile, "a");
489
+ const child = spawn(process.execPath, [process.argv[1], ...args], {
490
+ detached: true,
491
+ stdio: ["ignore", out, err],
492
+ env: { ...process.env, CLAUDE_BRIDGE_DAEMON_CHILD: "1" }
493
+ });
494
+ child.unref();
495
+ writePidFile(child.pid);
496
+ console.log(` Running in background (PID: ${child.pid})`);
497
+ console.log(` Log file: ${logFile}`);
498
+ console.log(` Use 'claude-bridge status' to check status`);
499
+ console.log(` Use 'claude-bridge stop' to stop the bridge`);
500
+ process.exit(0);
448
501
  }
449
502
  const bridge = new Bridge(config);
450
503
  setupGracefulShutdown({
@@ -453,7 +506,7 @@ async function startBridge(options, globalOptions) {
453
506
  await bridge.stop();
454
507
  logger.info("Bridge stopped");
455
508
  },
456
- afterCleanup: options.daemon ? removePidFile : void 0,
509
+ afterCleanup: process.env.CLAUDE_BRIDGE_DAEMON_CHILD ? removePidFile : void 0,
457
510
  verbose: true,
458
511
  timeout: 1e4
459
512
  });
@@ -470,7 +523,7 @@ async function startBridge(options, globalOptions) {
470
523
  excludePatterns: fileConfig.contextSharing.excludePatterns
471
524
  });
472
525
  }
473
- if (options.daemon) {
526
+ if (process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {
474
527
  writePidFile(process.pid);
475
528
  }
476
529
  console.log("Bridge started successfully.");
@@ -480,13 +533,13 @@ async function startBridge(options, globalOptions) {
480
533
  To connect from another bridge:`);
481
534
  console.log(` claude-bridge connect ws://localhost:${config.listen.port}`);
482
535
  }
483
- if (!options.daemon) {
536
+ if (!process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {
484
537
  console.log("\nPress Ctrl+C to stop.");
485
538
  }
486
539
  } catch (error) {
487
540
  logger.error({ error: error.message }, "Failed to start bridge");
488
541
  console.error(`Failed to start bridge: ${error.message}`);
489
- if (options.daemon) {
542
+ if (process.env.CLAUDE_BRIDGE_DAEMON_CHILD) {
490
543
  removePidFile();
491
544
  }
492
545
  process.exit(1);
@@ -494,7 +547,7 @@ To connect from another bridge:`);
494
547
  }
495
548
  function createStartCommand() {
496
549
  const command = new Command("start");
497
- command.description("Start the bridge server").option("-p, --port <port>", "Port to listen on (default: 8765 in container, 8766 native)").option("-h, --host <host>", "Host to bind to (default: 0.0.0.0)").option("-c, --connect <url>", "URL to connect to on startup (e.g., ws://localhost:8765)").option("-a, --auto", "Auto-detect environment and configure").option("-d, --daemon", "Run in background").option("--with-handlers", "Enable file reading and task handling capabilities").action(async (options) => {
550
+ command.description("Start the bridge server").option("-p, --port <port>", "Port to listen on (default: 8765)").option("-h, --host <host>", "Host to bind to (default: 0.0.0.0)").option("-c, --connect <url>", "URL to connect to on startup (e.g., ws://localhost:8765)").option("-d, --daemon", "Run in background").option("--with-handlers", "Enable file reading and task handling capabilities").action(async (options) => {
498
551
  const globalOptions = command.parent?.opts();
499
552
  await startBridge(options, globalOptions);
500
553
  });
@@ -841,76 +894,12 @@ function createConnectCommand() {
841
894
  return command;
842
895
  }
843
896
 
844
- // src/cli/commands/discover.ts
845
- import { Command as Command5 } from "commander";
846
- var logger5 = createLogger("cli:discover");
847
- function printPeersTable(peers) {
848
- if (peers.length === 0) {
849
- console.log("No bridges found.");
850
- console.log("");
851
- console.log("Suggestions:");
852
- console.log(" - Start a bridge: claude-bridge start");
853
- console.log(" - Add bridge labels to Docker containers");
854
- console.log(" - Install bridge addon in your Docksal/DDEV project");
855
- return;
856
- }
857
- const cols = {
858
- name: { title: "Name", width: 25 },
859
- source: { title: "Source", width: 12 },
860
- url: { title: "URL", width: 35 },
861
- status: { title: "Status", width: 12 }
862
- };
863
- console.log(
864
- cols.name.title.padEnd(cols.name.width) + cols.source.title.padEnd(cols.source.width) + cols.url.title.padEnd(cols.url.width) + cols.status.title.padEnd(cols.status.width)
865
- );
866
- console.log(
867
- "-".repeat(cols.name.width - 1) + " " + "-".repeat(cols.source.width - 1) + " " + "-".repeat(cols.url.width - 1) + " " + "-".repeat(cols.status.width - 1)
868
- );
869
- for (const peer of peers) {
870
- const row = peer.name.slice(0, cols.name.width - 1).padEnd(cols.name.width) + peer.source.padEnd(cols.source.width) + peer.url.slice(0, cols.url.width - 1).padEnd(cols.url.width) + (peer.status || "unknown").padEnd(cols.status.width);
871
- console.log(row);
872
- }
873
- console.log("");
874
- console.log("To connect to a bridge:");
875
- console.log(" claude-bridge connect <url>");
876
- }
877
- async function discoverBridges() {
878
- console.log("Discovering bridges on local network...\n");
879
- const allPeers = [];
880
- const dockerPeers = discoverDockerPeers();
881
- allPeers.push(...dockerPeers);
882
- logger5.debug({ count: dockerPeers.length }, "Docker peers discovered");
883
- const docksalPeers = discoverDocksalProjects();
884
- allPeers.push(...docksalPeers);
885
- logger5.debug({ count: docksalPeers.length }, "Docksal peers discovered");
886
- const ddevPeers = discoverDdevProjects();
887
- allPeers.push(...ddevPeers);
888
- logger5.debug({ count: ddevPeers.length }, "DDEV peers discovered");
889
- const landoPeers = discoverLandoProjects();
890
- allPeers.push(...landoPeers);
891
- logger5.debug({ count: landoPeers.length }, "Lando peers discovered");
892
- printPeersTable(allPeers);
893
- }
894
- function createDiscoverCommand() {
895
- const command = new Command5("discover");
896
- command.description("Discover bridges on local network").action(async () => {
897
- try {
898
- await discoverBridges();
899
- } catch (error) {
900
- logger5.error({ error: error.message }, "Discover command failed");
901
- console.error(`Error: ${error.message}`);
902
- process.exit(1);
903
- }
904
- });
905
- return command;
906
- }
907
-
908
897
  // src/cli/commands/info.ts
909
- import { Command as Command6 } from "commander";
898
+ import { Command as Command5 } from "commander";
910
899
  import * as fs4 from "fs";
911
900
  import * as path4 from "path";
912
901
  import * as os4 from "os";
913
- var logger6 = createLogger("cli:info");
902
+ var logger5 = createLogger("cli:info");
914
903
  function getConfigFilePath() {
915
904
  const localConfig = path4.join(process.cwd(), ".claude-bridge.yml");
916
905
  if (fs4.existsSync(localConfig)) {
@@ -944,30 +933,25 @@ function printKeyValue(key, value, indent = 0) {
944
933
  console.log(`${prefix}${key}: ${formatValue(value)}`);
945
934
  }
946
935
  function showInfo(globalOptions) {
947
- console.log("Claude Code Bridge - Environment Information");
948
- console.log("=".repeat(45));
949
- printSection("Environment");
950
- const env = detectEnvironment();
951
- printKeyValue("Type", env.type);
952
- printKeyValue("Platform", env.platform);
953
- printKeyValue("Is Container", env.isContainer);
954
- printKeyValue("Project Name", env.projectName);
955
- printKeyValue("Project Root", env.projectRoot);
936
+ console.log("Claude Code Bridge - System Information");
937
+ console.log("=".repeat(40));
938
+ printSection("System");
939
+ printKeyValue("Node Version", process.version);
940
+ printKeyValue("OS", `${os4.type()} ${os4.release()}`);
941
+ printKeyValue("Platform", process.platform);
942
+ printKeyValue("Arch", os4.arch());
943
+ printKeyValue("Home Directory", os4.homedir());
944
+ printKeyValue("Working Directory", process.cwd());
956
945
  printSection("Network");
957
- const hostGateway = getHostGateway();
958
- const envDefaults = getDefaultConfig(env);
959
- const listenPort = envDefaults.listen?.port ?? 8765;
960
- const listenHost = envDefaults.listen?.host ?? "0.0.0.0";
961
- printKeyValue("Host Gateway", hostGateway);
962
- printKeyValue("Recommended Port", listenPort);
963
- printKeyValue("Default Host", listenHost);
964
- if (env.isContainer) {
965
- console.log("");
966
- console.log(" Note: To connect from host machine:");
967
- console.log(` ws://localhost:${listenPort}`);
968
- console.log("");
969
- console.log(" To connect to host from this container:");
970
- console.log(` ws://${hostGateway}:8766`);
946
+ const interfaces = os4.networkInterfaces();
947
+ for (const [name, addrs] of Object.entries(interfaces)) {
948
+ if (addrs) {
949
+ for (const addr of addrs) {
950
+ if (addr.family === "IPv4" && !addr.internal) {
951
+ printKeyValue(name, addr.address);
952
+ }
953
+ }
954
+ }
971
955
  }
972
956
  printSection("Configuration");
973
957
  const configPath = globalOptions.config || getConfigFilePath();
@@ -1006,43 +990,16 @@ function showInfo(globalOptions) {
1006
990
  printKeyValue("Require Confirmation", config.interaction.requireConfirmation, 2);
1007
991
  printKeyValue("Notify On Activity", config.interaction.notifyOnActivity, 2);
1008
992
  printKeyValue("Task Timeout", `${config.interaction.taskTimeout}ms`, 2);
1009
- printSection("System");
1010
- printKeyValue("Node Version", process.version);
1011
- printKeyValue("OS", `${os4.type()} ${os4.release()}`);
1012
- printKeyValue("Arch", os4.arch());
1013
- printKeyValue("Home Directory", os4.homedir());
1014
- printKeyValue("Working Directory", process.cwd());
1015
- printSection("Environment Variables");
1016
- const relevantEnvVars = [
1017
- "DOCKSAL_STACK",
1018
- "DOCKSAL_PROJECT",
1019
- "IS_DDEV_PROJECT",
1020
- "DDEV_PROJECT",
1021
- "LANDO",
1022
- "LANDO_APP_NAME",
1023
- "LOG_LEVEL"
1024
- ];
1025
- let hasEnvVars = false;
1026
- for (const varName of relevantEnvVars) {
1027
- const value = process.env[varName];
1028
- if (value !== void 0) {
1029
- printKeyValue(varName, value);
1030
- hasEnvVars = true;
1031
- }
1032
- }
1033
- if (!hasEnvVars) {
1034
- console.log(" (no relevant environment variables set)");
1035
- }
1036
993
  console.log("");
1037
994
  }
1038
995
  function createInfoCommand() {
1039
- const command = new Command6("info");
1040
- command.description("Show environment and configuration info").action(() => {
996
+ const command = new Command5("info");
997
+ command.description("Show system and configuration info").action(() => {
1041
998
  try {
1042
999
  const globalOptions = command.parent?.opts() ?? {};
1043
1000
  showInfo(globalOptions);
1044
1001
  } catch (error) {
1045
- logger6.error({ error: error.message }, "Info command failed");
1002
+ logger5.error({ error: error.message }, "Info command failed");
1046
1003
  console.error(`Error: ${error.message}`);
1047
1004
  process.exit(1);
1048
1005
  }
@@ -1050,6 +1007,135 @@ function createInfoCommand() {
1050
1007
  return command;
1051
1008
  }
1052
1009
 
1010
+ // src/cli/commands/mcp-server.ts
1011
+ import { Command as Command6 } from "commander";
1012
+ import * as fs5 from "fs";
1013
+ import * as path5 from "path";
1014
+ import * as os5 from "os";
1015
+ import { spawn as spawn2 } from "child_process";
1016
+ var logger6 = createLogger("cli:mcp-server");
1017
+ var DEFAULT_DAEMON_PORT = 8766;
1018
+ function getStatusFilePath2() {
1019
+ const bridgeDir = path5.join(os5.homedir(), ".claude-bridge");
1020
+ return path5.join(bridgeDir, "status.json");
1021
+ }
1022
+ function getPidFilePath4() {
1023
+ const bridgeDir = path5.join(os5.homedir(), ".claude-bridge");
1024
+ return path5.join(bridgeDir, "bridge.pid");
1025
+ }
1026
+ function isDaemonRunning() {
1027
+ const pidFile = getPidFilePath4();
1028
+ if (!fs5.existsSync(pidFile)) {
1029
+ return { running: false };
1030
+ }
1031
+ try {
1032
+ const pid = parseInt(fs5.readFileSync(pidFile, "utf-8").trim(), 10);
1033
+ process.kill(pid, 0);
1034
+ const statusFile = getStatusFilePath2();
1035
+ if (fs5.existsSync(statusFile)) {
1036
+ const status = JSON.parse(fs5.readFileSync(statusFile, "utf-8"));
1037
+ return { running: true, pid, port: status.port };
1038
+ }
1039
+ return { running: true, pid };
1040
+ } catch {
1041
+ return { running: false };
1042
+ }
1043
+ }
1044
+ async function waitForDaemon(port, timeoutMs) {
1045
+ const startTime = Date.now();
1046
+ while (Date.now() - startTime < timeoutMs) {
1047
+ const { running, port: runningPort } = isDaemonRunning();
1048
+ if (running && (runningPort === port || runningPort === void 0)) {
1049
+ await new Promise((resolve2) => setTimeout(resolve2, 500));
1050
+ return;
1051
+ }
1052
+ await new Promise((resolve2) => setTimeout(resolve2, 200));
1053
+ }
1054
+ throw new Error(`Daemon did not start within ${timeoutMs}ms`);
1055
+ }
1056
+ function ensureBridgeDir2() {
1057
+ const bridgeDir = path5.join(os5.homedir(), ".claude-bridge");
1058
+ if (!fs5.existsSync(bridgeDir)) {
1059
+ fs5.mkdirSync(bridgeDir, { recursive: true });
1060
+ }
1061
+ }
1062
+ async function ensureDaemonRunning(port) {
1063
+ const { running, pid, port: runningPort } = isDaemonRunning();
1064
+ if (running) {
1065
+ const effectivePort = runningPort ?? port;
1066
+ console.error(`[MCP] Bridge daemon already running (PID: ${pid}, port: ${effectivePort})`);
1067
+ return effectivePort;
1068
+ }
1069
+ console.error("[MCP] Starting bridge daemon...");
1070
+ ensureBridgeDir2();
1071
+ const logFile = path5.join(os5.homedir(), ".claude-bridge", "bridge.log");
1072
+ const out = fs5.openSync(logFile, "a");
1073
+ const err = fs5.openSync(logFile, "a");
1074
+ const cliPath = process.argv[1];
1075
+ const child = spawn2(process.execPath, [cliPath, "start", "--daemon", "--port", String(port)], {
1076
+ detached: true,
1077
+ stdio: ["ignore", out, err]
1078
+ });
1079
+ child.unref();
1080
+ console.error(`[MCP] Daemon starting (PID: ${child.pid})`);
1081
+ try {
1082
+ await waitForDaemon(port, 5e3);
1083
+ console.error(`[MCP] Daemon ready on port ${port}`);
1084
+ return port;
1085
+ } catch (error) {
1086
+ console.error(`[MCP] Warning: Could not verify daemon is ready: ${error.message}`);
1087
+ return port;
1088
+ }
1089
+ }
1090
+ async function startMcpServer(options, _globalOptions) {
1091
+ let bridgeUrl = options.connect ?? `ws://localhost:${DEFAULT_DAEMON_PORT}`;
1092
+ if (!options.connect) {
1093
+ try {
1094
+ const port = await ensureDaemonRunning(DEFAULT_DAEMON_PORT);
1095
+ bridgeUrl = `ws://localhost:${port}`;
1096
+ } catch (error) {
1097
+ console.error(`[MCP] Warning: Could not ensure daemon is running: ${error.message}`);
1098
+ }
1099
+ }
1100
+ const config = {
1101
+ bridgeUrl,
1102
+ name: options.name ?? "claude-bridge",
1103
+ version: "0.4.0",
1104
+ instanceName: `mcp-server-${process.pid}`,
1105
+ taskTimeout: 6e4
1106
+ };
1107
+ const server = new BridgeMcpServer(config);
1108
+ setupGracefulShutdown({
1109
+ cleanup: async () => {
1110
+ console.error("[MCP] Shutting down...");
1111
+ await server.stop();
1112
+ },
1113
+ verbose: false,
1114
+ timeout: 5e3
1115
+ });
1116
+ handleUnhandledRejections({
1117
+ exit: true,
1118
+ logger: (msg, err) => {
1119
+ console.error(`[MCP] ${msg}: ${err.message}`);
1120
+ logger6.error({ error: err.message }, msg);
1121
+ }
1122
+ });
1123
+ try {
1124
+ await server.start();
1125
+ } catch (error) {
1126
+ console.error(`[MCP] Failed to start MCP server: ${error.message}`);
1127
+ process.exit(1);
1128
+ }
1129
+ }
1130
+ function createMcpServerCommand() {
1131
+ const command = new Command6("mcp-server");
1132
+ command.description("Start the MCP server for Claude Code integration").option("-c, --connect <url>", `Bridge WebSocket URL (default: ws://localhost:${DEFAULT_DAEMON_PORT})`).option("--name <name>", "MCP server name (default: claude-bridge)").action(async (options) => {
1133
+ const globalOptions = command.parent?.opts();
1134
+ await startMcpServer(options, globalOptions);
1135
+ });
1136
+ return command;
1137
+ }
1138
+
1053
1139
  // src/cli/index.ts
1054
1140
  var VERSION = "0.1.0";
1055
1141
  var logger7 = createLogger("cli");
@@ -1073,8 +1159,8 @@ async function main() {
1073
1159
  program.addCommand(createStopCommand());
1074
1160
  program.addCommand(createStatusCommand());
1075
1161
  program.addCommand(createConnectCommand());
1076
- program.addCommand(createDiscoverCommand());
1077
1162
  program.addCommand(createInfoCommand());
1163
+ program.addCommand(createMcpServerCommand());
1078
1164
  await program.parseAsync(process.argv);
1079
1165
  }
1080
1166
  main().catch((error) => {