@aiwerk/mcp-bridge 2.8.29 → 2.8.31

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.
@@ -14,6 +14,7 @@ export declare class StandaloneServer {
14
14
  private readonly requestIdState;
15
15
  private directTools;
16
16
  private directConnections;
17
+ private stdoutRef;
17
18
  constructor(config: BridgeConfig, logger: Logger);
18
19
  private isRouterMode;
19
20
  /** Start stdio mode: read JSON-RPC from stdin, write responses to stdout.
@@ -30,6 +31,8 @@ export declare class StandaloneServer {
30
31
  /** Connect to all backend servers and discover their tools (direct mode). */
31
32
  private discoverDirectTools;
32
33
  private _doDiscovery;
34
+ /** Send notifications/tools/list_changed to the client via stdout */
35
+ private sendToolsChanged;
33
36
  /** Extract server name from a tool name like "todoist_call" or "github_call" */
34
37
  private guessServerFromToolName;
35
38
  /** Discover tools from a single server (lazy, per-server) */
@@ -26,6 +26,7 @@ export class StandaloneServer {
26
26
  // Direct mode state
27
27
  directTools = [];
28
28
  directConnections = new Map();
29
+ stdoutRef = null;
29
30
  constructor(config, logger) {
30
31
  this.config = config;
31
32
  this.logger = logger;
@@ -50,6 +51,7 @@ export class StandaloneServer {
50
51
  async startStdio() {
51
52
  const stdin = process.stdin;
52
53
  const stdout = process.stdout;
54
+ this.stdoutRef = stdout;
53
55
  let buffer = Buffer.alloc(0);
54
56
  // LSP framing state
55
57
  let lspContentLength = -1; // -1 means not in LSP mode for current message
@@ -346,16 +348,17 @@ export class StandaloneServer {
346
348
  if (serverName) {
347
349
  this.logger.info(`[mcp-bridge] Lazy discovery for server: ${serverName} (triggered by ${toolName})`);
348
350
  await this.discoverSingleServer(serverName);
351
+ // After discovery, try to find the real tool
349
352
  entry = this.directTools.find(t => t.registeredName === toolName);
350
- // If the original call was a placeholder (_discover), return discovered tools
351
- if (!entry && toolArgs?._discover) {
353
+ if (!entry) {
354
+ // Placeholder was called — return discovered tools list and notify client to refresh
352
355
  const serverTools = this.directTools.filter(t => t.serverName === serverName);
353
356
  const discovered = serverTools.map(t => `${t.registeredName}: ${t.description}`);
354
357
  return {
355
358
  jsonrpc: "2.0",
356
359
  id,
357
360
  result: {
358
- content: [{ type: "text", text: `Discovered ${serverTools.length} tools from ${serverName}:\n${discovered.join("\n")}` }]
361
+ content: [{ type: "text", text: `Server "${serverName}" is now connected with ${serverTools.length} tools. The tool list has been updated — please retry your request. Available tools:\n\n${discovered.join("\n")}` }]
359
362
  }
360
363
  };
361
364
  }
@@ -497,6 +500,14 @@ export class StandaloneServer {
497
500
  }
498
501
  }
499
502
  }
503
+ /** Send notifications/tools/list_changed to the client via stdout */
504
+ sendToolsChanged() {
505
+ if (!this.stdoutRef)
506
+ return;
507
+ const notification = { jsonrpc: "2.0", method: "notifications/tools/list_changed" };
508
+ this.writeResponse(this.stdoutRef, notification);
509
+ this.logger.info("[mcp-bridge] Sent notifications/tools/list_changed");
510
+ }
500
511
  /** Extract server name from a tool name like "todoist_call" or "github_call" */
501
512
  guessServerFromToolName(toolName) {
502
513
  // Try exact match with placeholder pattern: serverName_call
@@ -541,6 +552,8 @@ export class StandaloneServer {
541
552
  // Cache tools to disk
542
553
  this.saveToolCache(serverName, tools);
543
554
  this.logger.info(`[mcp-bridge] Discovered ${tools.length} tools from ${serverName}`);
555
+ // Notify client that tool list changed (MCP spec: notifications/tools/list_changed)
556
+ this.sendToolsChanged();
544
557
  }
545
558
  catch (err) {
546
559
  this.logger.error(`[mcp-bridge] Failed to discover ${serverName}:`, err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwerk/mcp-bridge",
3
- "version": "2.8.29",
3
+ "version": "2.8.31",
4
4
  "description": "Standalone MCP server that multiplexes multiple MCP servers into one interface",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",