@eznix/mcp-gateway 1.4.0 → 1.5.2

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/index.js CHANGED
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
8
13
  var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
9
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
10
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
23
  for (let key of __getOwnPropNames(mod))
12
24
  if (!__hasOwnProp.call(to, key))
13
25
  __defProp(to, key, {
14
- get: () => mod[key],
26
+ get: __accessProp.bind(mod, key),
15
27
  enumerable: true
16
28
  });
29
+ if (canCache)
30
+ cache.set(mod, to);
17
31
  return to;
18
32
  };
19
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
20
38
  var __export = (target, all) => {
21
39
  for (var name in all)
22
40
  __defProp(target, name, {
23
41
  get: all[name],
24
42
  enumerable: true,
25
43
  configurable: true,
26
- set: (newValue) => all[name] = () => newValue
44
+ set: __exportSetter.bind(all, name)
27
45
  });
28
46
  };
29
47
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
@@ -6278,7 +6296,7 @@ var require_formats = __commonJS((exports) => {
6278
6296
  }
6279
6297
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6280
6298
  function getTime(strictTimeZone) {
6281
- return function time(str) {
6299
+ return function time3(str) {
6282
6300
  const matches = TIME.exec(str);
6283
6301
  if (!matches)
6284
6302
  return false;
@@ -14190,8 +14208,9 @@ class Config {
14190
14208
  this.watcher = watch(this.configPath, (event) => {
14191
14209
  if (event !== "change")
14192
14210
  return;
14211
+ const oldConfig = this.getAll();
14193
14212
  this.reload();
14194
- callback(this.config);
14213
+ callback(oldConfig, this.config);
14195
14214
  });
14196
14215
  console.error(` Watching config: ${this.configPath}`);
14197
14216
  }
@@ -24885,6 +24904,10 @@ class ConnectionManager {
24885
24904
  async disconnect(serverKey) {
24886
24905
  const client = this.upstreams.get(serverKey);
24887
24906
  if (client) {
24907
+ const tools = this.searchEngine.getTools().filter((t) => t.server === serverKey);
24908
+ for (const tool of tools) {
24909
+ this.searchEngine.removeTool(tool.id);
24910
+ }
24888
24911
  await client.close();
24889
24912
  this.upstreams.delete(serverKey);
24890
24913
  }
@@ -24901,7 +24924,7 @@ class ConnectionManager {
24901
24924
  // package.json
24902
24925
  var package_default = {
24903
24926
  name: "@eznix/mcp-gateway",
24904
- version: "1.4.0",
24927
+ version: "1.5.2",
24905
24928
  description: "MCP Gateway - Aggregate multiple MCP servers into a single gateway",
24906
24929
  type: "module",
24907
24930
  bin: {
@@ -26206,7 +26229,7 @@ class MCPGateway {
26206
26229
  this.connectAll().catch((err) => {
26207
26230
  console.error(`Background connection error: ${err.message}`);
26208
26231
  });
26209
- this.config.watch((cfg) => this.handleConfigChange(cfg));
26232
+ this.config.watch((oldCfg, newCfg) => this.handleConfigChange(oldCfg, newCfg));
26210
26233
  }
26211
26234
  async startWithHttp(port = 3000) {
26212
26235
  console.error(`MCP Gateway starting (http://localhost:${port})...`);
@@ -26215,11 +26238,10 @@ class MCPGateway {
26215
26238
  sessionIdGenerator: undefined
26216
26239
  });
26217
26240
  await this.server.connect(transport);
26218
- this.config.watch((cfg) => this.handleConfigChange(cfg));
26241
+ this.config.watch((oldCfg, newCfg) => this.handleConfigChange(oldCfg, newCfg));
26219
26242
  return transport;
26220
26243
  }
26221
- handleConfigChange(newConfig) {
26222
- const oldConfig = this.config.getAll();
26244
+ handleConfigChange(oldConfig, newConfig) {
26223
26245
  const oldServers = new Set(Object.keys(oldConfig));
26224
26246
  const newServers = new Set(Object.keys(newConfig));
26225
26247
  const toRemove = [...oldServers].filter((s) => !newServers.has(s));
@@ -26233,13 +26255,30 @@ class MCPGateway {
26233
26255
  for (const key of toUpdate) {
26234
26256
  const oldC = oldConfig[key];
26235
26257
  const newC = newConfig[key];
26236
- if (oldC && newC && oldC.enabled === false && newC.enabled !== false) {
26258
+ if (oldC && oldC.enabled !== false && newC && newC.enabled === false) {
26259
+ await this.connections.disconnect(key);
26260
+ console.error(` ${key} disabled`);
26261
+ continue;
26262
+ }
26263
+ if (oldC && oldC.enabled === false && newC && newC.enabled !== false) {
26237
26264
  try {
26238
26265
  await this.connections.connectWithRetry(key, newC);
26239
- console.error(` ${key} connected`);
26266
+ console.error(` ${key} enabled`);
26240
26267
  } catch (e) {
26241
26268
  console.error(` ${key} failed: ${e.message}`);
26242
26269
  }
26270
+ continue;
26271
+ }
26272
+ if (oldC && newC && oldC.enabled !== false && newC.enabled !== false) {
26273
+ if (JSON.stringify(oldC) !== JSON.stringify(newC)) {
26274
+ await this.connections.disconnect(key);
26275
+ try {
26276
+ await this.connections.connectWithRetry(key, newC);
26277
+ console.error(` ${key} reconnected (config changed)`);
26278
+ } catch (e) {
26279
+ console.error(` ${key} failed: ${e.message}`);
26280
+ }
26281
+ }
26243
26282
  }
26244
26283
  }
26245
26284
  for (const key of toAdd) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eznix/mcp-gateway",
3
- "version": "1.4.0",
3
+ "version": "1.5.2",
4
4
  "description": "MCP Gateway - Aggregate multiple MCP servers into a single gateway",
5
5
  "type": "module",
6
6
  "bin": {
package/src/config.ts CHANGED
@@ -37,12 +37,13 @@ export class Config {
37
37
  return this.config;
38
38
  }
39
39
 
40
- watch(callback: (config: GatewayConfig) => void): void {
40
+ watch(callback: (oldConfig: GatewayConfig, newConfig: GatewayConfig) => void): void {
41
41
  if (this.watcher) return;
42
42
  this.watcher = watch(this.configPath, (event: string) => {
43
43
  if (event !== "change") return;
44
+ const oldConfig = this.getAll(); // snapshot before reload
44
45
  this.reload();
45
- callback(this.config);
46
+ callback(oldConfig, this.config);
46
47
  });
47
48
  console.error(` Watching config: ${this.configPath}`);
48
49
  }
@@ -128,6 +128,12 @@ export class ConnectionManager {
128
128
  async disconnect(serverKey: string): Promise<void> {
129
129
  const client = this.upstreams.get(serverKey);
130
130
  if (client) {
131
+ // Remove all tools for this server from the search index
132
+ const tools = this.searchEngine.getTools().filter((t) => t.server === serverKey);
133
+ for (const tool of tools) {
134
+ this.searchEngine.removeTool(tool.id);
135
+ }
136
+
131
137
  await client.close();
132
138
  this.upstreams.delete(serverKey);
133
139
  }
package/src/gateway.ts CHANGED
@@ -50,7 +50,7 @@ export class MCPGateway {
50
50
  console.error(`Background connection error: ${err.message}`);
51
51
  });
52
52
 
53
- this.config.watch((cfg) => this.handleConfigChange(cfg));
53
+ this.config.watch((oldCfg, newCfg) => this.handleConfigChange(oldCfg, newCfg));
54
54
  }
55
55
 
56
56
  async startWithHttp(port: number = 3000): Promise<StreamableHTTPServerTransport> {
@@ -61,13 +61,12 @@ export class MCPGateway {
61
61
  sessionIdGenerator: undefined,
62
62
  });
63
63
  await this.server.connect(transport);
64
- this.config.watch((cfg) => this.handleConfigChange(cfg));
64
+ this.config.watch((oldCfg, newCfg) => this.handleConfigChange(oldCfg, newCfg));
65
65
 
66
66
  return transport;
67
67
  }
68
68
 
69
- private handleConfigChange(newConfig: GatewayConfig): void {
70
- const oldConfig = this.config.getAll();
69
+ private handleConfigChange(oldConfig: GatewayConfig, newConfig: GatewayConfig): void {
71
70
  const oldServers = new Set(Object.keys(oldConfig));
72
71
  const newServers = new Set(Object.keys(newConfig));
73
72
 
@@ -84,8 +83,37 @@ export class MCPGateway {
84
83
  for (const key of toUpdate) {
85
84
  const oldC = oldConfig[key];
86
85
  const newC = newConfig[key];
87
- if (oldC && newC && oldC.enabled === false && newC.enabled !== false) {
88
- try { await this.connections.connectWithRetry(key, newC); console.error(` ${key} connected`); } catch (e: any) { console.error(` ${key} failed: ${e.message}`); }
86
+
87
+ // Handle disabling a server
88
+ if (oldC && oldC.enabled !== false && newC && newC.enabled === false) {
89
+ await this.connections.disconnect(key);
90
+ console.error(` ${key} disabled`);
91
+ continue;
92
+ }
93
+
94
+ // Handle enabling a previously disabled server
95
+ if (oldC && oldC.enabled === false && newC && newC.enabled !== false) {
96
+ try {
97
+ await this.connections.connectWithRetry(key, newC);
98
+ console.error(` ${key} enabled`);
99
+ } catch (e: any) {
100
+ console.error(` ${key} failed: ${e.message}`);
101
+ }
102
+ continue;
103
+ }
104
+
105
+ // Handle config changes for enabled servers (reconnect)
106
+ if (oldC && newC && oldC.enabled !== false && newC.enabled !== false) {
107
+ // Deep compare to detect any config changes
108
+ if (JSON.stringify(oldC) !== JSON.stringify(newC)) {
109
+ await this.connections.disconnect(key);
110
+ try {
111
+ await this.connections.connectWithRetry(key, newC);
112
+ console.error(` ${key} reconnected (config changed)`);
113
+ } catch (e: any) {
114
+ console.error(` ${key} failed: ${e.message}`);
115
+ }
116
+ }
89
117
  }
90
118
  }
91
119