@willjackson/claude-code-bridge 0.6.2 → 0.7.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.
@@ -148,9 +148,137 @@ var ConnectionState = /* @__PURE__ */ ((ConnectionState2) => {
148
148
  return ConnectionState2;
149
149
  })(ConnectionState || {});
150
150
 
151
+ // src/utils/tls.ts
152
+ import * as fs from "fs";
153
+ var logger = createLogger("tls");
154
+ function readCertFile(filePath) {
155
+ try {
156
+ return fs.readFileSync(filePath, "utf-8");
157
+ } catch (error) {
158
+ const err = error;
159
+ if (err.code === "ENOENT") {
160
+ throw new Error(`Certificate file not found: ${filePath}`);
161
+ }
162
+ if (err.code === "EACCES") {
163
+ throw new Error(`Permission denied reading certificate file: ${filePath}`);
164
+ }
165
+ throw new Error(`Failed to read certificate file ${filePath}: ${err.message}`);
166
+ }
167
+ }
168
+ async function loadCertificates(config) {
169
+ const options = {};
170
+ if (config.cert) {
171
+ logger.debug({ path: config.cert }, "Loading certificate");
172
+ options.cert = readCertFile(config.cert);
173
+ }
174
+ if (config.key) {
175
+ logger.debug({ path: config.key }, "Loading private key");
176
+ options.key = readCertFile(config.key);
177
+ }
178
+ if (config.ca) {
179
+ logger.debug({ path: config.ca }, "Loading CA certificate");
180
+ options.ca = readCertFile(config.ca);
181
+ }
182
+ options.rejectUnauthorized = config.rejectUnauthorized ?? true;
183
+ if (config.passphrase) {
184
+ options.passphrase = config.passphrase;
185
+ }
186
+ logger.info(
187
+ {
188
+ hasCert: !!options.cert,
189
+ hasKey: !!options.key,
190
+ hasCa: !!options.ca,
191
+ rejectUnauthorized: options.rejectUnauthorized
192
+ },
193
+ "TLS certificates loaded"
194
+ );
195
+ return options;
196
+ }
197
+ function loadCertificatesSync(config) {
198
+ const options = {};
199
+ if (config.cert) {
200
+ options.cert = readCertFile(config.cert);
201
+ }
202
+ if (config.key) {
203
+ options.key = readCertFile(config.key);
204
+ }
205
+ if (config.ca) {
206
+ options.ca = readCertFile(config.ca);
207
+ }
208
+ options.rejectUnauthorized = config.rejectUnauthorized ?? true;
209
+ if (config.passphrase) {
210
+ options.passphrase = config.passphrase;
211
+ }
212
+ return options;
213
+ }
214
+ function isFileReadable(filePath) {
215
+ try {
216
+ fs.accessSync(filePath, fs.constants.R_OK);
217
+ return true;
218
+ } catch {
219
+ return false;
220
+ }
221
+ }
222
+ function validateTLSConfig(config) {
223
+ const errors = [];
224
+ const warnings = [];
225
+ if (config.cert && !config.key) {
226
+ errors.push("Certificate provided without private key");
227
+ }
228
+ if (config.key && !config.cert) {
229
+ errors.push("Private key provided without certificate");
230
+ }
231
+ if (config.cert) {
232
+ if (!isFileReadable(config.cert)) {
233
+ errors.push(`Certificate file not readable: ${config.cert}`);
234
+ }
235
+ }
236
+ if (config.key) {
237
+ if (!isFileReadable(config.key)) {
238
+ errors.push(`Private key file not readable: ${config.key}`);
239
+ }
240
+ }
241
+ if (config.ca) {
242
+ if (!isFileReadable(config.ca)) {
243
+ errors.push(`CA certificate file not readable: ${config.ca}`);
244
+ }
245
+ }
246
+ if (config.rejectUnauthorized === false) {
247
+ warnings.push("TLS certificate verification is disabled - this is insecure for production use");
248
+ }
249
+ return {
250
+ valid: errors.length === 0,
251
+ errors,
252
+ warnings
253
+ };
254
+ }
255
+ function isTLSEnabled(config) {
256
+ if (!config) {
257
+ return false;
258
+ }
259
+ return !!(config.cert && config.key);
260
+ }
261
+ function createSecureContextOptions(loaded) {
262
+ const options = {};
263
+ if (loaded.cert) {
264
+ options.cert = loaded.cert;
265
+ }
266
+ if (loaded.key) {
267
+ options.key = loaded.key;
268
+ }
269
+ if (loaded.ca) {
270
+ options.ca = loaded.ca;
271
+ }
272
+ if (loaded.passphrase) {
273
+ options.passphrase = loaded.passphrase;
274
+ }
275
+ return options;
276
+ }
277
+
151
278
  // src/transport/websocket.ts
152
279
  import WebSocket from "ws";
153
- var logger = createLogger("websocket-transport");
280
+ import * as https from "https";
281
+ var logger2 = createLogger("websocket-transport");
154
282
  var DEFAULT_RECONNECT_INTERVAL = 1e3;
155
283
  var DEFAULT_MAX_RECONNECT_ATTEMPTS = 10;
156
284
  var DEFAULT_HEARTBEAT_INTERVAL = 3e4;
