@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 +50 -11
- package/package.json +1 -1
- package/src/config.ts +3 -2
- package/src/connections.ts +6 -0
- package/src/gateway.ts +34 -6
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: (
|
|
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: (
|
|
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
|
|
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.
|
|
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((
|
|
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((
|
|
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 &&
|
|
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}
|
|
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
package/src/config.ts
CHANGED
|
@@ -37,12 +37,13 @@ export class Config {
|
|
|
37
37
|
return this.config;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
watch(callback: (
|
|
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
|
}
|
package/src/connections.ts
CHANGED
|
@@ -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((
|
|
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((
|
|
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
|
-
|
|
88
|
-
|
|
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
|
|