@agiflowai/one-mcp 0.3.14 → 0.3.15
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/cli.cjs +5 -5
- package/dist/cli.mjs +5 -5
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +1 -1
- package/dist/{src-D7Yq1bTx.mjs → src-CH93aUm2.mjs} +135 -30
- package/dist/{src-iTE9Cero.cjs → src-CWShQS8u.cjs} +135 -30
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_src = require('./src-
|
|
2
|
+
const require_src = require('./src-CWShQS8u.cjs');
|
|
3
3
|
let node_fs_promises = require("node:fs/promises");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
@@ -653,9 +653,9 @@ async function removeRuntimeRecordDuringStop(runtimeStateService, serverId) {
|
|
|
653
653
|
throw new Error(`Failed to remove runtime state during HTTP stop callback for '${serverId}': ${toErrorMessage$6(error)}`);
|
|
654
654
|
}
|
|
655
655
|
}
|
|
656
|
-
|
|
656
|
+
function createStdioHttpInternalTransport(serverOptions, config, adminOptions) {
|
|
657
657
|
try {
|
|
658
|
-
return new require_src.HttpTransportHandler(
|
|
658
|
+
return new require_src.HttpTransportHandler(() => require_src.createServer(serverOptions), config, adminOptions);
|
|
659
659
|
} catch (error) {
|
|
660
660
|
throw new Error(`Failed to create internal HTTP transport for stdio-http proxy: ${toErrorMessage$6(error)}`);
|
|
661
661
|
}
|
|
@@ -702,7 +702,7 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
702
702
|
}
|
|
703
703
|
};
|
|
704
704
|
try {
|
|
705
|
-
handler = new require_src.HttpTransportHandler(
|
|
705
|
+
handler = new require_src.HttpTransportHandler(() => require_src.createServer(serverOptions), config, createHttpAdminOptions(runtimeRecord.serverId, shutdownToken, stopHandler));
|
|
706
706
|
} catch (error) {
|
|
707
707
|
throw new Error(`Failed to create HTTP runtime server: ${toErrorMessage$6(error)}`);
|
|
708
708
|
}
|
|
@@ -776,7 +776,7 @@ async function startStdioHttpTransport(serverOptions, config, resolvedConfigPath
|
|
|
776
776
|
initialProxyConnectError = error;
|
|
777
777
|
}
|
|
778
778
|
try {
|
|
779
|
-
httpHandler =
|
|
779
|
+
httpHandler = createStdioHttpInternalTransport(serverOptions, config, adminOptions);
|
|
780
780
|
await httpHandler.start();
|
|
781
781
|
ownsInternalHttpTransport = true;
|
|
782
782
|
} catch (error) {
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as findConfigFile, a as SseTransportHandler, c as createServer, d as SearchListToolsTool, g as generateServerId, h as DefinitionsCacheService, i as StdioTransportHandler, l as version, m as McpClientManagerService, n as RuntimeStateService, o as HttpTransportHandler, p as SkillService, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, v as ConfigFetcherService } from "./src-
|
|
2
|
+
import { _ as findConfigFile, a as SseTransportHandler, c as createServer, d as SearchListToolsTool, g as generateServerId, h as DefinitionsCacheService, i as StdioTransportHandler, l as version, m as McpClientManagerService, n as RuntimeStateService, o as HttpTransportHandler, p as SkillService, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, v as ConfigFetcherService } from "./src-CH93aUm2.mjs";
|
|
3
3
|
import { access, writeFile } from "node:fs/promises";
|
|
4
4
|
import { constants } from "node:fs";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
@@ -653,9 +653,9 @@ async function removeRuntimeRecordDuringStop(runtimeStateService, serverId) {
|
|
|
653
653
|
throw new Error(`Failed to remove runtime state during HTTP stop callback for '${serverId}': ${toErrorMessage$6(error)}`);
|
|
654
654
|
}
|
|
655
655
|
}
|
|
656
|
-
|
|
656
|
+
function createStdioHttpInternalTransport(serverOptions, config, adminOptions) {
|
|
657
657
|
try {
|
|
658
|
-
return new HttpTransportHandler(
|
|
658
|
+
return new HttpTransportHandler(() => createServer(serverOptions), config, adminOptions);
|
|
659
659
|
} catch (error) {
|
|
660
660
|
throw new Error(`Failed to create internal HTTP transport for stdio-http proxy: ${toErrorMessage$6(error)}`);
|
|
661
661
|
}
|
|
@@ -702,7 +702,7 @@ async function createAndStartHttpRuntime(serverOptions, config, resolvedConfigPa
|
|
|
702
702
|
}
|
|
703
703
|
};
|
|
704
704
|
try {
|
|
705
|
-
handler = new HttpTransportHandler(
|
|
705
|
+
handler = new HttpTransportHandler(() => createServer(serverOptions), config, createHttpAdminOptions(runtimeRecord.serverId, shutdownToken, stopHandler));
|
|
706
706
|
} catch (error) {
|
|
707
707
|
throw new Error(`Failed to create HTTP runtime server: ${toErrorMessage$6(error)}`);
|
|
708
708
|
}
|
|
@@ -776,7 +776,7 @@ async function startStdioHttpTransport(serverOptions, config, resolvedConfigPath
|
|
|
776
776
|
initialProxyConnectError = error;
|
|
777
777
|
}
|
|
778
778
|
try {
|
|
779
|
-
httpHandler =
|
|
779
|
+
httpHandler = createStdioHttpInternalTransport(serverOptions, config, adminOptions);
|
|
780
780
|
await httpHandler.start();
|
|
781
781
|
ownsInternalHttpTransport = true;
|
|
782
782
|
} catch (error) {
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -440,7 +440,7 @@ declare class HttpTransportHandler implements HttpTransportHandler$1 {
|
|
|
440
440
|
private config;
|
|
441
441
|
private adminOptions?;
|
|
442
442
|
private adminRateLimiter;
|
|
443
|
-
constructor(serverFactory:
|
|
443
|
+
constructor(serverFactory: (() => Server | Promise<Server>), config: TransportConfig, adminOptions?: HttpTransportAdminOptions);
|
|
444
444
|
private setupMiddleware;
|
|
445
445
|
private setupRoutes;
|
|
446
446
|
private isAuthorizedShutdownRequest;
|
|
@@ -1083,7 +1083,7 @@ declare class RuntimeStateService implements RuntimeStateManager {
|
|
|
1083
1083
|
remove(serverId: string): Promise<void>;
|
|
1084
1084
|
}
|
|
1085
1085
|
//#endregion
|
|
1086
|
-
//#region src/services/StopServerService.d.ts
|
|
1086
|
+
//#region src/services/StopServerService/types.d.ts
|
|
1087
1087
|
/**
|
|
1088
1088
|
* Stop request options.
|
|
1089
1089
|
* @property serverId - Explicit one-mcp server identifier to stop
|
|
@@ -1116,6 +1116,8 @@ interface StopServerResult {
|
|
|
1116
1116
|
port: number;
|
|
1117
1117
|
message: string;
|
|
1118
1118
|
}
|
|
1119
|
+
//#endregion
|
|
1120
|
+
//#region src/services/StopServerService/StopServerService.d.ts
|
|
1119
1121
|
/**
|
|
1120
1122
|
* Service for resolving runtime targets and stopping them safely.
|
|
1121
1123
|
*/
|
package/dist/index.d.mts
CHANGED
|
@@ -441,7 +441,7 @@ declare class HttpTransportHandler implements HttpTransportHandler$1 {
|
|
|
441
441
|
private config;
|
|
442
442
|
private adminOptions?;
|
|
443
443
|
private adminRateLimiter;
|
|
444
|
-
constructor(serverFactory:
|
|
444
|
+
constructor(serverFactory: (() => Server | Promise<Server>), config: TransportConfig, adminOptions?: HttpTransportAdminOptions);
|
|
445
445
|
private setupMiddleware;
|
|
446
446
|
private setupRoutes;
|
|
447
447
|
private isAuthorizedShutdownRequest;
|
|
@@ -1084,7 +1084,7 @@ declare class RuntimeStateService implements RuntimeStateManager {
|
|
|
1084
1084
|
remove(serverId: string): Promise<void>;
|
|
1085
1085
|
}
|
|
1086
1086
|
//#endregion
|
|
1087
|
-
//#region src/services/StopServerService.d.ts
|
|
1087
|
+
//#region src/services/StopServerService/types.d.ts
|
|
1088
1088
|
/**
|
|
1089
1089
|
* Stop request options.
|
|
1090
1090
|
* @property serverId - Explicit one-mcp server identifier to stop
|
|
@@ -1117,6 +1117,8 @@ interface StopServerResult {
|
|
|
1117
1117
|
port: number;
|
|
1118
1118
|
message: string;
|
|
1119
1119
|
}
|
|
1120
|
+
//#endregion
|
|
1121
|
+
//#region src/services/StopServerService/StopServerService.d.ts
|
|
1120
1122
|
/**
|
|
1121
1123
|
* Service for resolving runtime targets and stopping them safely.
|
|
1122
1124
|
*/
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { _ as findConfigFile, a as SseTransportHandler, c as createServer, d as SearchListToolsTool, f as DescribeToolsTool, g as generateServerId, h as DefinitionsCacheService, i as StdioTransportHandler, m as McpClientManagerService, n as RuntimeStateService, o as HttpTransportHandler, p as SkillService, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, u as UseToolTool, v as ConfigFetcherService } from "./src-
|
|
1
|
+
import { _ as findConfigFile, a as SseTransportHandler, c as createServer, d as SearchListToolsTool, f as DescribeToolsTool, g as generateServerId, h as DefinitionsCacheService, i as StdioTransportHandler, m as McpClientManagerService, n as RuntimeStateService, o as HttpTransportHandler, p as SkillService, r as StdioHttpTransportHandler, s as TRANSPORT_MODE, t as StopServerService, u as UseToolTool, v as ConfigFetcherService } from "./src-CH93aUm2.mjs";
|
|
2
2
|
|
|
3
3
|
export { ConfigFetcherService, DefinitionsCacheService, DescribeToolsTool, HttpTransportHandler, McpClientManagerService, RuntimeStateService, SearchListToolsTool, SkillService, SseTransportHandler, StdioHttpTransportHandler, StdioTransportHandler, StopServerService, TRANSPORT_MODE, UseToolTool, createServer, findConfigFile, generateServerId };
|
|
@@ -2779,7 +2779,7 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
|
|
|
2779
2779
|
|
|
2780
2780
|
//#endregion
|
|
2781
2781
|
//#region package.json
|
|
2782
|
-
var version = "0.3.
|
|
2782
|
+
var version = "0.3.14";
|
|
2783
2783
|
|
|
2784
2784
|
//#endregion
|
|
2785
2785
|
//#region src/server/index.ts
|
|
@@ -3147,16 +3147,26 @@ var HttpFullSessionManager = class {
|
|
|
3147
3147
|
server
|
|
3148
3148
|
});
|
|
3149
3149
|
}
|
|
3150
|
-
deleteSession(sessionId) {
|
|
3150
|
+
async deleteSession(sessionId) {
|
|
3151
3151
|
const session = this.sessions.get(sessionId);
|
|
3152
|
-
if (session)
|
|
3152
|
+
if (session) try {
|
|
3153
|
+
await session.server.close();
|
|
3154
|
+
} catch (error) {
|
|
3155
|
+
throw new Error(`Failed to close MCP server for session '${sessionId}': ${toErrorMessage$2(error)}`);
|
|
3156
|
+
}
|
|
3153
3157
|
this.sessions.delete(sessionId);
|
|
3154
3158
|
}
|
|
3155
3159
|
hasSession(sessionId) {
|
|
3156
3160
|
return this.sessions.has(sessionId);
|
|
3157
3161
|
}
|
|
3158
|
-
clear() {
|
|
3159
|
-
|
|
3162
|
+
async clear() {
|
|
3163
|
+
try {
|
|
3164
|
+
await Promise.all(Array.from(this.sessions.values()).map(async (session) => {
|
|
3165
|
+
await session.server.close();
|
|
3166
|
+
}));
|
|
3167
|
+
} catch (error) {
|
|
3168
|
+
throw new Error(`Failed to clear sessions: ${toErrorMessage$2(error)}`);
|
|
3169
|
+
}
|
|
3160
3170
|
this.sessions.clear();
|
|
3161
3171
|
}
|
|
3162
3172
|
};
|
|
@@ -3197,7 +3207,7 @@ var HttpTransportHandler = class {
|
|
|
3197
3207
|
adminOptions;
|
|
3198
3208
|
adminRateLimiter = new AdminRateLimiter();
|
|
3199
3209
|
constructor(serverFactory, config, adminOptions) {
|
|
3200
|
-
this.serverFactory =
|
|
3210
|
+
this.serverFactory = serverFactory;
|
|
3201
3211
|
this.app = express();
|
|
3202
3212
|
this.sessionManager = new HttpFullSessionManager();
|
|
3203
3213
|
this.config = {
|
|
@@ -3320,7 +3330,7 @@ var HttpTransportHandler = class {
|
|
|
3320
3330
|
let transport;
|
|
3321
3331
|
if (sessionId && this.sessionManager.hasSession(sessionId)) transport = this.sessionManager.getSession(sessionId).transport;
|
|
3322
3332
|
else if (!sessionId && isInitializeRequest(req.body)) {
|
|
3323
|
-
const mcpServer = this.serverFactory();
|
|
3333
|
+
const mcpServer = await this.serverFactory();
|
|
3324
3334
|
transport = new StreamableHTTPServerTransport({
|
|
3325
3335
|
sessionIdGenerator: () => randomUUID(),
|
|
3326
3336
|
enableJsonResponse: true,
|
|
@@ -3328,8 +3338,12 @@ var HttpTransportHandler = class {
|
|
|
3328
3338
|
this.sessionManager.setSession(initializedSessionId, transport, mcpServer);
|
|
3329
3339
|
}
|
|
3330
3340
|
});
|
|
3331
|
-
transport.onclose = () => {
|
|
3332
|
-
if (transport.sessionId)
|
|
3341
|
+
transport.onclose = async () => {
|
|
3342
|
+
if (transport.sessionId) try {
|
|
3343
|
+
await this.sessionManager.deleteSession(transport.sessionId);
|
|
3344
|
+
} catch (error) {
|
|
3345
|
+
console.error(`Failed to clean up session '${transport.sessionId}': ${toErrorMessage$2(error)}`);
|
|
3346
|
+
}
|
|
3333
3347
|
};
|
|
3334
3348
|
try {
|
|
3335
3349
|
await mcpServer.connect(transport);
|
|
@@ -3378,7 +3392,7 @@ var HttpTransportHandler = class {
|
|
|
3378
3392
|
} catch (error) {
|
|
3379
3393
|
throw new Error(`Failed handling MCP DELETE request for session '${sessionId}': ${toErrorMessage$2(error)}`);
|
|
3380
3394
|
}
|
|
3381
|
-
this.sessionManager.deleteSession(sessionId);
|
|
3395
|
+
await this.sessionManager.deleteSession(sessionId);
|
|
3382
3396
|
}
|
|
3383
3397
|
async start() {
|
|
3384
3398
|
try {
|
|
@@ -3401,7 +3415,11 @@ var HttpTransportHandler = class {
|
|
|
3401
3415
|
}
|
|
3402
3416
|
async stop() {
|
|
3403
3417
|
if (!this.server) return;
|
|
3404
|
-
|
|
3418
|
+
try {
|
|
3419
|
+
await this.sessionManager.clear();
|
|
3420
|
+
} catch (error) {
|
|
3421
|
+
throw new Error(`Failed to clear sessions during HTTP transport stop: ${toErrorMessage$2(error)}`);
|
|
3422
|
+
}
|
|
3405
3423
|
const closeServer = promisify(this.server.close.bind(this.server));
|
|
3406
3424
|
try {
|
|
3407
3425
|
await closeServer();
|
|
@@ -3738,11 +3756,11 @@ var StdioHttpTransportHandler = class {
|
|
|
3738
3756
|
*/
|
|
3739
3757
|
const RUNTIME_DIR_NAME = "runtimes";
|
|
3740
3758
|
const RUNTIME_FILE_SUFFIX = ".runtime.json";
|
|
3741
|
-
function isObject
|
|
3759
|
+
function isObject(value) {
|
|
3742
3760
|
return typeof value === "object" && value !== null;
|
|
3743
3761
|
}
|
|
3744
3762
|
function isRuntimeStateRecord(value) {
|
|
3745
|
-
if (!isObject
|
|
3763
|
+
if (!isObject(value)) return false;
|
|
3746
3764
|
return typeof value.serverId === "string" && typeof value.host === "string" && typeof value.port === "number" && value.transport === "http" && typeof value.shutdownToken === "string" && typeof value.startedAt === "string" && typeof value.pid === "number" && (value.configPath === void 0 || typeof value.configPath === "string");
|
|
3747
3765
|
}
|
|
3748
3766
|
function toErrorMessage$1(error) {
|
|
@@ -3792,7 +3810,7 @@ var RuntimeStateService = class RuntimeStateService {
|
|
|
3792
3810
|
const parsed = JSON.parse(content);
|
|
3793
3811
|
return isRuntimeStateRecord(parsed) ? parsed : null;
|
|
3794
3812
|
} catch (error) {
|
|
3795
|
-
if (isObject
|
|
3813
|
+
if (isObject(error) && "code" in error && error.code === "ENOENT") return null;
|
|
3796
3814
|
throw new Error(`Failed to read runtime state for server '${serverId}' from '${filePath}': ${toErrorMessage$1(error)}`);
|
|
3797
3815
|
}
|
|
3798
3816
|
}
|
|
@@ -3813,7 +3831,7 @@ var RuntimeStateService = class RuntimeStateService {
|
|
|
3813
3831
|
}
|
|
3814
3832
|
}))).filter((record) => record !== null);
|
|
3815
3833
|
} catch (error) {
|
|
3816
|
-
if (isObject
|
|
3834
|
+
if (isObject(error) && "code" in error && error.code === "ENOENT") return [];
|
|
3817
3835
|
throw new Error(`Failed to list runtime states from '${this.runtimeDir}': ${toErrorMessage$1(error)}`);
|
|
3818
3836
|
}
|
|
3819
3837
|
}
|
|
@@ -3828,18 +3846,105 @@ var RuntimeStateService = class RuntimeStateService {
|
|
|
3828
3846
|
};
|
|
3829
3847
|
|
|
3830
3848
|
//#endregion
|
|
3831
|
-
//#region src/services/StopServerService.ts
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3849
|
+
//#region src/services/StopServerService/constants.ts
|
|
3850
|
+
/**
|
|
3851
|
+
* StopServerService constants.
|
|
3852
|
+
*/
|
|
3853
|
+
/** Maximum time in milliseconds to wait for a shutdown to complete. */
|
|
3854
|
+
const DEFAULT_STOP_TIMEOUT_MS = 5e3;
|
|
3855
|
+
/** Minimum timeout in milliseconds for individual health check requests. */
|
|
3856
|
+
const HEALTH_REQUEST_TIMEOUT_FLOOR_MS = 250;
|
|
3857
|
+
/** Delay in milliseconds between shutdown polling attempts. */
|
|
3858
|
+
const SHUTDOWN_POLL_INTERVAL_MS = 200;
|
|
3859
|
+
/** Path for the runtime health check endpoint. */
|
|
3860
|
+
const HEALTH_CHECK_PATH = "/health";
|
|
3861
|
+
/** Path for the authenticated admin shutdown endpoint. */
|
|
3862
|
+
const ADMIN_SHUTDOWN_PATH = "/admin/shutdown";
|
|
3863
|
+
/** HTTP GET method identifier. */
|
|
3864
|
+
const HTTP_METHOD_GET = "GET";
|
|
3865
|
+
/** HTTP POST method identifier. */
|
|
3866
|
+
const HTTP_METHOD_POST = "POST";
|
|
3867
|
+
/** HTTP header name for bearer token authorization. */
|
|
3868
|
+
const AUTHORIZATION_HEADER_NAME = "Authorization";
|
|
3869
|
+
/** Prefix for bearer token values in the Authorization header. */
|
|
3870
|
+
const BEARER_TOKEN_PREFIX = "Bearer ";
|
|
3871
|
+
/** HTTP protocol scheme prefix for URL construction. */
|
|
3872
|
+
const HTTP_PROTOCOL = "http://";
|
|
3873
|
+
/** Separator between host and port in URL construction. */
|
|
3874
|
+
const URL_PORT_SEPARATOR = ":";
|
|
3875
|
+
/** Loopback hostname. */
|
|
3876
|
+
const LOOPBACK_HOST_LOCALHOST = "localhost";
|
|
3877
|
+
/** IPv4 loopback address. */
|
|
3878
|
+
const LOOPBACK_HOST_IPV4 = "127.0.0.1";
|
|
3879
|
+
/** IPv6 loopback address. */
|
|
3880
|
+
const LOOPBACK_HOST_IPV6 = "::1";
|
|
3881
|
+
/** Hosts that are safe to send admin requests to (loopback only). */
|
|
3882
|
+
const ALLOWED_HOSTS = new Set([
|
|
3883
|
+
LOOPBACK_HOST_LOCALHOST,
|
|
3884
|
+
LOOPBACK_HOST_IPV4,
|
|
3885
|
+
LOOPBACK_HOST_IPV6
|
|
3886
|
+
]);
|
|
3887
|
+
/** Expected status value in a healthy runtime response. */
|
|
3888
|
+
const HEALTH_STATUS_OK = "ok";
|
|
3889
|
+
/** Expected transport value in a healthy runtime response. */
|
|
3890
|
+
const HEALTH_TRANSPORT_HTTP = "http";
|
|
3891
|
+
/** Property key for status field in health responses. */
|
|
3892
|
+
const KEY_STATUS = "status";
|
|
3893
|
+
/** Property key for transport field in health responses. */
|
|
3894
|
+
const KEY_TRANSPORT = "transport";
|
|
3895
|
+
/** Property key for serverId field in runtime responses. */
|
|
3896
|
+
const KEY_SERVER_ID = "serverId";
|
|
3897
|
+
/** Property key for ok field in shutdown responses. */
|
|
3898
|
+
const KEY_OK = "ok";
|
|
3899
|
+
/** Property key for message field in shutdown responses. */
|
|
3900
|
+
const KEY_MESSAGE = "message";
|
|
3901
|
+
|
|
3902
|
+
//#endregion
|
|
3903
|
+
//#region src/services/StopServerService/types.ts
|
|
3904
|
+
/**
|
|
3905
|
+
* Safely cast a non-null object to a string-keyed record for property access.
|
|
3906
|
+
* @param value - Object value already verified as non-null
|
|
3907
|
+
* @returns The same value typed as a record
|
|
3908
|
+
*/
|
|
3909
|
+
function toRecord(value) {
|
|
3910
|
+
return value;
|
|
3837
3911
|
}
|
|
3912
|
+
/**
|
|
3913
|
+
* Type guard for health responses.
|
|
3914
|
+
* @param value - Candidate payload to validate
|
|
3915
|
+
* @returns True when payload matches health response shape
|
|
3916
|
+
*/
|
|
3838
3917
|
function isHealthResponse(value) {
|
|
3839
|
-
|
|
3918
|
+
if (typeof value !== "object" || value === null) return false;
|
|
3919
|
+
const record = toRecord(value);
|
|
3920
|
+
return KEY_STATUS in record && record[KEY_STATUS] === HEALTH_STATUS_OK && KEY_TRANSPORT in record && record[KEY_TRANSPORT] === HEALTH_TRANSPORT_HTTP && (!(KEY_SERVER_ID in record) || record[KEY_SERVER_ID] === void 0 || typeof record[KEY_SERVER_ID] === "string");
|
|
3840
3921
|
}
|
|
3922
|
+
/**
|
|
3923
|
+
* Type guard for shutdown responses.
|
|
3924
|
+
* @param value - Candidate payload to validate
|
|
3925
|
+
* @returns True when payload matches shutdown response shape
|
|
3926
|
+
*/
|
|
3841
3927
|
function isShutdownResponse(value) {
|
|
3842
|
-
|
|
3928
|
+
if (typeof value !== "object" || value === null) return false;
|
|
3929
|
+
const record = toRecord(value);
|
|
3930
|
+
return KEY_OK in record && typeof record[KEY_OK] === "boolean" && KEY_MESSAGE in record && typeof record[KEY_MESSAGE] === "string" && (!(KEY_SERVER_ID in record) || record[KEY_SERVER_ID] === void 0 || typeof record[KEY_SERVER_ID] === "string");
|
|
3931
|
+
}
|
|
3932
|
+
|
|
3933
|
+
//#endregion
|
|
3934
|
+
//#region src/services/StopServerService/StopServerService.ts
|
|
3935
|
+
/**
|
|
3936
|
+
* Format runtime endpoint URL after validating the host is a loopback address.
|
|
3937
|
+
* Rejects non-loopback hosts to prevent SSRF via tampered runtime state files.
|
|
3938
|
+
* @param runtime - Runtime record to format
|
|
3939
|
+
* @param path - Request path to append
|
|
3940
|
+
* @returns Full runtime URL
|
|
3941
|
+
*/
|
|
3942
|
+
function buildRuntimeUrl(runtime, path) {
|
|
3943
|
+
if (!ALLOWED_HOSTS.has(runtime.host)) throw new Error(`Refusing to connect to non-loopback host '${runtime.host}'. Only ${Array.from(ALLOWED_HOSTS).join(", ")} are allowed.`);
|
|
3944
|
+
return `${HTTP_PROTOCOL}${runtime.host}${URL_PORT_SEPARATOR}${runtime.port}${path}`;
|
|
3945
|
+
}
|
|
3946
|
+
function toErrorMessage(error) {
|
|
3947
|
+
return error instanceof Error ? error.message : String(error);
|
|
3843
3948
|
}
|
|
3844
3949
|
function sleep(delayMs) {
|
|
3845
3950
|
return new Promise((resolve$1) => {
|
|
@@ -3860,7 +3965,7 @@ var StopServerService = class {
|
|
|
3860
3965
|
* @returns Stop result payload
|
|
3861
3966
|
*/
|
|
3862
3967
|
async stop(request) {
|
|
3863
|
-
const timeoutMs = request.timeoutMs ??
|
|
3968
|
+
const timeoutMs = request.timeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
|
|
3864
3969
|
const runtime = await this.resolveRuntime(request);
|
|
3865
3970
|
const health = await this.fetchHealth(runtime, timeoutMs);
|
|
3866
3971
|
if (!health.reachable) {
|
|
@@ -3906,7 +4011,7 @@ var StopServerService = class {
|
|
|
3906
4011
|
*/
|
|
3907
4012
|
async fetchHealth(runtime, timeoutMs) {
|
|
3908
4013
|
try {
|
|
3909
|
-
const response = await this.fetchWithTimeout(
|
|
4014
|
+
const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, HEALTH_CHECK_PATH), { method: HTTP_METHOD_GET }, timeoutMs);
|
|
3910
4015
|
if (!response.ok) return { reachable: false };
|
|
3911
4016
|
const payload = await response.json();
|
|
3912
4017
|
if (!isHealthResponse(payload)) throw new Error("Received invalid health response payload.");
|
|
@@ -3926,9 +4031,9 @@ var StopServerService = class {
|
|
|
3926
4031
|
* @returns Parsed shutdown response payload
|
|
3927
4032
|
*/
|
|
3928
4033
|
async requestShutdown(runtime, shutdownToken, timeoutMs) {
|
|
3929
|
-
const response = await this.fetchWithTimeout(
|
|
3930
|
-
method:
|
|
3931
|
-
headers: {
|
|
4034
|
+
const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, ADMIN_SHUTDOWN_PATH), {
|
|
4035
|
+
method: HTTP_METHOD_POST,
|
|
4036
|
+
headers: { [AUTHORIZATION_HEADER_NAME]: `${BEARER_TOKEN_PREFIX}${shutdownToken}` }
|
|
3932
4037
|
}, timeoutMs);
|
|
3933
4038
|
const payload = await response.json();
|
|
3934
4039
|
if (!isShutdownResponse(payload)) throw new Error("Received invalid shutdown response payload.");
|
|
@@ -3944,8 +4049,8 @@ var StopServerService = class {
|
|
|
3944
4049
|
async waitForShutdown(runtime, timeoutMs) {
|
|
3945
4050
|
const deadline = Date.now() + timeoutMs;
|
|
3946
4051
|
while (Date.now() < deadline) {
|
|
3947
|
-
if (!(await this.fetchHealth(runtime, Math.max(
|
|
3948
|
-
await sleep(
|
|
4052
|
+
if (!(await this.fetchHealth(runtime, Math.max(HEALTH_REQUEST_TIMEOUT_FLOOR_MS, deadline - Date.now()))).reachable) return;
|
|
4053
|
+
await sleep(SHUTDOWN_POLL_INTERVAL_MS);
|
|
3949
4054
|
}
|
|
3950
4055
|
throw new Error(`Timed out waiting for runtime '${runtime.serverId}' to stop at http://${runtime.host}:${runtime.port}.`);
|
|
3951
4056
|
}
|
|
@@ -2808,7 +2808,7 @@ IMPORTANT: Only use tools discovered from describe_tools with id="${this.serverI
|
|
|
2808
2808
|
|
|
2809
2809
|
//#endregion
|
|
2810
2810
|
//#region package.json
|
|
2811
|
-
var version = "0.3.
|
|
2811
|
+
var version = "0.3.14";
|
|
2812
2812
|
|
|
2813
2813
|
//#endregion
|
|
2814
2814
|
//#region src/server/index.ts
|
|
@@ -3176,16 +3176,26 @@ var HttpFullSessionManager = class {
|
|
|
3176
3176
|
server
|
|
3177
3177
|
});
|
|
3178
3178
|
}
|
|
3179
|
-
deleteSession(sessionId) {
|
|
3179
|
+
async deleteSession(sessionId) {
|
|
3180
3180
|
const session = this.sessions.get(sessionId);
|
|
3181
|
-
if (session)
|
|
3181
|
+
if (session) try {
|
|
3182
|
+
await session.server.close();
|
|
3183
|
+
} catch (error) {
|
|
3184
|
+
throw new Error(`Failed to close MCP server for session '${sessionId}': ${toErrorMessage$2(error)}`);
|
|
3185
|
+
}
|
|
3182
3186
|
this.sessions.delete(sessionId);
|
|
3183
3187
|
}
|
|
3184
3188
|
hasSession(sessionId) {
|
|
3185
3189
|
return this.sessions.has(sessionId);
|
|
3186
3190
|
}
|
|
3187
|
-
clear() {
|
|
3188
|
-
|
|
3191
|
+
async clear() {
|
|
3192
|
+
try {
|
|
3193
|
+
await Promise.all(Array.from(this.sessions.values()).map(async (session) => {
|
|
3194
|
+
await session.server.close();
|
|
3195
|
+
}));
|
|
3196
|
+
} catch (error) {
|
|
3197
|
+
throw new Error(`Failed to clear sessions: ${toErrorMessage$2(error)}`);
|
|
3198
|
+
}
|
|
3189
3199
|
this.sessions.clear();
|
|
3190
3200
|
}
|
|
3191
3201
|
};
|
|
@@ -3226,7 +3236,7 @@ var HttpTransportHandler = class {
|
|
|
3226
3236
|
adminOptions;
|
|
3227
3237
|
adminRateLimiter = new AdminRateLimiter();
|
|
3228
3238
|
constructor(serverFactory, config, adminOptions) {
|
|
3229
|
-
this.serverFactory =
|
|
3239
|
+
this.serverFactory = serverFactory;
|
|
3230
3240
|
this.app = (0, express.default)();
|
|
3231
3241
|
this.sessionManager = new HttpFullSessionManager();
|
|
3232
3242
|
this.config = {
|
|
@@ -3349,7 +3359,7 @@ var HttpTransportHandler = class {
|
|
|
3349
3359
|
let transport;
|
|
3350
3360
|
if (sessionId && this.sessionManager.hasSession(sessionId)) transport = this.sessionManager.getSession(sessionId).transport;
|
|
3351
3361
|
else if (!sessionId && (0, __modelcontextprotocol_sdk_types_js.isInitializeRequest)(req.body)) {
|
|
3352
|
-
const mcpServer = this.serverFactory();
|
|
3362
|
+
const mcpServer = await this.serverFactory();
|
|
3353
3363
|
transport = new __modelcontextprotocol_sdk_server_streamableHttp_js.StreamableHTTPServerTransport({
|
|
3354
3364
|
sessionIdGenerator: () => (0, node_crypto.randomUUID)(),
|
|
3355
3365
|
enableJsonResponse: true,
|
|
@@ -3357,8 +3367,12 @@ var HttpTransportHandler = class {
|
|
|
3357
3367
|
this.sessionManager.setSession(initializedSessionId, transport, mcpServer);
|
|
3358
3368
|
}
|
|
3359
3369
|
});
|
|
3360
|
-
transport.onclose = () => {
|
|
3361
|
-
if (transport.sessionId)
|
|
3370
|
+
transport.onclose = async () => {
|
|
3371
|
+
if (transport.sessionId) try {
|
|
3372
|
+
await this.sessionManager.deleteSession(transport.sessionId);
|
|
3373
|
+
} catch (error) {
|
|
3374
|
+
console.error(`Failed to clean up session '${transport.sessionId}': ${toErrorMessage$2(error)}`);
|
|
3375
|
+
}
|
|
3362
3376
|
};
|
|
3363
3377
|
try {
|
|
3364
3378
|
await mcpServer.connect(transport);
|
|
@@ -3407,7 +3421,7 @@ var HttpTransportHandler = class {
|
|
|
3407
3421
|
} catch (error) {
|
|
3408
3422
|
throw new Error(`Failed handling MCP DELETE request for session '${sessionId}': ${toErrorMessage$2(error)}`);
|
|
3409
3423
|
}
|
|
3410
|
-
this.sessionManager.deleteSession(sessionId);
|
|
3424
|
+
await this.sessionManager.deleteSession(sessionId);
|
|
3411
3425
|
}
|
|
3412
3426
|
async start() {
|
|
3413
3427
|
try {
|
|
@@ -3430,7 +3444,11 @@ var HttpTransportHandler = class {
|
|
|
3430
3444
|
}
|
|
3431
3445
|
async stop() {
|
|
3432
3446
|
if (!this.server) return;
|
|
3433
|
-
|
|
3447
|
+
try {
|
|
3448
|
+
await this.sessionManager.clear();
|
|
3449
|
+
} catch (error) {
|
|
3450
|
+
throw new Error(`Failed to clear sessions during HTTP transport stop: ${toErrorMessage$2(error)}`);
|
|
3451
|
+
}
|
|
3434
3452
|
const closeServer = (0, node_util.promisify)(this.server.close.bind(this.server));
|
|
3435
3453
|
try {
|
|
3436
3454
|
await closeServer();
|
|
@@ -3767,11 +3785,11 @@ var StdioHttpTransportHandler = class {
|
|
|
3767
3785
|
*/
|
|
3768
3786
|
const RUNTIME_DIR_NAME = "runtimes";
|
|
3769
3787
|
const RUNTIME_FILE_SUFFIX = ".runtime.json";
|
|
3770
|
-
function isObject
|
|
3788
|
+
function isObject(value) {
|
|
3771
3789
|
return typeof value === "object" && value !== null;
|
|
3772
3790
|
}
|
|
3773
3791
|
function isRuntimeStateRecord(value) {
|
|
3774
|
-
if (!isObject
|
|
3792
|
+
if (!isObject(value)) return false;
|
|
3775
3793
|
return typeof value.serverId === "string" && typeof value.host === "string" && typeof value.port === "number" && value.transport === "http" && typeof value.shutdownToken === "string" && typeof value.startedAt === "string" && typeof value.pid === "number" && (value.configPath === void 0 || typeof value.configPath === "string");
|
|
3776
3794
|
}
|
|
3777
3795
|
function toErrorMessage$1(error) {
|
|
@@ -3821,7 +3839,7 @@ var RuntimeStateService = class RuntimeStateService {
|
|
|
3821
3839
|
const parsed = JSON.parse(content);
|
|
3822
3840
|
return isRuntimeStateRecord(parsed) ? parsed : null;
|
|
3823
3841
|
} catch (error) {
|
|
3824
|
-
if (isObject
|
|
3842
|
+
if (isObject(error) && "code" in error && error.code === "ENOENT") return null;
|
|
3825
3843
|
throw new Error(`Failed to read runtime state for server '${serverId}' from '${filePath}': ${toErrorMessage$1(error)}`);
|
|
3826
3844
|
}
|
|
3827
3845
|
}
|
|
@@ -3842,7 +3860,7 @@ var RuntimeStateService = class RuntimeStateService {
|
|
|
3842
3860
|
}
|
|
3843
3861
|
}))).filter((record) => record !== null);
|
|
3844
3862
|
} catch (error) {
|
|
3845
|
-
if (isObject
|
|
3863
|
+
if (isObject(error) && "code" in error && error.code === "ENOENT") return [];
|
|
3846
3864
|
throw new Error(`Failed to list runtime states from '${this.runtimeDir}': ${toErrorMessage$1(error)}`);
|
|
3847
3865
|
}
|
|
3848
3866
|
}
|
|
@@ -3857,18 +3875,105 @@ var RuntimeStateService = class RuntimeStateService {
|
|
|
3857
3875
|
};
|
|
3858
3876
|
|
|
3859
3877
|
//#endregion
|
|
3860
|
-
//#region src/services/StopServerService.ts
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3878
|
+
//#region src/services/StopServerService/constants.ts
|
|
3879
|
+
/**
|
|
3880
|
+
* StopServerService constants.
|
|
3881
|
+
*/
|
|
3882
|
+
/** Maximum time in milliseconds to wait for a shutdown to complete. */
|
|
3883
|
+
const DEFAULT_STOP_TIMEOUT_MS = 5e3;
|
|
3884
|
+
/** Minimum timeout in milliseconds for individual health check requests. */
|
|
3885
|
+
const HEALTH_REQUEST_TIMEOUT_FLOOR_MS = 250;
|
|
3886
|
+
/** Delay in milliseconds between shutdown polling attempts. */
|
|
3887
|
+
const SHUTDOWN_POLL_INTERVAL_MS = 200;
|
|
3888
|
+
/** Path for the runtime health check endpoint. */
|
|
3889
|
+
const HEALTH_CHECK_PATH = "/health";
|
|
3890
|
+
/** Path for the authenticated admin shutdown endpoint. */
|
|
3891
|
+
const ADMIN_SHUTDOWN_PATH = "/admin/shutdown";
|
|
3892
|
+
/** HTTP GET method identifier. */
|
|
3893
|
+
const HTTP_METHOD_GET = "GET";
|
|
3894
|
+
/** HTTP POST method identifier. */
|
|
3895
|
+
const HTTP_METHOD_POST = "POST";
|
|
3896
|
+
/** HTTP header name for bearer token authorization. */
|
|
3897
|
+
const AUTHORIZATION_HEADER_NAME = "Authorization";
|
|
3898
|
+
/** Prefix for bearer token values in the Authorization header. */
|
|
3899
|
+
const BEARER_TOKEN_PREFIX = "Bearer ";
|
|
3900
|
+
/** HTTP protocol scheme prefix for URL construction. */
|
|
3901
|
+
const HTTP_PROTOCOL = "http://";
|
|
3902
|
+
/** Separator between host and port in URL construction. */
|
|
3903
|
+
const URL_PORT_SEPARATOR = ":";
|
|
3904
|
+
/** Loopback hostname. */
|
|
3905
|
+
const LOOPBACK_HOST_LOCALHOST = "localhost";
|
|
3906
|
+
/** IPv4 loopback address. */
|
|
3907
|
+
const LOOPBACK_HOST_IPV4 = "127.0.0.1";
|
|
3908
|
+
/** IPv6 loopback address. */
|
|
3909
|
+
const LOOPBACK_HOST_IPV6 = "::1";
|
|
3910
|
+
/** Hosts that are safe to send admin requests to (loopback only). */
|
|
3911
|
+
const ALLOWED_HOSTS = new Set([
|
|
3912
|
+
LOOPBACK_HOST_LOCALHOST,
|
|
3913
|
+
LOOPBACK_HOST_IPV4,
|
|
3914
|
+
LOOPBACK_HOST_IPV6
|
|
3915
|
+
]);
|
|
3916
|
+
/** Expected status value in a healthy runtime response. */
|
|
3917
|
+
const HEALTH_STATUS_OK = "ok";
|
|
3918
|
+
/** Expected transport value in a healthy runtime response. */
|
|
3919
|
+
const HEALTH_TRANSPORT_HTTP = "http";
|
|
3920
|
+
/** Property key for status field in health responses. */
|
|
3921
|
+
const KEY_STATUS = "status";
|
|
3922
|
+
/** Property key for transport field in health responses. */
|
|
3923
|
+
const KEY_TRANSPORT = "transport";
|
|
3924
|
+
/** Property key for serverId field in runtime responses. */
|
|
3925
|
+
const KEY_SERVER_ID = "serverId";
|
|
3926
|
+
/** Property key for ok field in shutdown responses. */
|
|
3927
|
+
const KEY_OK = "ok";
|
|
3928
|
+
/** Property key for message field in shutdown responses. */
|
|
3929
|
+
const KEY_MESSAGE = "message";
|
|
3930
|
+
|
|
3931
|
+
//#endregion
|
|
3932
|
+
//#region src/services/StopServerService/types.ts
|
|
3933
|
+
/**
|
|
3934
|
+
* Safely cast a non-null object to a string-keyed record for property access.
|
|
3935
|
+
* @param value - Object value already verified as non-null
|
|
3936
|
+
* @returns The same value typed as a record
|
|
3937
|
+
*/
|
|
3938
|
+
function toRecord(value) {
|
|
3939
|
+
return value;
|
|
3866
3940
|
}
|
|
3941
|
+
/**
|
|
3942
|
+
* Type guard for health responses.
|
|
3943
|
+
* @param value - Candidate payload to validate
|
|
3944
|
+
* @returns True when payload matches health response shape
|
|
3945
|
+
*/
|
|
3867
3946
|
function isHealthResponse(value) {
|
|
3868
|
-
|
|
3947
|
+
if (typeof value !== "object" || value === null) return false;
|
|
3948
|
+
const record = toRecord(value);
|
|
3949
|
+
return KEY_STATUS in record && record[KEY_STATUS] === HEALTH_STATUS_OK && KEY_TRANSPORT in record && record[KEY_TRANSPORT] === HEALTH_TRANSPORT_HTTP && (!(KEY_SERVER_ID in record) || record[KEY_SERVER_ID] === void 0 || typeof record[KEY_SERVER_ID] === "string");
|
|
3869
3950
|
}
|
|
3951
|
+
/**
|
|
3952
|
+
* Type guard for shutdown responses.
|
|
3953
|
+
* @param value - Candidate payload to validate
|
|
3954
|
+
* @returns True when payload matches shutdown response shape
|
|
3955
|
+
*/
|
|
3870
3956
|
function isShutdownResponse(value) {
|
|
3871
|
-
|
|
3957
|
+
if (typeof value !== "object" || value === null) return false;
|
|
3958
|
+
const record = toRecord(value);
|
|
3959
|
+
return KEY_OK in record && typeof record[KEY_OK] === "boolean" && KEY_MESSAGE in record && typeof record[KEY_MESSAGE] === "string" && (!(KEY_SERVER_ID in record) || record[KEY_SERVER_ID] === void 0 || typeof record[KEY_SERVER_ID] === "string");
|
|
3960
|
+
}
|
|
3961
|
+
|
|
3962
|
+
//#endregion
|
|
3963
|
+
//#region src/services/StopServerService/StopServerService.ts
|
|
3964
|
+
/**
|
|
3965
|
+
* Format runtime endpoint URL after validating the host is a loopback address.
|
|
3966
|
+
* Rejects non-loopback hosts to prevent SSRF via tampered runtime state files.
|
|
3967
|
+
* @param runtime - Runtime record to format
|
|
3968
|
+
* @param path - Request path to append
|
|
3969
|
+
* @returns Full runtime URL
|
|
3970
|
+
*/
|
|
3971
|
+
function buildRuntimeUrl(runtime, path) {
|
|
3972
|
+
if (!ALLOWED_HOSTS.has(runtime.host)) throw new Error(`Refusing to connect to non-loopback host '${runtime.host}'. Only ${Array.from(ALLOWED_HOSTS).join(", ")} are allowed.`);
|
|
3973
|
+
return `${HTTP_PROTOCOL}${runtime.host}${URL_PORT_SEPARATOR}${runtime.port}${path}`;
|
|
3974
|
+
}
|
|
3975
|
+
function toErrorMessage(error) {
|
|
3976
|
+
return error instanceof Error ? error.message : String(error);
|
|
3872
3977
|
}
|
|
3873
3978
|
function sleep(delayMs) {
|
|
3874
3979
|
return new Promise((resolve$2) => {
|
|
@@ -3889,7 +3994,7 @@ var StopServerService = class {
|
|
|
3889
3994
|
* @returns Stop result payload
|
|
3890
3995
|
*/
|
|
3891
3996
|
async stop(request) {
|
|
3892
|
-
const timeoutMs = request.timeoutMs ??
|
|
3997
|
+
const timeoutMs = request.timeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
|
|
3893
3998
|
const runtime = await this.resolveRuntime(request);
|
|
3894
3999
|
const health = await this.fetchHealth(runtime, timeoutMs);
|
|
3895
4000
|
if (!health.reachable) {
|
|
@@ -3935,7 +4040,7 @@ var StopServerService = class {
|
|
|
3935
4040
|
*/
|
|
3936
4041
|
async fetchHealth(runtime, timeoutMs) {
|
|
3937
4042
|
try {
|
|
3938
|
-
const response = await this.fetchWithTimeout(
|
|
4043
|
+
const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, HEALTH_CHECK_PATH), { method: HTTP_METHOD_GET }, timeoutMs);
|
|
3939
4044
|
if (!response.ok) return { reachable: false };
|
|
3940
4045
|
const payload = await response.json();
|
|
3941
4046
|
if (!isHealthResponse(payload)) throw new Error("Received invalid health response payload.");
|
|
@@ -3955,9 +4060,9 @@ var StopServerService = class {
|
|
|
3955
4060
|
* @returns Parsed shutdown response payload
|
|
3956
4061
|
*/
|
|
3957
4062
|
async requestShutdown(runtime, shutdownToken, timeoutMs) {
|
|
3958
|
-
const response = await this.fetchWithTimeout(
|
|
3959
|
-
method:
|
|
3960
|
-
headers: {
|
|
4063
|
+
const response = await this.fetchWithTimeout(buildRuntimeUrl(runtime, ADMIN_SHUTDOWN_PATH), {
|
|
4064
|
+
method: HTTP_METHOD_POST,
|
|
4065
|
+
headers: { [AUTHORIZATION_HEADER_NAME]: `${BEARER_TOKEN_PREFIX}${shutdownToken}` }
|
|
3961
4066
|
}, timeoutMs);
|
|
3962
4067
|
const payload = await response.json();
|
|
3963
4068
|
if (!isShutdownResponse(payload)) throw new Error("Received invalid shutdown response payload.");
|
|
@@ -3973,8 +4078,8 @@ var StopServerService = class {
|
|
|
3973
4078
|
async waitForShutdown(runtime, timeoutMs) {
|
|
3974
4079
|
const deadline = Date.now() + timeoutMs;
|
|
3975
4080
|
while (Date.now() < deadline) {
|
|
3976
|
-
if (!(await this.fetchHealth(runtime, Math.max(
|
|
3977
|
-
await sleep(
|
|
4081
|
+
if (!(await this.fetchHealth(runtime, Math.max(HEALTH_REQUEST_TIMEOUT_FLOOR_MS, deadline - Date.now()))).reachable) return;
|
|
4082
|
+
await sleep(SHUTDOWN_POLL_INTERVAL_MS);
|
|
3978
4083
|
}
|
|
3979
4084
|
throw new Error(`Timed out waiting for runtime '${runtime.serverId}' to stop at http://${runtime.host}:${runtime.port}.`);
|
|
3980
4085
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agiflowai/one-mcp",
|
|
3
3
|
"description": "One MCP server package",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.15",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"js-yaml": "^4.1.0",
|
|
28
28
|
"liquidjs": "^10.21.0",
|
|
29
29
|
"zod": "^3.24.1",
|
|
30
|
-
"@agiflowai/aicode-utils": "1.0.
|
|
30
|
+
"@agiflowai/aicode-utils": "1.0.20"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/express": "^5.0.0",
|