@@ -176,6 +304,7 @@ var WebSocketTransport = class {
176
304
  reconnectingHandlers = [];
177
305
  /**
178
306
  * Build the WebSocket URL from the connection configuration
307
+ * Uses wss:// if TLS is configured, ws:// otherwise
179
308
  */
180
309
  buildUrl(config) {
181
310
  if (config.url) {
@@ -183,7 +312,79 @@ var WebSocketTransport = class {
183
312
  }
184
313
  const host = config.host ?? "localhost";
185
314
  const port = config.port ?? 8765;
186
- return `ws://${host}:${port}`;
315
+ const useTls = config.tls?.ca || config.tls?.rejectUnauthorized !== void 0;
316
+ const protocol = useTls ? "wss" : "ws";
317
+ return `${protocol}://${host}:${port}`;
318
+ }
319
+ /**
320
+ * Build WebSocket options including TLS and auth configuration
321
+ */
322
+ buildWsOptions(config) {
323
+ const options = {};
324
+ if (config.tls) {
325
+ try {
326
+ const tlsOptions = loadCertificatesSync(config.tls);
327
+ const agentOptions = {
328
+ rejectUnauthorized: tlsOptions.rejectUnauthorized ?? true
329
+ };
330
+ if (tlsOptions.ca) {
331
+ agentOptions.ca = tlsOptions.ca;
332
+ }
333
+ if (tlsOptions.cert) {
334
+ agentOptions.cert = tlsOptions.cert;
335
+ }
336
+ if (tlsOptions.key) {
337
+ agentOptions.key = tlsOptions.key;
338
+ }
339
+ if (tlsOptions.passphrase) {
340
+ agentOptions.passphrase = tlsOptions.passphrase;
341
+ }
342
+ options.agent = new https.Agent(agentOptions);
343
+ if (tlsOptions.rejectUnauthorized !== void 0) {
344
+ options.rejectUnauthorized = tlsOptions.rejectUnauthorized;
345
+ }
346
+ if (tlsOptions.ca) {
347
+ options.ca = tlsOptions.ca;
348
+ }
349
+ logger2.debug(
350
+ { hasCa: !!tlsOptions.ca, rejectUnauthorized: tlsOptions.rejectUnauthorized },
351
+ "TLS options configured for client"
352
+ );
353
+ } catch (error) {
354
+ logger2.error({ error: error.message }, "Failed to load TLS certificates");
355
+ throw error;
356
+ }
357
+ }
358
+ if (config.auth && config.auth.type !== "none") {
359
+ options.headers = options.headers || {};
360
+ if (config.auth.token) {
361
+ options.headers["Authorization"] = `Bearer ${config.auth.token}`;
362
+ }
363
+ if (config.auth.password) {
364
+ options.headers["X-Auth-Password"] = config.auth.password;
365
+ }
366
+ logger2.debug(
367
+ { hasToken: !!config.auth.token, hasPassword: !!config.auth.password },
368
+ "Auth headers configured"
369
+ );
370
+ }
371
+ return options;
372
+ }
373
+ /**
374
+ * Build URL with auth query parameters (fallback for servers that don't support headers)
375
+ */
376
+ buildUrlWithAuth(baseUrl, config) {
377
+ if (!config.auth || config.auth.type === "none") {
378
+ return baseUrl;
379
+ }
380
+ const url = new URL(baseUrl);
381
+ if (config.auth.token) {
382
+ url.searchParams.set("token", config.auth.token);
383
+ }
384
+ if (config.auth.password) {
385
+ url.searchParams.set("password", config.auth.password);
386
+ }
387
+ return url.toString();
187
388
  }
188
389
  /**
189
390
  * Establish connection to a remote peer
@@ -206,15 +407,20 @@ var WebSocketTransport = class {
206
407
  throw new Error("No configuration set");
207
408
  }
208
409
  this.state = "CONNECTING" /* CONNECTING */;
209
- const url = this.buildUrl(this.config);
210
- logger.debug({ url, attempt: this.reconnectAttempts }, "Connecting to WebSocket server");
410
+ const baseUrl = this.buildUrl(this.config);
411
+ const wsOptions = this.buildWsOptions(this.config);
412
+ const url = this.buildUrlWithAuth(baseUrl, this.config);
413
+ logger2.debug(
414
+ { url: baseUrl, attempt: this.reconnectAttempts, hasOptions: Object.keys(wsOptions).length > 0 },
415
+ "Connecting to WebSocket server"
416
+ );
211
417
  return new Promise((resolve, reject) => {
212
418
  try {
213
- this.ws = new WebSocket(url);
419
+ this.ws = Object.keys(wsOptions).length > 0 ? new WebSocket(url, wsOptions) : new WebSocket(url);
214
420
  this.ws.on("open", () => {
215
421
  this.state = "CONNECTED" /* CONNECTED */;
216
422
  this.reconnectAttempts = 0;
217
- logger.info({ url }, "WebSocket connection established");
423
+ logger2.info({ url }, "WebSocket connection established");
218
424
  this.startHeartbeat();
219
425
  this.flushMessageQueue();
220
426
  resolve();
@@ -229,7 +435,7 @@ var WebSocketTransport = class {
229
435
  const wasConnected = this.state === "CONNECTED" /* CONNECTED */;
230
436
  const wasReconnecting = this.state === "RECONNECTING" /* RECONNECTING */;
231
437
  this.stopHeartbeat();
232
- logger.info({ code, reason: reason.toString() }, "WebSocket connection closed");
438
+ logger2.info({ code, reason: reason.toString() }, "WebSocket connection closed");
233
439
  if (wasConnected) {
234
440
  this.notifyDisconnect();
235
441
  }
@@ -240,7 +446,7 @@ var WebSocketTransport = class {
240
446
  }
241
447
  });
242
448
  this.ws.on("error", (error) => {
243
- logger.error({ error: error.message }, "WebSocket error");
449
+ logger2.error({ error: error.message }, "WebSocket error");
244
450
  if (this.state === "CONNECTING" /* CONNECTING */ && this.reconnectAttempts === 0) {
245
451
  this.state = "DISCONNECTED" /* DISCONNECTED */;
246
452
  reject(error);
@@ -266,7 +472,7 @@ var WebSocketTransport = class {
266
472
  this.state = "DISCONNECTED" /* DISCONNECTED */;
267
473
  return;
268
474
  }
269
- logger.debug("Disconnecting WebSocket");
475
+ logger2.debug("Disconnecting WebSocket");
270
476
  return new Promise((resolve) => {
271
477
  if (!this.ws) {
272
478
  this.state = "DISCONNECTED" /* DISCONNECTED */;
@@ -316,11 +522,11 @@ var WebSocketTransport = class {
316
522
  throw new Error("Not connected");
317
523
  }
318
524
  const serialized = serializeMessage(message);
319
- logger.debug({ messageId: message.id, type: message.type }, "Sending message");
525
+ logger2.debug({ messageId: message.id, type: message.type }, "Sending message");
320
526
  return new Promise((resolve, reject) => {
321
527
  this.ws.send(serialized, (error) => {
322
528
  if (error) {
323
- logger.error({ error: error.message, messageId: message.id }, "Failed to send message");
529
+ logger2.error({ error: error.message, messageId: message.id }, "Failed to send message");
324
530
  reject(error);
325
531
  } else {
326
532
  resolve();
@@ -333,7 +539,7 @@ var WebSocketTransport = class {
333
539
  */
334
540
  queueMessage(message) {
335
541
  this.messageQueue.push(message);
336
- logger.debug({ messageId: message.id, queueLength: this.messageQueue.length }, "Message queued for delivery");
542
+ logger2.debug({ messageId: message.id, queueLength: this.messageQueue.length }, "Message queued for delivery");
337
543
  }
338
544
  /**
339
545
  * Flush all queued messages after reconnection
@@ -342,14 +548,14 @@ var WebSocketTransport = class {
342
548
  if (this.messageQueue.length === 0) {
343
549
  return;
344
550
  }
345
- logger.info({ queueLength: this.messageQueue.length }, "Flushing message queue");
551
+ logger2.info({ queueLength: this.messageQueue.length }, "Flushing message queue");
346
552
  const messages = [...this.messageQueue];
347
553
  this.messageQueue = [];
348
554
  for (const message of messages) {
349
555
  try {
350
556
  await this.sendImmediate(message);
351
557
  } catch (error) {
352
- logger.error({ error: error.message, messageId: message.id }, "Failed to send queued message");
558
+ logger2.error({ error: error.message, messageId: message.id }, "Failed to send queued message");
353
559
  this.messageQueue.unshift(message);
354
560
  break;
355
561
  }
@@ -396,20 +602,20 @@ var WebSocketTransport = class {
396
602
  */
397
603
  handleIncomingMessage(data) {
398
604
  const messageString = data.toString();
399
- logger.debug({ dataLength: messageString.length }, "Received message");
605
+ logger2.debug({ dataLength: messageString.length }, "Received message");
400
606
  const result = safeDeserializeMessage(messageString);
401
607
  if (!result.success) {
402
- logger.warn({ error: result.error.message }, "Failed to parse incoming message");
608
+ logger2.warn({ error: result.error.message }, "Failed to parse incoming message");
403
609
  this.notifyError(new Error(`Invalid message format: ${result.error.message}`));
404
610
  return;
405
611
  }
406
612
  const message = result.data;
407
- logger.debug({ messageId: message.id, type: message.type }, "Parsed message");
613
+ logger2.debug({ messageId: message.id, type: message.type }, "Parsed message");
408
614
  for (const handler of this.messageHandlers) {
409
615
  try {
410
616
  handler(message);
411
617
  } catch (error) {
412
- logger.error({ error: error.message }, "Message handler threw error");
618
+ logger2.error({ error: error.message }, "Message handler threw error");
413
619
  }
414
620
  }
415
621
  }
@@ -421,7 +627,7 @@ var WebSocketTransport = class {
421
627
  try {
422
628
  handler();
423
629
  } catch (error) {
424
- logger.error({ error: error.message }, "Disconnect handler threw error");
630
+ logger2.error({ error: error.message }, "Disconnect handler threw error");
425
631
  }
426
632
  }
427
633
  }
@@ -433,7 +639,7 @@ var WebSocketTransport = class {
433
639
  try {
434
640
  handler(error);
435
641
  } catch (handlerError) {
436
- logger.error({ error: handlerError.message }, "Error handler threw error");
642
+ logger2.error({ error: handlerError.message }, "Error handler threw error");
437
643
  }
438
644
  }
439
645
  }
@@ -445,7 +651,7 @@ var WebSocketTransport = class {
445
651
  try {
446
652
  handler(attempt, maxAttempts);
447
653
  } catch (error) {
448
- logger.error({ error: error.message }, "Reconnecting handler threw error");
654
+ logger2.error({ error: error.message }, "Reconnecting handler threw error");
449
655
  }
450
656
  }
451
657
  }
@@ -473,7 +679,7 @@ var WebSocketTransport = class {
473
679
  this.reconnectAttempts++;
474
680
  const maxAttempts = this.config?.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;
475
681
  const interval = this.config?.reconnectInterval ?? DEFAULT_RECONNECT_INTERVAL;
476
- logger.info(
682
+ logger2.info(
477
683
  { attempt: this.reconnectAttempts, maxAttempts, interval },
478
684
  "Scheduling reconnection attempt"
479
685
  );
@@ -482,13 +688,13 @@ var WebSocketTransport = class {
482
688
  this.reconnectTimer = null;
483
689
  try {
484
690
  await this.establishConnection();
485
- logger.info({ attempts: this.reconnectAttempts }, "Reconnection successful");
691
+ logger2.info({ attempts: this.reconnectAttempts }, "Reconnection successful");
486
692
  } catch (error) {
487
- logger.warn({ error: error.message }, "Reconnection attempt failed");
693
+ logger2.warn({ error: error.message }, "Reconnection attempt failed");
488
694
  if (this.shouldReconnect()) {
489
695
  this.scheduleReconnect();
490
696
  } else {
491
- logger.error({ maxAttempts }, "Max reconnection attempts reached, giving up");
697
+ logger2.error({ maxAttempts }, "Max reconnection attempts reached, giving up");
492
698
  this.state = "DISCONNECTED" /* DISCONNECTED */;
493
699
  this.notifyError(new Error(`Failed to reconnect after ${maxAttempts} attempts`));
494
700
  }
@@ -515,7 +721,7 @@ var WebSocketTransport = class {
515
721
  this.heartbeatInterval = setInterval(() => {
516
722
  this.sendPing();
517
723
  }, DEFAULT_HEARTBEAT_INTERVAL);
518
- logger.debug({ interval: DEFAULT_HEARTBEAT_INTERVAL }, "Heartbeat monitoring started");
724
+ logger2.debug({ interval: DEFAULT_HEARTBEAT_INTERVAL }, "Heartbeat monitoring started");
519
725
  }
520
726
  /**
521
727
  * Stop the heartbeat monitoring
@@ -539,7 +745,7 @@ var WebSocketTransport = class {
539
745
  return;
540
746
  }
541
747
  if (this.awaitingPong) {
542
- logger.warn("No pong received, connection may be dead");
748
+ logger2.warn("No pong received, connection may be dead");
543
749
  this.handleHeartbeatTimeout();
544
750
  return;
545
751
  }
@@ -550,7 +756,7 @@ var WebSocketTransport = class {
550
756
  this.handleHeartbeatTimeout();
551
757
  }
552
758
  }, HEARTBEAT_TIMEOUT);
553
- logger.debug("Ping sent");
759
+ logger2.debug("Ping sent");
554
760
  }
555
761
  /**
556
762
  * Handle pong response from peer
@@ -561,13 +767,13 @@ var WebSocketTransport = class {
561
767
  clearTimeout(this.heartbeatTimeout);
562
768
  this.heartbeatTimeout = null;
563
769
  }
564
- logger.debug("Pong received");
770
+ logger2.debug("Pong received");
565
771
  }
566
772
  /**
567
773
  * Handle heartbeat timeout (no pong received)
568
774
  */
569
775
  handleHeartbeatTimeout() {
570
- logger.warn("Heartbeat timeout - closing connection");
776
+ logger2.warn("Heartbeat timeout - closing connection");
571
777
  this.awaitingPong = false;
572
778
  if (this.heartbeatTimeout) {
573
779
  clearTimeout(this.heartbeatTimeout);
@@ -594,6 +800,290 @@ var WebSocketTransport = class {
594
800
  }
595
801
  };
596
802
 
803
+ // src/utils/auth.ts
804
+ import * as crypto from "crypto";
805
+ var logger3 = createLogger("auth");
806
+ function ipv4ToInt(ip) {
807
+ const parts = ip.split(".").map(Number);
808
+ if (parts.length !== 4 || parts.some((p) => isNaN(p) || p < 0 || p > 255)) {
809
+ return -1;
810
+ }
811
+ return parts[0] << 24 | parts[1] << 16 | parts[2] << 8 | parts[3];
812
+ }
813
+ function matchesCidr(clientIp, cidr) {
814
+ let normalizedIp = clientIp;
815
+ if (normalizedIp.startsWith("::ffff:")) {
816
+ normalizedIp = normalizedIp.substring(7);
817
+ }
818
+ const [network, prefixStr] = cidr.split("/");
819
+ const prefix = prefixStr ? parseInt(prefixStr, 10) : 32;
820
+ if (prefix < 0 || prefix > 32) {
821
+ return false;
822
+ }
823
+ const clientInt = ipv4ToInt(normalizedIp);
824
+ const networkInt = ipv4ToInt(network);
825
+ if (clientInt === -1 || networkInt === -1) {
826
+ return normalizedIp === network || clientIp === cidr;
827
+ }
828
+ const mask = prefix === 0 ? 0 : -1 << 32 - prefix >>> 0;
829
+ return (clientInt & mask) >>> 0 === (networkInt & mask) >>> 0;
830
+ }
831
+ function validateIp(clientIp, allowedCidrs) {
832
+ if (!allowedCidrs || allowedCidrs.length === 0) {
833
+ return false;
834
+ }
835
+ for (const cidr of allowedCidrs) {
836
+ if (matchesCidr(clientIp, cidr)) {
837
+ logger3.debug({ clientIp, matchedCidr: cidr }, "IP matched allowed range");
838
+ return true;
839
+ }
840
+ }
841
+ logger3.debug({ clientIp, allowedCidrs }, "IP did not match any allowed range");
842
+ return false;
843
+ }
844
+ function timingSafeCompare(provided, expected) {
845
+ const providedBuffer = Buffer.from(provided, "utf-8");
846
+ const expectedBuffer = Buffer.from(expected, "utf-8");
847
+ if (providedBuffer.length !== expectedBuffer.length) {
848
+ crypto.timingSafeEqual(expectedBuffer, expectedBuffer);
849
+ return false;
850
+ }
851
+ return crypto.timingSafeEqual(providedBuffer, expectedBuffer);
852
+ }
853
+ function validateToken(provided, expected) {
854
+ if (!provided) {
855
+ return false;
856
+ }
857
+ return timingSafeCompare(provided, expected);
858
+ }
859
+ function validatePassword(provided, expected) {
860
+ if (!provided) {
861
+ return false;
862
+ }
863
+ return timingSafeCompare(provided, expected);
864
+ }
865
+ function getClientIp(request) {
866
+ const forwarded = request.headers["x-forwarded-for"];
867
+ if (forwarded) {
868
+ const ips = Array.isArray(forwarded) ? forwarded[0] : forwarded;
869
+ const clientIp = ips.split(",")[0].trim();
870
+ if (clientIp) {
871
+ return clientIp;
872
+ }
873
+ }
874
+ return request.socket.remoteAddress || "unknown";
875
+ }
876
+ function extractCredentials(request) {
877
+ const credentials = {
878
+ clientIp: getClientIp(request)
879
+ };
880
+ const url = new URL(request.url || "/", `http://${request.headers.host || "localhost"}`);
881
+ const queryToken = url.searchParams.get("token");
882
+ if (queryToken) {
883
+ credentials.token = queryToken;
884
+ }
885
+ const queryPassword = url.searchParams.get("password");
886
+ if (queryPassword) {
887
+ credentials.password = queryPassword;
888
+ }
889
+ const authHeader = request.headers.authorization;
890
+ if (authHeader) {
891
+ if (authHeader.startsWith("Bearer ")) {
892
+ credentials.token = authHeader.substring(7);
893
+ } else if (authHeader.startsWith("Basic ")) {
894
+ try {
895
+ const decoded = Buffer.from(authHeader.substring(6), "base64").toString("utf-8");
896
+ const [, password] = decoded.split(":");
897
+ if (password) {
898
+ credentials.password = password;
899
+ }
900
+ } catch {
901
+ }
902
+ }
903
+ }
904
+ const tokenHeader = request.headers["x-auth-token"];
905
+ if (tokenHeader && !credentials.token) {
906
+ credentials.token = Array.isArray(tokenHeader) ? tokenHeader[0] : tokenHeader;
907
+ }
908
+ const passwordHeader = request.headers["x-auth-password"];
909
+ if (passwordHeader && !credentials.password) {
910
+ credentials.password = Array.isArray(passwordHeader) ? passwordHeader[0] : passwordHeader;
911
+ }
912
+ return credentials;
913
+ }
914
+ var Authenticator = class {
915
+ config;
916
+ /**
917
+ * Create a new Authenticator
918
+ * @param config - Authentication configuration
919
+ */
920
+ constructor(config) {
921
+ this.config = config;
922
+ }
923
+ /**
924
+ * Authenticate a request
925
+ * @param request - The incoming HTTP request (WebSocket upgrade request)
926
+ * @returns Authentication result
927
+ */
928
+ authenticate(request) {
929
+ if (this.config.type === "none") {
930
+ return { success: true };
931
+ }
932
+ const credentials = extractCredentials(request);
933
+ return this.authenticateWithCredentials(credentials);
934
+ }
935
+ /**
936
+ * Authenticate with extracted credentials
937
+ * @param credentials - The extracted credentials
938
+ * @returns Authentication result
939
+ */
940
+ authenticateWithCredentials(credentials) {
941
+ const { clientIp } = credentials;
942
+ if (this.config.type === "none") {
943
+ return { success: true, clientIp };
944
+ }
945
+ const results = [];
946
+ if (this.config.token) {
947
+ const tokenValid = validateToken(credentials.token, this.config.token);
948
+ results.push({ method: "token", success: tokenValid });
949
+ if (tokenValid) {
950
+ logger3.debug({ clientIp }, "Token authentication succeeded");
951
+ } else {
952
+ logger3.debug({ clientIp }, "Token authentication failed");
953
+ }
954
+ }
955
+ if (this.config.password) {
956
+ const passwordValid = validatePassword(credentials.password, this.config.password);
957
+ results.push({ method: "password", success: passwordValid });
958
+ if (passwordValid) {
959
+ logger3.debug({ clientIp }, "Password authentication succeeded");
960
+ } else {
961
+ logger3.debug({ clientIp }, "Password authentication failed");
962
+ }
963
+ }
964
+ if (this.config.allowedIps && this.config.allowedIps.length > 0) {
965
+ const ipValid = validateIp(clientIp, this.config.allowedIps);
966
+ results.push({ method: "ip", success: ipValid });
967
+ if (ipValid) {
968
+ logger3.debug({ clientIp }, "IP authentication succeeded");
969
+ } else {
970
+ logger3.debug({ clientIp }, "IP authentication failed");
971
+ }
972
+ }
973
+ if (results.length === 0) {
974
+ logger3.warn("Authentication configured but no methods available");
975
+ return {
976
+ success: false,
977
+ error: "Authentication required but not configured",
978
+ clientIp
979
+ };
980
+ }
981
+ if (this.config.requireAll) {
982
+ const allPassed = results.every((r) => r.success);
983
+ if (allPassed) {
984
+ logger3.info({ clientIp, methods: results.map((r) => r.method) }, "All authentication methods passed");
985
+ return { success: true, clientIp };
986
+ } else {
987
+ const failed = results.filter((r) => !r.success).map((r) => r.method);
988
+ logger3.warn({ clientIp, failedMethods: failed }, "Authentication failed (requireAll mode)");
989
+ return {
990
+ success: false,
991
+ error: `Authentication failed for methods: ${failed.join(", ")}`,
992
+ clientIp
993
+ };
994
+ }
995
+ } else {
996
+ const passed = results.find((r) => r.success);
997
+ if (passed) {
998
+ logger3.info({ clientIp, method: passed.method }, "Authentication succeeded");
999
+ return { success: true, method: passed.method, clientIp };
1000
+ } else {
1001
+ logger3.warn({ clientIp }, "All authentication methods failed");
1002
+ return {
1003
+ success: false,
1004
+ error: "Authentication failed",
1005
+ clientIp
1006
+ };
1007
+ }
1008
+ }
1009
+ }
1010
+ /**
1011
+ * Get the configured authentication type
1012
+ */
1013
+ getType() {
1014
+ return this.config.type;
1015
+ }
1016
+ /**
1017
+ * Check if authentication is required
1018
+ */
1019
+ isRequired() {
1020
+ return this.config.type !== "none";
1021
+ }
1022
+ };
1023
+ function createAuthConfigFromOptions(options) {
1024
+ const hasToken = !!options.authToken;
1025
+ const hasPassword = !!options.authPassword;
1026
+ const hasIp = options.authIp && options.authIp.length > 0;
1027
+ let type = "none";
1028
+ if (hasToken || hasPassword || hasIp) {
1029
+ const count = [hasToken, hasPassword, hasIp].filter(Boolean).length;
1030
+ if (count > 1) {
1031
+ type = "combined";
1032
+ } else if (hasToken) {
1033
+ type = "token";
1034
+ } else if (hasPassword) {
1035
+ type = "password";
1036
+ } else if (hasIp) {
1037
+ type = "ip";
1038
+ }
1039
+ }
1040
+ return {
1041
+ type,
1042
+ token: options.authToken,
1043
+ password: options.authPassword,
1044
+ allowedIps: options.authIp,
1045
+ requireAll: options.authRequireAll ?? false
1046
+ };
1047
+ }
1048
+ function validateAuthConfig(config) {
1049
+ const errors = [];
1050
+ const warnings = [];
1051
+ if (config.type === "token" && !config.token) {
1052
+ errors.push("Token authentication requires a token");
1053
+ }
1054
+ if (config.type === "password" && !config.password) {
1055
+ errors.push("Password authentication requires a password");
1056
+ }
1057
+ if (config.type === "ip" && (!config.allowedIps || config.allowedIps.length === 0)) {
1058
+ errors.push("IP authentication requires at least one allowed IP/CIDR");
1059
+ }
1060
+ if (config.allowedIps) {
1061
+ for (const cidr of config.allowedIps) {
1062
+ const [ip, prefix] = cidr.split("/");
1063
+ if (ipv4ToInt(ip) === -1) {
1064
+ warnings.push(`IP address may not be valid IPv4: ${ip}`);
1065
+ }
1066
+ if (prefix !== void 0) {
1067
+ const prefixNum = parseInt(prefix, 10);
1068
+ if (isNaN(prefixNum) || prefixNum < 0 || prefixNum > 32) {
1069
+ errors.push(`Invalid CIDR prefix: ${cidr}`);
1070
+ }
1071
+ }
1072
+ }
1073
+ }
1074
+ if (config.token && config.token.length < 16) {
1075
+ warnings.push("Token is shorter than 16 characters - consider using a longer token");
1076
+ }
1077
+ if (config.password && config.password.length < 8) {
1078
+ warnings.push("Password is shorter than 8 characters - consider using a longer password");
1079
+ }
1080
+ return {
1081
+ valid: errors.length === 0,
1082
+ errors,
1083
+ warnings
1084
+ };
1085
+ }
1086
+
597
1087
  // src/bridge/messages.ts
598
1088
  function createContextSyncMessage(source, context) {
599
1089
  const message = createMessage("context_sync", source);
@@ -644,17 +1134,20 @@ function createNotificationMessage(source, notification) {
644
1134
 
645
1135
  // src/bridge/core.ts
646
1136
  import { WebSocketServer } from "ws";
1137
+ import * as https2 from "https";
647
1138
  import { v4 as uuidv42 } from "uuid";
648
- import * as fs from "fs";
1139
+ import * as fs2 from "fs";
649
1140
  import * as path from "path";
650
1141
  import * as os from "os";
651
- var logger2 = createLogger("bridge");
1142
+ var logger4 = createLogger("bridge");
652
1143
  var Bridge = class {
653
1144
  config;
654
1145
  server = null;
1146
+ httpsServer = null;
655
1147
  clientTransport = null;
656
1148
  peers = /* @__PURE__ */ new Map();
657
1149
  started = false;
1150
+ authenticator = null;
658
1151
  // Event handlers
659
1152
  peerConnectedHandlers = [];
660
1153
  peerDisconnectedHandlers = [];
@@ -675,7 +1168,7 @@ var Bridge = class {
675
1168
  constructor(config) {
676
1169
  this.config = config;
677
1170
  this.validateConfig();
678
- logger2.info({ instanceName: config.instanceName, mode: config.mode }, "Bridge instance created");
1171
+ logger4.info({ instanceName: config.instanceName, mode: config.mode }, "Bridge instance created");
679
1172
  }
680
1173
  /**
681
1174
  * Validate the configuration based on mode requirements
@@ -688,28 +1181,32 @@ var Bridge = class {
688
1181
  if (mode === "client" && !connect) {
689
1182
  throw new Error("'client' mode requires 'connect' configuration");
690
1183
  }
1184
+ if (mode === "peer" && !listen && !connect) {
1185
+ throw new Error("'peer' mode requires either 'listen' or 'connect' configuration");
1186
+ }
691
1187
  }
692
1188
  /**
693
1189
  * Start the bridge based on configured mode
694
1190
  * - 'host': Starts WebSocket server, sends commands via MCP
695
1191
  * - 'client': Connects to host, receives and executes commands
1192
+ * - 'peer': Starts server (if listen configured) and connects to remote (if connect configured)
696
1193
  */
697
1194
  async start() {
698
1195
  if (this.started) {
699
1196
  throw new Error("Bridge is already started");
700
1197
  }
701
1198
  const { mode } = this.config;
702
- logger2.info({ mode }, "Starting bridge");
1199
+ logger4.info({ mode }, "Starting bridge");
703
1200
  try {
704
- if (mode === "host" && this.config.listen) {
1201
+ if ((mode === "host" || mode === "peer") && this.config.listen) {
705
1202
  await this.startServer();
706
1203
  }
707
- if (mode === "client" && this.config.connect) {
1204
+ if ((mode === "client" || mode === "peer") && this.config.connect) {
708
1205
  await this.connectToRemote();
709
1206
  }
710
1207
  this.started = true;
711
1208
  this.writeStatusFile();
712
- logger2.info({ mode, instanceName: this.config.instanceName }, "Bridge started successfully");
1209
+ logger4.info({ mode, instanceName: this.config.instanceName }, "Bridge started successfully");
713
1210
  } catch (error) {
714
1211
  await this.cleanup();
715
1212
  throw error;
@@ -722,10 +1219,10 @@ var Bridge = class {
722
1219
  if (!this.started) {
723
1220
  return;
724
1221
  }
725
- logger2.info("Stopping bridge");
1222
+ logger4.info("Stopping bridge");
726
1223
  await this.cleanup();
727
1224
  this.started = false;
728
- logger2.info("Bridge stopped");
1225
+ logger4.info("Bridge stopped");
729
1226
  }
730
1227
  /**
731
1228
  * Get list of connected peers
@@ -766,9 +1263,9 @@ var Bridge = class {
766
1263
  });
767
1264
  transport._peerId = peerId;
768
1265
  this.notifyPeerConnected(peerInfo);
769
- logger2.info({ peerId, url }, "Connected to remote peer");
1266
+ logger4.info({ peerId, url }, "Connected to remote peer");
770
1267
  } catch (error) {
771
- logger2.error({ error: error.message, url }, "Failed to connect to remote peer");
1268
+ logger4.error({ error: error.message, url }, "Failed to connect to remote peer");
772
1269
  throw error;
773
1270
  }
774
1271
  }
@@ -789,7 +1286,7 @@ var Bridge = class {
789
1286
  }
790
1287
  this.peers.delete(peerId);
791
1288
  this.notifyPeerDisconnected(peer.info);
792
- logger2.info({ peerId }, "Disconnected from peer");
1289
+ logger4.info({ peerId }, "Disconnected from peer");
793
1290
  }
794
1291
  /**
795
1292
  * Send a message to a specific peer
@@ -817,7 +1314,7 @@ var Bridge = class {
817
1314
  } else {
818
1315
  throw new Error("No transport available for peer");
819
1316
  }
820
- logger2.debug({ peerId, messageId: message.id, type: message.type }, "Sent message to peer");
1317
+ logger4.debug({ peerId, messageId: message.id, type: message.type }, "Sent message to peer");
821
1318
  }
822
1319
  /**
823
1320
  * Broadcast a message to all connected peers
@@ -826,11 +1323,11 @@ var Bridge = class {
826
1323
  async broadcast(message) {
827
1324
  const sendPromises = Array.from(this.peers.keys()).map(
828
1325
  (peerId) => this.sendToPeer(peerId, message).catch((error) => {
829
- logger2.error({ error: error.message, peerId }, "Failed to send to peer");
1326
+ logger4.error({ error: error.message, peerId }, "Failed to send to peer");
830
1327
  })
831
1328
  );
832
1329
  await Promise.all(sendPromises);
833
- logger2.debug({ messageId: message.id, peerCount: this.peers.size }, "Broadcast message sent");
1330
+ logger4.debug({ messageId: message.id, peerCount: this.peers.size }, "Broadcast message sent");
834
1331
  }
835
1332
  // ============================================================================
836
1333
  // Event Registration
@@ -920,7 +1417,7 @@ var Bridge = class {
920
1417
  this.pendingTasks.delete(task.id);
921
1418
  reject(error);
922
1419
  });
923
- logger2.debug({ taskId: task.id, peerId, timeout }, "Task delegated");
1420
+ logger4.debug({ taskId: task.id, peerId, timeout }, "Task delegated");
924
1421
  });
925
1422
  }
926
1423
  // ============================================================================
@@ -936,10 +1433,10 @@ var Bridge = class {
936
1433
  const message = createContextSyncMessage(this.config.instanceName, contextToSync);
937
1434
  if (peerId) {
938
1435
  await this.sendToPeer(peerId, message);
939
- logger2.debug({ peerId, messageId: message.id }, "Context synced to peer");
1436
+ logger4.debug({ peerId, messageId: message.id }, "Context synced to peer");
940
1437
  } else {
941
1438
  await this.broadcast(message);
942
- logger2.debug({ peerCount: this.peers.size, messageId: message.id }, "Context synced to all peers");
1439
+ logger4.debug({ peerCount: this.peers.size, messageId: message.id }, "Context synced to all peers");
943
1440
  }
944
1441
  }
945
1442
  /**
@@ -982,7 +1479,7 @@ var Bridge = class {
982
1479
  this.pendingContextRequests.delete(message.id);
983
1480
  reject(error);
984
1481
  });
985
- logger2.debug({ requestId: message.id, peerId, query }, "Context requested");
1482
+ logger4.debug({ requestId: message.id, peerId, query }, "Context requested");
986
1483
  });
987
1484
  }
988
1485
  /**
@@ -998,10 +1495,10 @@ var Bridge = class {
998
1495
  const context = contextProvider ? await contextProvider() : void 0;
999
1496
  await this.syncContext(context);
1000
1497
  } catch (error) {
1001
- logger2.error({ error: error.message }, "Auto-sync error");
1498
+ logger4.error({ error: error.message }, "Auto-sync error");
1002
1499
  }
1003
1500
  }, interval);
1004
- logger2.info({ interval }, "Auto-sync started");
1501
+ logger4.info({ interval }, "Auto-sync started");
1005
1502
  }
1006
1503
  /**
1007
1504
  * Stop automatic context synchronization
@@ -1010,7 +1507,7 @@ var Bridge = class {
1010
1507
  if (this.autoSyncIntervalId) {
1011
1508
  clearInterval(this.autoSyncIntervalId);
1012
1509
  this.autoSyncIntervalId = null;
1013
- logger2.info("Auto-sync stopped");
1510
+ logger4.info("Auto-sync stopped");
1014
1511
  }
1015
1512
  }
1016
1513
  // ============================================================================
@@ -1018,30 +1515,97 @@ var Bridge = class {
1018
1515
  // ============================================================================
1019
1516
  /**
1020
1517
  * Start the WebSocket server
1518
+ * If TLS is configured, starts an HTTPS server with WebSocket upgrade
1519
+ * If auth is configured, validates connections before accepting
1021
1520
  */
1022
1521
  async startServer() {
1023
1522
  const { listen } = this.config;
1024
1523
  if (!listen) {
1025
1524
  throw new Error("Listen configuration is required");
1026
1525
  }
1526
+ const host = listen.host ?? "0.0.0.0";
1527
+ const port = listen.port;
1528
+ const useTls = isTLSEnabled(listen.tls);
1529
+ if (listen.auth && listen.auth.type !== "none") {
1530
+ this.authenticator = new Authenticator(listen.auth);
1531
+ logger4.info({ authType: listen.auth.type }, "Authentication enabled");
1532
+ }
1027
1533
  return new Promise((resolve, reject) => {
1028
- const host = listen.host ?? "0.0.0.0";
1029
- const port = listen.port;
1030
- logger2.debug({ host, port }, "Starting WebSocket server");
1031
- this.server = new WebSocketServer({ host, port });
1032
- this.server.on("listening", () => {
1033
- logger2.info({ host, port }, "WebSocket server listening");
1034
- resolve();
1035
- });
1036
- this.server.on("error", (error) => {
1037
- logger2.error({ error: error.message }, "WebSocket server error");
1534
+ logger4.debug({ host, port, tls: useTls, auth: !!this.authenticator }, "Starting WebSocket server");
1535
+ try {
1536
+ if (useTls && listen.tls) {
1537
+ const tlsOptions = loadCertificatesSync(listen.tls);
1538
+ logger4.info({ host, port }, "Starting secure WebSocket server (wss://)");
1539
+ this.httpsServer = https2.createServer({
1540
+ cert: tlsOptions.cert,
1541
+ key: tlsOptions.key,
1542
+ ca: tlsOptions.ca,
1543
+ passphrase: tlsOptions.passphrase
1544
+ });
1545
+ const wsOptions = {
1546
+ server: this.httpsServer
1547
+ };
1548
+ if (this.authenticator) {
1549
+ wsOptions.verifyClient = (info, callback) => {
1550
+ this.verifyClient(info, callback);
1551
+ };
1552
+ }
1553
+ this.server = new WebSocketServer(wsOptions);
1554
+ this.httpsServer.listen(port, host, () => {
1555
+ logger4.info({ host, port, protocol: "wss" }, "Secure WebSocket server listening");
1556
+ resolve();
1557
+ });
1558
+ this.httpsServer.on("error", (error) => {
1559
+ logger4.error({ error: error.message }, "HTTPS server error");
1560
+ reject(error);
1561
+ });
1562
+ } else {
1563
+ const wsOptions = {
1564
+ host,
1565
+ port
1566
+ };
1567
+ if (this.authenticator) {
1568
+ wsOptions.verifyClient = (info, callback) => {
1569
+ this.verifyClient(info, callback);
1570
+ };
1571
+ }
1572
+ this.server = new WebSocketServer(wsOptions);
1573
+ this.server.on("listening", () => {
1574
+ logger4.info({ host, port, protocol: "ws" }, "WebSocket server listening");
1575
+ resolve();
1576
+ });
1577
+ this.server.on("error", (error) => {
1578
+ logger4.error({ error: error.message }, "WebSocket server error");
1579
+ reject(error);
1580
+ });
1581
+ }
1582
+ this.server.on("connection", (ws, request) => {
1583
+ this.handleNewConnection(ws, request);
1584
+ });
1585
+ } catch (error) {
1586
+ logger4.error({ error: error.message }, "Failed to start server");
1038
1587
  reject(error);
1039
- });
1040
- this.server.on("connection", (ws, request) => {
1041
- this.handleNewConnection(ws, request);
1042
- });
1588
+ }
1043
1589
  });
1044
1590
  }
1591
+ /**
1592
+ * Verify client connection for authentication
1593
+ * Used as WebSocketServer verifyClient callback
1594
+ */
1595
+ verifyClient(info, callback) {
1596
+ if (!this.authenticator) {
1597
+ callback(true);
1598
+ return;
1599
+ }
1600
+ const result = this.authenticator.authenticate(info.req);
1601
+ if (result.success) {
1602
+ logger4.info({ clientIp: result.clientIp, method: result.method }, "Client authenticated");
1603
+ callback(true);
1604
+ } else {
1605
+ logger4.warn({ clientIp: result.clientIp, error: result.error }, "Client authentication failed");
1606
+ callback(false, 4001, result.error || "Authentication failed");
1607
+ }
1608
+ }
1045
1609
  /**
1046
1610
  * Handle a new incoming connection
1047
1611
  */
@@ -1058,7 +1622,7 @@ var Bridge = class {
1058
1622
  info: peerInfo,
1059
1623
  ws
1060
1624
  });
1061
- logger2.info({ peerId, url: request.url }, "New peer connected");
1625
+ logger4.info({ peerId, url: request.url }, "New peer connected");
1062
1626
  ws.on("message", (data) => {
1063
1627
  const messageString = data.toString();
1064
1628
  const result = safeDeserializeMessage(messageString);
@@ -1066,16 +1630,16 @@ var Bridge = class {
1066
1630
  peerInfo.lastActivity = Date.now();
1067
1631
  this.handleMessage(result.data, ws, peerId);
1068
1632
  } else {
1069
- logger2.warn({ peerId, error: result.error.message }, "Invalid message received");
1633
+ logger4.warn({ peerId, error: result.error.message }, "Invalid message received");
1070
1634
  }
1071
1635
  });
1072
1636
  ws.on("close", (code, reason) => {
1073
- logger2.info({ peerId, code, reason: reason.toString() }, "Peer disconnected");
1637
+ logger4.info({ peerId, code, reason: reason.toString() }, "Peer disconnected");
1074
1638
  this.peers.delete(peerId);
1075
1639
  this.notifyPeerDisconnected(peerInfo);
1076
1640
  });
1077
1641
  ws.on("error", (error) => {
1078
- logger2.error({ peerId, error: error.message }, "Peer connection error");
1642
+ logger4.error({ peerId, error: error.message }, "Peer connection error");
1079
1643
  });
1080
1644
  this.notifyPeerConnected(peerInfo);
1081
1645
  }
@@ -1094,7 +1658,8 @@ var Bridge = class {
1094
1658
  if (!url) {
1095
1659
  const host = connect.hostGateway ? "host.docker.internal" : "localhost";
1096
1660
  const port = connect.port ?? 8765;
1097
- url = `ws://${host}:${port}`;
1661
+ const protocol = isTLSEnabled(connect.tls) || connect.tls?.ca ? "wss" : "ws";
1662
+ url = `${protocol}://${host}:${port}`;
1098
1663
  }
1099
1664
  this.clientTransport = new WebSocketTransport();
1100
1665
  this.clientTransport.onMessage((message) => {
@@ -1108,7 +1673,9 @@ var Bridge = class {
1108
1673
  url,
1109
1674
  reconnect: true,
1110
1675
  reconnectInterval: 1e3,
1111
- maxReconnectAttempts: 10
1676
+ maxReconnectAttempts: 10,
1677
+ tls: connect.tls,
1678
+ auth: connect.auth
1112
1679
  });
1113
1680
  const peerId = uuidv42();
1114
1681
  const peerInfo = {
@@ -1123,9 +1690,9 @@ var Bridge = class {
1123
1690
  });
1124
1691
  this.clientTransport._peerId = peerId;
1125
1692
  this.notifyPeerConnected(peerInfo);
1126
- logger2.info({ peerId, url }, "Connected to remote bridge");
1693
+ logger4.info({ peerId, url }, "Connected to remote bridge");
1127
1694
  } catch (error) {
1128
- logger2.error({ error: error.message }, "Failed to connect to remote bridge");
1695
+ logger4.error({ error: error.message }, "Failed to connect to remote bridge");
1129
1696
  this.clientTransport = null;
1130
1697
  throw error;
1131
1698
  }
@@ -1141,7 +1708,7 @@ var Bridge = class {
1141
1708
  if (peer) {
1142
1709
  this.peers.delete(peerId);
1143
1710
  this.notifyPeerDisconnected(peer.info);
1144
- logger2.info({ peerId }, "Client transport disconnected");
1711
+ logger4.info({ peerId }, "Client transport disconnected");
1145
1712
  }
1146
1713
  }
1147
1714
  }
@@ -1165,14 +1732,14 @@ var Bridge = class {
1165
1732
  }
1166
1733
  }
1167
1734
  if (!peerId) {
1168
- logger2.warn({ messageId: message.id }, "Received message from unknown peer");
1735
+ logger4.warn({ messageId: message.id }, "Received message from unknown peer");
1169
1736
  return;
1170
1737
  }
1171
1738
  const peer = this.peers.get(peerId);
1172
1739
  if (peer) {
1173
1740
  peer.info.lastActivity = Date.now();
1174
1741
  }
1175
- logger2.debug({ peerId, messageId: message.id, type: message.type }, "Received message");
1742
+ logger4.debug({ peerId, messageId: message.id, type: message.type }, "Received message");
1176
1743
  if (message.type === "task_delegate" && message.task) {
1177
1744
  this.handleTaskDelegate(message, peerId);
1178
1745
  return;
@@ -1200,22 +1767,22 @@ var Bridge = class {
1200
1767
  */
1201
1768
  async handleTaskDelegate(message, peerId) {
1202
1769
  const task = message.task;
1203
- logger2.debug({ taskId: task.id, peerId }, "Received task delegation");
1770
+ logger4.debug({ taskId: task.id, peerId }, "Received task delegation");
1204
1771
  if (!this.taskReceivedHandler) {
1205
1772
  const otherPeers = Array.from(this.peers.keys()).filter((id) => id !== peerId);
1206
1773
  if (otherPeers.length > 0) {
1207
1774
  const targetPeerId = otherPeers[0];
1208
- logger2.info({ taskId: task.id, targetPeerId }, "Forwarding task to another peer");
1775
+ logger4.info({ taskId: task.id, targetPeerId }, "Forwarding task to another peer");
1209
1776
  try {
1210
1777
  await this.sendToPeer(targetPeerId, message);
1211
1778
  const forwardKey = `forward:${task.id}`;
1212
1779
  this[forwardKey] = peerId;
1213
1780
  return;
1214
1781
  } catch (err) {
1215
- logger2.error({ error: err.message, taskId: task.id }, "Failed to forward task");
1782
+ logger4.error({ error: err.message, taskId: task.id }, "Failed to forward task");
1216
1783
  }
1217
1784
  }
1218
- logger2.warn({ taskId: task.id }, "No task handler registered and no peers to forward to");
1785
+ logger4.warn({ taskId: task.id }, "No task handler registered and no peers to forward to");
1219
1786
  const response = createTaskResponseMessage(
1220
1787
  this.config.instanceName,
1221
1788
  task.id,
@@ -1226,7 +1793,7 @@ var Bridge = class {
1226
1793
  }
1227
1794
  );
1228
1795
  await this.sendToPeer(peerId, response).catch((err) => {
1229
- logger2.error({ error: err.message, taskId: task.id }, "Failed to send error response");
1796
+ logger4.error({ error: err.message, taskId: task.id }, "Failed to send error response");
1230
1797
  });
1231
1798
  return;
1232
1799
  }
@@ -1238,7 +1805,7 @@ var Bridge = class {
1238
1805
  result
1239
1806
  );
1240
1807
  await this.sendToPeer(peerId, response);
1241
- logger2.debug({ taskId: task.id, success: result.success }, "Task response sent");
1808
+ logger4.debug({ taskId: task.id, success: result.success }, "Task response sent");
1242
1809
  } catch (error) {
1243
1810
  const response = createTaskResponseMessage(
1244
1811
  this.config.instanceName,
@@ -1250,9 +1817,9 @@ var Bridge = class {
1250
1817
  }
1251
1818
  );
1252
1819
  await this.sendToPeer(peerId, response).catch((err) => {
1253
- logger2.error({ error: err.message, taskId: task.id }, "Failed to send error response");
1820
+ logger4.error({ error: err.message, taskId: task.id }, "Failed to send error response");
1254
1821
  });
1255
- logger2.error({ taskId: task.id, error: error.message }, "Task handler error");
1822
+ logger4.error({ taskId: task.id, error: error.message }, "Task handler error");
1256
1823
  }
1257
1824
  }
1258
1825
  /**
@@ -1264,15 +1831,15 @@ var Bridge = class {
1264
1831
  const originalSender = this[forwardKey];
1265
1832
  if (originalSender) {
1266
1833
  delete this[forwardKey];
1267
- logger2.info({ taskId, originalSender }, "Forwarding task response to original sender");
1834
+ logger4.info({ taskId, originalSender }, "Forwarding task response to original sender");
1268
1835
  await this.sendToPeer(originalSender, message).catch((err) => {
1269
- logger2.error({ error: err.message, taskId }, "Failed to forward response");
1836
+ logger4.error({ error: err.message, taskId }, "Failed to forward response");
1270
1837
  });
1271
1838
  return;
1272
1839
  }
1273
1840
  const pending = this.pendingTasks.get(taskId);
1274
1841
  if (!pending) {
1275
- logger2.warn({ taskId }, "Received response for unknown task");
1842
+ logger4.warn({ taskId }, "Received response for unknown task");
1276
1843
  return;
1277
1844
  }
1278
1845
  clearTimeout(pending.timeoutId);
@@ -1285,7 +1852,7 @@ var Bridge = class {
1285
1852
  followUp: message.result.followUp,
1286
1853
  error: message.result.error
1287
1854
  };
1288
- logger2.debug({ taskId, success: result.success }, "Task result received");
1855
+ logger4.debug({ taskId, success: result.success }, "Task result received");
1289
1856
  pending.resolve(result);
1290
1857
  }
1291
1858
  /**
@@ -1293,7 +1860,7 @@ var Bridge = class {
1293
1860
  */
1294
1861
  handleContextSync(message, peerId) {
1295
1862
  const context = message.context;
1296
- logger2.debug({ peerId, messageId: message.id }, "Received context sync");
1863
+ logger4.debug({ peerId, messageId: message.id }, "Received context sync");
1297
1864
  this.notifyContextReceived(context, peerId);
1298
1865
  }
1299
1866
  /**
@@ -1301,22 +1868,22 @@ var Bridge = class {
1301
1868
  */
1302
1869
  async handleContextRequest(message, peerId) {
1303
1870
  const query = message.context.summary;
1304
- logger2.debug({ peerId, messageId: message.id, query }, "Received context request");
1871
+ logger4.debug({ peerId, messageId: message.id, query }, "Received context request");
1305
1872
  if (!this.contextRequestedHandler) {
1306
1873
  const otherPeers = Array.from(this.peers.keys()).filter((id) => id !== peerId);
1307
1874
  if (otherPeers.length > 0) {
1308
1875
  const targetPeerId = otherPeers[0];
1309
- logger2.info({ messageId: message.id, targetPeerId }, "Forwarding context request to another peer");
1876
+ logger4.info({ messageId: message.id, targetPeerId }, "Forwarding context request to another peer");
1310
1877
  try {
1311
1878
  await this.sendToPeer(targetPeerId, message);
1312
1879
  const forwardKey = `ctxfwd:${message.id}`;
1313
1880
  this[forwardKey] = peerId;
1314
1881
  return;
1315
1882
  } catch (err) {
1316
- logger2.error({ error: err.message, messageId: message.id }, "Failed to forward context request");
1883
+ logger4.error({ error: err.message, messageId: message.id }, "Failed to forward context request");
1317
1884
  }
1318
1885
  }
1319
- logger2.warn({ messageId: message.id }, "No context request handler registered and no peers to forward to");
1886
+ logger4.warn({ messageId: message.id }, "No context request handler registered and no peers to forward to");
1320
1887
  const response = createContextSyncMessage(this.config.instanceName, { files: [] });
1321
1888
  const responseMessage = {
1322
1889
  ...response,
@@ -1327,7 +1894,7 @@ var Bridge = class {
1327
1894
  }
1328
1895
  };
1329
1896
  await this.sendToPeer(peerId, responseMessage).catch((err) => {
1330
- logger2.error({ error: err.message, messageId: message.id }, "Failed to send empty context response");
1897
+ logger4.error({ error: err.message, messageId: message.id }, "Failed to send empty context response");
1331
1898
  });
1332
1899
  return;
1333
1900
  }
@@ -1343,7 +1910,7 @@ var Bridge = class {
1343
1910
  }
1344
1911
  };
1345
1912
  await this.sendToPeer(peerId, responseMessage);
1346
- logger2.debug({ messageId: message.id, fileCount: files.length }, "Context response sent");
1913
+ logger4.debug({ messageId: message.id, fileCount: files.length }, "Context response sent");
1347
1914
  } catch (error) {
1348
1915
  const response = createContextSyncMessage(this.config.instanceName, {
1349
1916
  files: [],
@@ -1358,9 +1925,9 @@ var Bridge = class {
1358
1925
  }
1359
1926
  };
1360
1927
  await this.sendToPeer(peerId, responseMessage).catch((err) => {
1361
- logger2.error({ error: err.message, messageId: message.id }, "Failed to send error context response");
1928
+ logger4.error({ error: err.message, messageId: message.id }, "Failed to send error context response");
1362
1929
  });
1363
- logger2.error({ messageId: message.id, error: error.message }, "Context request handler error");
1930
+ logger4.error({ messageId: message.id, error: error.message }, "Context request handler error");
1364
1931
  }
1365
1932
  }
1366
1933
  /**
@@ -1369,22 +1936,22 @@ var Bridge = class {
1369
1936
  async handleContextResponse(message) {
1370
1937
  const requestId = message.context?.variables?.requestId;
1371
1938
  if (!requestId) {
1372
- logger2.warn({ messageId: message.id }, "Context response without requestId");
1939
+ logger4.warn({ messageId: message.id }, "Context response without requestId");
1373
1940
  return;
1374
1941
  }
1375
1942
  const forwardKey = `ctxfwd:${requestId}`;
1376
1943
  const originalSender = this[forwardKey];
1377
1944
  if (originalSender) {
1378
1945
  delete this[forwardKey];
1379
- logger2.info({ requestId, originalSender }, "Forwarding context response to original sender");
1946
+ logger4.info({ requestId, originalSender }, "Forwarding context response to original sender");
1380
1947
  await this.sendToPeer(originalSender, message).catch((err) => {
1381
- logger2.error({ error: err.message, requestId }, "Failed to forward context response");
1948
+ logger4.error({ error: err.message, requestId }, "Failed to forward context response");
1382
1949
  });
1383
1950
  return;
1384
1951
  }
1385
1952
  const pending = this.pendingContextRequests.get(requestId);
1386
1953
  if (!pending) {
1387
- logger2.warn({ requestId }, "Received response for unknown context request");
1954
+ logger4.warn({ requestId }, "Received response for unknown context request");
1388
1955
  return;
1389
1956
  }
1390
1957
  clearTimeout(pending.timeoutId);
@@ -1395,7 +1962,7 @@ var Bridge = class {
1395
1962
  return;
1396
1963
  }
1397
1964
  const files = message.context?.files ?? [];
1398
- logger2.debug({ requestId, fileCount: files.length }, "Context response received");
1965
+ logger4.debug({ requestId, fileCount: files.length }, "Context response received");
1399
1966
  pending.resolve(files);
1400
1967
  }
1401
1968
  // ============================================================================
@@ -1407,7 +1974,7 @@ var Bridge = class {
1407
1974
  try {
1408
1975
  handler(peer);
1409
1976
  } catch (error) {
1410
- logger2.error({ error: error.message }, "Peer connected handler error");
1977
+ logger4.error({ error: error.message }, "Peer connected handler error");
1411
1978
  }
1412
1979
  }
1413
1980
  }
@@ -1430,7 +1997,7 @@ var Bridge = class {
1430
1997
  try {
1431
1998
  handler(peer);
1432
1999
  } catch (error) {
1433
- logger2.error({ error: error.message }, "Peer disconnected handler error");
2000
+ logger4.error({ error: error.message }, "Peer disconnected handler error");
1434
2001
  }
1435
2002
  }
1436
2003
  this.writeStatusFile();
@@ -1440,7 +2007,7 @@ var Bridge = class {
1440
2007
  try {
1441
2008
  handler(message, peerId);
1442
2009
  } catch (error) {
1443
- logger2.error({ error: error.message }, "Message received handler error");
2010
+ logger4.error({ error: error.message }, "Message received handler error");
1444
2011
  }
1445
2012
  }
1446
2013
  }
@@ -1449,7 +2016,7 @@ var Bridge = class {
1449
2016
  try {
1450
2017
  handler(context, peerId);
1451
2018
  } catch (error) {
1452
- logger2.error({ error: error.message }, "Context received handler error");
2019
+ logger4.error({ error: error.message }, "Context received handler error");
1453
2020
  }
1454
2021
  }
1455
2022
  }
@@ -1460,9 +2027,9 @@ var Bridge = class {
1460
2027
  * Clean up all resources
1461
2028
  */
1462
2029
  async cleanup() {
1463
- logger2.debug("Starting cleanup");
2030
+ logger4.debug("Starting cleanup");
1464
2031
  this.stopAutoSync();
1465
- logger2.debug("Auto-sync stopped");
2032
+ logger4.debug("Auto-sync stopped");
1466
2033
  const pendingTaskCount = this.pendingTasks.size;
1467
2034
  for (const [taskId, pending] of this.pendingTasks) {
1468
2035
  clearTimeout(pending.timeoutId);
@@ -1470,7 +2037,7 @@ var Bridge = class {
1470
2037
  }
1471
2038
  this.pendingTasks.clear();
1472
2039
  if (pendingTaskCount > 0) {
1473
- logger2.debug({ count: pendingTaskCount }, "Pending tasks cancelled");
2040
+ logger4.debug({ count: pendingTaskCount }, "Pending tasks cancelled");
1474
2041
  }
1475
2042
  const pendingContextCount = this.pendingContextRequests.size;
1476
2043
  for (const [requestId, pending] of this.pendingContextRequests) {
@@ -1479,20 +2046,20 @@ var Bridge = class {
1479
2046
  }
1480
2047
  this.pendingContextRequests.clear();
1481
2048
  if (pendingContextCount > 0) {
1482
- logger2.debug({ count: pendingContextCount }, "Pending context requests cancelled");
2049
+ logger4.debug({ count: pendingContextCount }, "Pending context requests cancelled");
1483
2050
  }
1484
2051
  if (this.clientTransport) {
1485
- logger2.debug("Disconnecting client transport");
2052
+ logger4.debug("Disconnecting client transport");
1486
2053
  try {
1487
2054
  await this.clientTransport.disconnect();
1488
- logger2.debug("Client transport disconnected");
2055
+ logger4.debug("Client transport disconnected");
1489
2056
  } catch {
1490
2057
  }
1491
2058
  this.clientTransport = null;
1492
2059
  }
1493
2060
  const peerCount = this.peers.size;
1494
2061
  if (peerCount > 0) {
1495
- logger2.debug({ count: peerCount }, "Closing peer connections");
2062
+ logger4.debug({ count: peerCount }, "Closing peer connections");
1496
2063
  }
1497
2064
  for (const [peerId, peer] of this.peers) {
1498
2065
  if (peer.ws) {
@@ -1507,21 +2074,31 @@ var Bridge = class {
1507
2074
  } catch {
1508
2075
  }
1509
2076
  }
1510
- logger2.debug({ peerId }, "Peer disconnected");
2077
+ logger4.debug({ peerId }, "Peer disconnected");
1511
2078
  }
1512
2079
  this.peers.clear();
1513
2080
  if (this.server) {
1514
- logger2.debug("Closing WebSocket server");
2081
+ logger4.debug("Closing WebSocket server");
1515
2082
  await new Promise((resolve) => {
1516
2083
  this.server.close(() => {
1517
2084
  resolve();
1518
2085
  });
1519
2086
  });
1520
2087
  this.server = null;
1521
- logger2.debug("WebSocket server closed");
2088
+ logger4.debug("WebSocket server closed");
2089
+ }
2090
+ if (this.httpsServer) {
2091
+ logger4.debug("Closing HTTPS server");
2092
+ await new Promise((resolve) => {
2093
+ this.httpsServer.close(() => {
2094
+ resolve();
2095
+ });
2096
+ });
2097
+ this.httpsServer = null;
2098
+ logger4.debug("HTTPS server closed");
1522
2099
  }
1523
2100
  this.removeStatusFile();
1524
- logger2.debug("Cleanup complete");
2101
+ logger4.debug("Cleanup complete");
1525
2102
  }
1526
2103
  // ============================================================================
1527
2104
  // Status File Management
@@ -1538,8 +2115,8 @@ var Bridge = class {
1538
2115
  */
1539
2116
  ensureBridgeDir() {
1540
2117
  const bridgeDir = path.join(os.homedir(), ".claude-bridge");
1541
- if (!fs.existsSync(bridgeDir)) {
1542
- fs.mkdirSync(bridgeDir, { recursive: true });
2118
+ if (!fs2.existsSync(bridgeDir)) {
2119
+ fs2.mkdirSync(bridgeDir, { recursive: true });
1543
2120
  }
1544
2121
  }
1545
2122
  /**
@@ -1560,10 +2137,10 @@ var Bridge = class {
1560
2137
  lastActivity: new Date(p.lastActivity).toISOString()
1561
2138
  }))
1562
2139
  };
1563
- fs.writeFileSync(statusFile, JSON.stringify(status, null, 2), "utf-8");
1564
- logger2.debug({ statusFile }, "Status file updated");
2140
+ fs2.writeFileSync(statusFile, JSON.stringify(status, null, 2), "utf-8");
2141
+ logger4.debug({ statusFile }, "Status file updated");
1565
2142
  } catch (error) {
1566
- logger2.error({ error: error.message }, "Failed to write status file");
2143
+ logger4.error({ error: error.message }, "Failed to write status file");
1567
2144
  }
1568
2145
  }
1569
2146
  /**
@@ -1572,12 +2149,12 @@ var Bridge = class {
1572
2149
  removeStatusFile() {
1573
2150
  try {
1574
2151
  const statusFile = this.getStatusFilePath();
1575
- if (fs.existsSync(statusFile)) {
1576
- fs.unlinkSync(statusFile);
1577
- logger2.debug({ statusFile }, "Status file removed");
2152
+ if (fs2.existsSync(statusFile)) {
2153
+ fs2.unlinkSync(statusFile);
2154
+ logger4.debug({ statusFile }, "Status file removed");
1578
2155
  }
1579
2156
  } catch (error) {
1580
- logger2.error({ error: error.message }, "Failed to remove status file");
2157
+ logger4.error({ error: error.message }, "Failed to remove status file");
1581
2158
  }
1582
2159
  }
1583
2160
  // ============================================================================
@@ -1610,7 +2187,7 @@ var Bridge = class {
1610
2187
  };
1611
2188
 
1612
2189
  // src/utils/config.ts
1613
- import * as fs2 from "fs";
2190
+ import * as fs3 from "fs";
1614
2191
  import * as path2 from "path";
1615
2192
  import * as os2 from "os";
1616
2193
  import { parse as parseYaml } from "yaml";
@@ -1656,10 +2233,10 @@ function mergeConfig(partial) {
1656
2233
  }
1657
2234
  function readConfigFile(filePath) {
1658
2235
  try {
1659
- if (!fs2.existsSync(filePath)) {
2236
+ if (!fs3.existsSync(filePath)) {
1660
2237
  return null;
1661
2238
  }
1662
- const content = fs2.readFileSync(filePath, "utf-8");
2239
+ const content = fs3.readFileSync(filePath, "utf-8");
1663
2240
  const parsed = parseYaml(content);
1664
2241
  return parsed;
1665
2242
  } catch {
@@ -1715,7 +2292,7 @@ function loadConfigSync(configPath) {
1715
2292
 
1716
2293
  // src/mcp/tools.ts
1717
2294
  import { z as z2 } from "zod";
1718
- var logger3 = createLogger("mcp:tools");
2295
+ var logger5 = createLogger("mcp:tools");
1719
2296
  var ReadFileInputSchema = z2.object({
1720
2297
  path: z2.string().describe("Path to the file to read")
1721
2298
  });
@@ -1798,7 +2375,7 @@ function createToolHandlers(bridge) {
1798
2375
  }
1799
2376
  handlers["bridge_read_file"] = async (args) => {
1800
2377
  const input = ReadFileInputSchema.parse(args);
1801
- logger3.debug({ path: input.path }, "Reading file");
2378
+ logger5.debug({ path: input.path }, "Reading file");
1802
2379
  try {
1803
2380
  const result = await delegateFileTask(
1804
2381
  "read_file",
@@ -1810,13 +2387,13 @@ function createToolHandlers(bridge) {
1810
2387
  }
1811
2388
  return successResponse(result.data.content);
1812
2389
  } catch (err) {
1813
- logger3.error({ error: err.message, path: input.path }, "Failed to read file");
2390
+ logger5.error({ error: err.message, path: input.path }, "Failed to read file");
1814
2391
  return errorResponse(err.message);
1815
2392
  }
1816
2393
  };
1817
2394
  handlers["bridge_write_file"] = async (args) => {
1818
2395
  const input = WriteFileInputSchema.parse(args);
1819
- logger3.debug({ path: input.path, contentLength: input.content.length }, "Writing file");
2396
+ logger5.debug({ path: input.path, contentLength: input.content.length }, "Writing file");
1820
2397
  try {
1821
2398
  const result = await delegateFileTask(
1822
2399
  "write_file",
@@ -1828,13 +2405,13 @@ function createToolHandlers(bridge) {
1828
2405
  }
1829
2406
  return successResponse(`File written successfully: ${input.path} (${result.data.bytesWritten} bytes)`);
1830
2407
  } catch (err) {
1831
- logger3.error({ error: err.message, path: input.path }, "Failed to write file");
2408
+ logger5.error({ error: err.message, path: input.path }, "Failed to write file");
1832
2409
  return errorResponse(err.message);
1833
2410
  }
1834
2411
  };
1835
2412
  handlers["bridge_delete_file"] = async (args) => {
1836
2413
  const input = DeleteFileInputSchema.parse(args);
1837
- logger3.debug({ path: input.path }, "Deleting file");
2414
+ logger5.debug({ path: input.path }, "Deleting file");
1838
2415
  try {
1839
2416
  const result = await delegateFileTask(
1840
2417
  "delete_file",
@@ -1846,13 +2423,13 @@ function createToolHandlers(bridge) {
1846
2423
  }
1847
2424
  return successResponse(`File deleted successfully: ${input.path}`);
1848
2425
  } catch (err) {
1849
- logger3.error({ error: err.message, path: input.path }, "Failed to delete file");
2426
+ logger5.error({ error: err.message, path: input.path }, "Failed to delete file");
1850
2427
  return errorResponse(err.message);
1851
2428
  }
1852
2429
  };
1853
2430
  handlers["bridge_list_directory"] = async (args) => {
1854
2431
  const input = ListDirectoryInputSchema.parse(args);
1855
- logger3.debug({ path: input.path }, "Listing directory");
2432
+ logger5.debug({ path: input.path }, "Listing directory");
1856
2433
  try {
1857
2434
  const result = await delegateFileTask(
1858
2435
  "list_directory",
@@ -1870,13 +2447,13 @@ function createToolHandlers(bridge) {
1870
2447
  return successResponse(`Contents of ${input.path}:
1871
2448
  ${listing}`);
1872
2449
  } catch (err) {
1873
- logger3.error({ error: err.message, path: input.path }, "Failed to list directory");
2450
+ logger5.error({ error: err.message, path: input.path }, "Failed to list directory");
1874
2451
  return errorResponse(err.message);
1875
2452
  }
1876
2453
  };
1877
2454
  handlers["bridge_delegate_task"] = async (args) => {
1878
2455
  const input = DelegateTaskInputSchema.parse(args);
1879
- logger3.debug({ description: input.description, scope: input.scope }, "Delegating task");
2456
+ logger5.debug({ description: input.description, scope: input.scope }, "Delegating task");
1880
2457
  try {
1881
2458
  const taskId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1882
2459
  const result = await bridge.delegateTask({
@@ -1890,13 +2467,13 @@ ${listing}`);
1890
2467
  }
1891
2468
  return successResponse(JSON.stringify(result.data, null, 2));
1892
2469
  } catch (err) {
1893
- logger3.error({ error: err.message }, "Failed to delegate task");
2470
+ logger5.error({ error: err.message }, "Failed to delegate task");
1894
2471
  return errorResponse(err.message);
1895
2472
  }
1896
2473
  };
1897
2474
  handlers["bridge_request_context"] = async (args) => {
1898
2475
  const input = RequestContextInputSchema.parse(args);
1899
- logger3.debug({ query: input.query }, "Requesting context");
2476
+ logger5.debug({ query: input.query }, "Requesting context");
1900
2477
  try {
1901
2478
  const files = await bridge.requestContext(input.query);
1902
2479
  if (files.length === 0) {
@@ -1912,12 +2489,12 @@ ${content}`;
1912
2489
 
1913
2490
  ${fileResults}`);
1914
2491
  } catch (err) {
1915
- logger3.error({ error: err.message }, "Failed to request context");
2492
+ logger5.error({ error: err.message }, "Failed to request context");
1916
2493
  return errorResponse(err.message);
1917
2494
  }
1918
2495
  };
1919
2496
  handlers["bridge_status"] = async () => {
1920
- logger3.debug("Getting bridge status");
2497
+ logger5.debug("Getting bridge status");
1921
2498
  const peers = bridge.getPeers();
1922
2499
  const peerCount = bridge.getPeerCount();
1923
2500
  const isStarted = bridge.isStarted();
@@ -1992,7 +2569,7 @@ import {
1992
2569
  CallToolRequestSchema,
1993
2570
  ListToolsRequestSchema
1994
2571
  } from "@modelcontextprotocol/sdk/types.js";
1995
- var logger4 = createLogger("mcp:server");
2572
+ var logger6 = createLogger("mcp:server");
1996
2573
  var BridgeMcpServer = class {
1997
2574
  server;
1998
2575
  bridge;
@@ -2015,7 +2592,9 @@ var BridgeMcpServer = class {
2015
2592
  mode: "client",
2016
2593
  instanceName: config.instanceName ?? `mcp-server-${process.pid}`,
2017
2594
  connect: {
2018
- url: config.bridgeUrl
2595
+ url: config.bridgeUrl,
2596
+ tls: config.tls,
2597
+ auth: config.auth
2019
2598
  },
2020
2599
  taskTimeout: config.taskTimeout ?? 6e4
2021
2600
  };
@@ -2027,7 +2606,7 @@ var BridgeMcpServer = class {
2027
2606
  */
2028
2607
  registerHandlers() {
2029
2608
  this.server.setRequestHandler(ListToolsRequestSchema, async () => {
2030
- logger4.debug("Listing tools");
2609
+ logger6.debug("Listing tools");
2031
2610
  return {
2032
2611
  tools: TOOL_DEFINITIONS.map((tool) => ({
2033
2612
  name: tool.name,
@@ -2038,13 +2617,13 @@ var BridgeMcpServer = class {
2038
2617
  });
2039
2618
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
2040
2619
  const { name, arguments: args } = request.params;
2041
- logger4.debug({ tool: name }, "Tool call received");
2620
+ logger6.debug({ tool: name }, "Tool call received");
2042
2621
  if (!this.toolHandlers) {
2043
2622
  this.toolHandlers = createToolHandlers(this.bridge);
2044
2623
  }
2045
2624
  const handler = this.toolHandlers[name];
2046
2625
  if (!handler) {
2047
- logger4.warn({ tool: name }, "Unknown tool requested");
2626
+ logger6.warn({ tool: name }, "Unknown tool requested");
2048
2627
  return {
2049
2628
  content: [{ type: "text", text: `Unknown tool: ${name}` }],
2050
2629
  isError: true
@@ -2052,13 +2631,13 @@ var BridgeMcpServer = class {
2052
2631
  }
2053
2632
  try {
2054
2633
  const result = await handler(args ?? {});
2055
- logger4.debug({ tool: name, isError: result.isError }, "Tool call completed");
2634
+ logger6.debug({ tool: name, isError: result.isError }, "Tool call completed");
2056
2635
  return {
2057
2636
  content: result.content,
2058
2637
  isError: result.isError
2059
2638
  };
2060
2639
  } catch (err) {
2061
- logger4.error({ tool: name, error: err.message }, "Tool call failed");
2640
+ logger6.error({ tool: name, error: err.message }, "Tool call failed");
2062
2641
  return {
2063
2642
  content: [{ type: "text", text: `Error: ${err.message}` }],
2064
2643
  isError: true
@@ -2080,7 +2659,7 @@ var BridgeMcpServer = class {
2080
2659
  const transport = new StdioServerTransport();
2081
2660
  await this.server.connect(transport);
2082
2661
  console.error("[MCP] MCP server started and listening on stdio");
2083
- logger4.info("MCP server started");
2662
+ logger6.info("MCP server started");
2084
2663
  } catch (err) {
2085
2664
  console.error(`[MCP] Failed to start: ${err.message}`);
2086
2665
  throw err;
@@ -2095,7 +2674,7 @@ var BridgeMcpServer = class {
2095
2674
  await this.bridge.stop();
2096
2675
  await this.server.close();
2097
2676
  console.error("[MCP] MCP server stopped");
2098
- logger4.info("MCP server stopped");
2677
+ logger6.info("MCP server stopped");
2099
2678
  } catch (err) {
2100
2679
  console.error(`[MCP] Error during shutdown: ${err.message}`);
2101
2680
  }
@@ -2131,7 +2710,19 @@ export {
2131
2710
  deserializeMessage,
2132
2711
  safeDeserializeMessage,
2133
2712
  ConnectionState,
2713
+ loadCertificates,
2714
+ loadCertificatesSync,
2715
+ validateTLSConfig,
2716
+ isTLSEnabled,
2717
+ createSecureContextOptions,
2134
2718
  WebSocketTransport,
2719
+ validateIp,
2720
+ validateToken,
2721
+ validatePassword,
2722
+ extractCredentials,
2723
+ Authenticator,
2724
+ createAuthConfigFromOptions,
2725
+ validateAuthConfig,
2135
2726
  createContextSyncMessage,
2136
2727
  createTaskDelegateMessage,
2137
2728
  createTaskResponseMessage,
@@ -2147,4 +2738,4 @@ export {
2147
2738
  BridgeMcpServer,
2148
2739
  startMcpServer
2149
2740
  };
2150
- //# sourceMappingURL=chunk-XOAR3DQB.js.map
2741
+ //# sourceMappingURL=chunk-2O352EPO.js.map