nuwax-mcp-stdio-proxy 1.4.5 → 1.4.6
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/bridge.js +33 -15
- package/dist/index.js +28 -16
- package/package.json +1 -1
package/dist/bridge.js
CHANGED
|
@@ -49,17 +49,36 @@ export class PersistentMcpBridge {
|
|
|
49
49
|
this.log.warn(`${LOG_TAG} Already running, stopping first`);
|
|
50
50
|
await this.stop();
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
const serverCount = Object.keys(servers).length;
|
|
53
|
+
this.log.info(`${LOG_TAG} Starting with ${serverCount} persistent servers (parallel)`);
|
|
54
|
+
// 1. 并行启动 HTTP server 和所有 MCP server 子进程。
|
|
55
|
+
// 两者完全独立:HTTP server 在请求时才查询 this.servers,
|
|
56
|
+
// startServer 会在异步 spawnAndConnect 前先同步写入 this.servers,
|
|
57
|
+
// 所以 HTTP server 收到第一个请求时所有 entry 都已注册。
|
|
58
|
+
//
|
|
59
|
+
// 提前保存 serverPromises 引用:若 startHttpServer 抛出,在 catch 中先
|
|
60
|
+
// await Promise.allSettled(serverPromises) 等所有 spawnAndConnect 跑完
|
|
61
|
+
// (保证 entry.client / entry.transport 已赋值),再调用 stopServer,
|
|
62
|
+
// 才能可靠关闭子进程,防止孤儿进程残留。
|
|
63
|
+
const serverPromises = Object.entries(servers).map(([id, config]) => this.startServer(id, config));
|
|
64
|
+
try {
|
|
65
|
+
await Promise.all([
|
|
66
|
+
this.startHttpServer(options?.port),
|
|
67
|
+
...serverPromises,
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
this.log.error(`${LOG_TAG} 启动失败,清理已 spawn 的子进程:`, e);
|
|
72
|
+
// 等待所有 spawnAndConnect 完成,确保 entry.client/transport 已赋值后再清理
|
|
73
|
+
await Promise.allSettled(serverPromises);
|
|
74
|
+
await Promise.all(Array.from(this.servers.keys()).map((id) => this.stopServer(id)));
|
|
75
|
+
this.servers.clear();
|
|
76
|
+
throw e;
|
|
56
77
|
}
|
|
57
|
-
// 2. Start HTTP server
|
|
58
|
-
await this.startHttpServer(options?.port);
|
|
59
78
|
this.running = true;
|
|
60
|
-
//
|
|
79
|
+
// 2. Start periodic session cleanup
|
|
61
80
|
this.sessionCleanupTimer = setInterval(() => this.cleanupStaleSessions(), SESSION_CLEANUP_INTERVAL_MS);
|
|
62
|
-
this.log.info(`${LOG_TAG} Bridge ready on port ${this.port}`);
|
|
81
|
+
this.log.info(`${LOG_TAG} Bridge ready on port ${this.port} (${serverCount} servers)`);
|
|
63
82
|
}
|
|
64
83
|
/**
|
|
65
84
|
* Stop bridge: close HTTP, kill all child processes
|
|
@@ -72,15 +91,16 @@ export class PersistentMcpBridge {
|
|
|
72
91
|
clearInterval(this.sessionCleanupTimer);
|
|
73
92
|
this.sessionCleanupTimer = null;
|
|
74
93
|
}
|
|
75
|
-
//
|
|
76
|
-
|
|
94
|
+
// 并行关闭所有 HTTP sessions(各 session transport 独立,无顺序依赖)。
|
|
95
|
+
// 内层 async 函数自行 catch 错误后不再 throw,Promise.all 足够,不需要 allSettled。
|
|
96
|
+
await Promise.all(Array.from(this.httpSessions.entries()).map(async ([key, session]) => {
|
|
77
97
|
try {
|
|
78
98
|
await session.transport.close();
|
|
79
99
|
}
|
|
80
100
|
catch (e) {
|
|
81
101
|
this.log.warn(`${LOG_TAG} Error closing HTTP session ${key}:`, e);
|
|
82
102
|
}
|
|
83
|
-
}
|
|
103
|
+
}));
|
|
84
104
|
this.httpSessions.clear();
|
|
85
105
|
// Close HTTP server
|
|
86
106
|
if (this.httpServer) {
|
|
@@ -90,10 +110,8 @@ export class PersistentMcpBridge {
|
|
|
90
110
|
this.httpServer = null;
|
|
91
111
|
this.port = 0;
|
|
92
112
|
}
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
await this.stopServer(id);
|
|
96
|
-
}
|
|
113
|
+
// 并行关闭所有 MCP server 子进程(各自独立,无顺序依赖)
|
|
114
|
+
await Promise.all(Array.from(this.servers.keys()).map((id) => this.stopServer(id)));
|
|
97
115
|
this.servers.clear();
|
|
98
116
|
this.log.info(`${LOG_TAG} Stopped`);
|
|
99
117
|
}
|
package/dist/index.js
CHANGED
|
@@ -23767,7 +23767,7 @@ var StdioServerTransport = class {
|
|
|
23767
23767
|
|
|
23768
23768
|
// src/constants.ts
|
|
23769
23769
|
var PKG_NAME = "nuwax-mcp-stdio-proxy";
|
|
23770
|
-
var PKG_VERSION = "1.4.
|
|
23770
|
+
var PKG_VERSION = "1.4.6";
|
|
23771
23771
|
|
|
23772
23772
|
// src/shared.ts
|
|
23773
23773
|
async function discoverTools(client) {
|
|
@@ -25382,14 +25382,24 @@ var PersistentMcpBridge = class {
|
|
|
25382
25382
|
this.log.warn(`${LOG_TAG} Already running, stopping first`);
|
|
25383
25383
|
await this.stop();
|
|
25384
25384
|
}
|
|
25385
|
-
|
|
25386
|
-
|
|
25387
|
-
|
|
25385
|
+
const serverCount = Object.keys(servers).length;
|
|
25386
|
+
this.log.info(`${LOG_TAG} Starting with ${serverCount} persistent servers (parallel)`);
|
|
25387
|
+
const serverPromises = Object.entries(servers).map(([id, config2]) => this.startServer(id, config2));
|
|
25388
|
+
try {
|
|
25389
|
+
await Promise.all([
|
|
25390
|
+
this.startHttpServer(options?.port),
|
|
25391
|
+
...serverPromises
|
|
25392
|
+
]);
|
|
25393
|
+
} catch (e) {
|
|
25394
|
+
this.log.error(`${LOG_TAG} \u542F\u52A8\u5931\u8D25\uFF0C\u6E05\u7406\u5DF2 spawn \u7684\u5B50\u8FDB\u7A0B:`, e);
|
|
25395
|
+
await Promise.allSettled(serverPromises);
|
|
25396
|
+
await Promise.all(Array.from(this.servers.keys()).map((id) => this.stopServer(id)));
|
|
25397
|
+
this.servers.clear();
|
|
25398
|
+
throw e;
|
|
25388
25399
|
}
|
|
25389
|
-
await this.startHttpServer(options?.port);
|
|
25390
25400
|
this.running = true;
|
|
25391
25401
|
this.sessionCleanupTimer = setInterval(() => this.cleanupStaleSessions(), SESSION_CLEANUP_INTERVAL_MS);
|
|
25392
|
-
this.log.info(`${LOG_TAG} Bridge ready on port ${this.port}`);
|
|
25402
|
+
this.log.info(`${LOG_TAG} Bridge ready on port ${this.port} (${serverCount} servers)`);
|
|
25393
25403
|
}
|
|
25394
25404
|
/**
|
|
25395
25405
|
* Stop bridge: close HTTP, kill all child processes
|
|
@@ -25401,13 +25411,15 @@ var PersistentMcpBridge = class {
|
|
|
25401
25411
|
clearInterval(this.sessionCleanupTimer);
|
|
25402
25412
|
this.sessionCleanupTimer = null;
|
|
25403
25413
|
}
|
|
25404
|
-
|
|
25405
|
-
|
|
25406
|
-
|
|
25407
|
-
|
|
25408
|
-
|
|
25409
|
-
|
|
25410
|
-
|
|
25414
|
+
await Promise.all(
|
|
25415
|
+
Array.from(this.httpSessions.entries()).map(async ([key, session]) => {
|
|
25416
|
+
try {
|
|
25417
|
+
await session.transport.close();
|
|
25418
|
+
} catch (e) {
|
|
25419
|
+
this.log.warn(`${LOG_TAG} Error closing HTTP session ${key}:`, e);
|
|
25420
|
+
}
|
|
25421
|
+
})
|
|
25422
|
+
);
|
|
25411
25423
|
this.httpSessions.clear();
|
|
25412
25424
|
if (this.httpServer) {
|
|
25413
25425
|
await new Promise((resolve) => {
|
|
@@ -25416,9 +25428,9 @@ var PersistentMcpBridge = class {
|
|
|
25416
25428
|
this.httpServer = null;
|
|
25417
25429
|
this.port = 0;
|
|
25418
25430
|
}
|
|
25419
|
-
|
|
25420
|
-
|
|
25421
|
-
|
|
25431
|
+
await Promise.all(
|
|
25432
|
+
Array.from(this.servers.keys()).map((id) => this.stopServer(id))
|
|
25433
|
+
);
|
|
25422
25434
|
this.servers.clear();
|
|
25423
25435
|
this.log.info(`${LOG_TAG} Stopped`);
|
|
25424
25436
|
}
|
package/package.json
CHANGED