@agimon-ai/mcp-proxy 0.10.2 → 0.10.4
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 +9 -2
- package/dist/cli.mjs +9 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-pCtALj-B.mjs → src-Bw4PNDZ8.mjs} +50 -7
- package/dist/{src-DMlOlvPm.cjs → src-DRpIyfzb.cjs} +50 -7
- package/package.json +3 -3
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-DRpIyfzb.cjs");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_fs_promises = require("node:fs/promises");
|
|
5
5
|
let js_yaml = require("js-yaml");
|
|
@@ -1224,6 +1224,10 @@ async function resolveStdioHttpEndpoint(config, options, resolvedConfigPath) {
|
|
|
1224
1224
|
ownedRuntimeServerId: runtime.reusedExistingRuntime ? void 0 : runtime.serverId
|
|
1225
1225
|
};
|
|
1226
1226
|
}
|
|
1227
|
+
async function rediscoverStdioHttpEndpoint(config, options, resolvedConfigPath) {
|
|
1228
|
+
const { endpoint } = await resolveStdioHttpEndpoint(config, options, resolvedConfigPath);
|
|
1229
|
+
return endpoint;
|
|
1230
|
+
}
|
|
1227
1231
|
async function startStdioHttpTransport(config, options, resolvedConfigPath, proxyDefaults) {
|
|
1228
1232
|
let ownedRuntimeServerId;
|
|
1229
1233
|
const keepAlive = proxyDefaults?.keepAlive ?? false;
|
|
@@ -1231,7 +1235,10 @@ async function startStdioHttpTransport(config, options, resolvedConfigPath, prox
|
|
|
1231
1235
|
const resolvedEndpoint = await resolveStdioHttpEndpoint(config, options, resolvedConfigPath);
|
|
1232
1236
|
ownedRuntimeServerId = resolvedEndpoint.ownedRuntimeServerId;
|
|
1233
1237
|
const { endpoint } = resolvedEndpoint;
|
|
1234
|
-
await startServer(new require_src.StdioHttpTransportHandler({
|
|
1238
|
+
await startServer(new require_src.StdioHttpTransportHandler({
|
|
1239
|
+
endpoint,
|
|
1240
|
+
resolveEndpoint: async () => await rediscoverStdioHttpEndpoint(config, options, resolvedConfigPath)
|
|
1241
|
+
}, createStdioSafeLogger()), async () => {
|
|
1235
1242
|
if (keepAlive || !ownedRuntimeServerId) return;
|
|
1236
1243
|
await new require_src.StopServerService().stop({
|
|
1237
1244
|
serverId: ownedRuntimeServerId,
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as DefinitionsCacheService, D as version, T as findConfigFile, b as RuntimeStateService, d as StdioHttpTransportHandler, f as StdioTransportHandler, m as HttpTransportHandler, n as createServer, o as createProxyIoCContainer, p as SseTransportHandler, r as createSessionServer, t as TRANSPORT_MODE, u as initializeSharedServices, v as StopServerService, w as generateServerId } from "./src-
|
|
2
|
+
import { C as DefinitionsCacheService, D as version, T as findConfigFile, b as RuntimeStateService, d as StdioHttpTransportHandler, f as StdioTransportHandler, m as HttpTransportHandler, n as createServer, o as createProxyIoCContainer, p as SseTransportHandler, r as createSessionServer, t as TRANSPORT_MODE, u as initializeSharedServices, v as StopServerService, w as generateServerId } from "./src-Bw4PNDZ8.mjs";
|
|
3
3
|
import { constants, existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { access, writeFile } from "node:fs/promises";
|
|
5
5
|
import yaml from "js-yaml";
|
|
@@ -1222,6 +1222,10 @@ async function resolveStdioHttpEndpoint(config, options, resolvedConfigPath) {
|
|
|
1222
1222
|
ownedRuntimeServerId: runtime.reusedExistingRuntime ? void 0 : runtime.serverId
|
|
1223
1223
|
};
|
|
1224
1224
|
}
|
|
1225
|
+
async function rediscoverStdioHttpEndpoint(config, options, resolvedConfigPath) {
|
|
1226
|
+
const { endpoint } = await resolveStdioHttpEndpoint(config, options, resolvedConfigPath);
|
|
1227
|
+
return endpoint;
|
|
1228
|
+
}
|
|
1225
1229
|
async function startStdioHttpTransport(config, options, resolvedConfigPath, proxyDefaults) {
|
|
1226
1230
|
let ownedRuntimeServerId;
|
|
1227
1231
|
const keepAlive = proxyDefaults?.keepAlive ?? false;
|
|
@@ -1229,7 +1233,10 @@ async function startStdioHttpTransport(config, options, resolvedConfigPath, prox
|
|
|
1229
1233
|
const resolvedEndpoint = await resolveStdioHttpEndpoint(config, options, resolvedConfigPath);
|
|
1230
1234
|
ownedRuntimeServerId = resolvedEndpoint.ownedRuntimeServerId;
|
|
1231
1235
|
const { endpoint } = resolvedEndpoint;
|
|
1232
|
-
await startServer(new StdioHttpTransportHandler({
|
|
1236
|
+
await startServer(new StdioHttpTransportHandler({
|
|
1237
|
+
endpoint,
|
|
1238
|
+
resolveEndpoint: async () => await rediscoverStdioHttpEndpoint(config, options, resolvedConfigPath)
|
|
1239
|
+
}, createStdioSafeLogger()), async () => {
|
|
1233
1240
|
if (keepAlive || !ownedRuntimeServerId) return;
|
|
1234
1241
|
await new StopServerService().stop({
|
|
1235
1242
|
serverId: ownedRuntimeServerId,
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_src = require("./src-
|
|
2
|
+
const require_src = require("./src-DRpIyfzb.cjs");
|
|
3
3
|
exports.ConfigFetcherService = require_src.ConfigFetcherService;
|
|
4
4
|
exports.DefinitionsCacheService = require_src.DefinitionsCacheService;
|
|
5
5
|
exports.DescribeToolsTool = require_src.DescribeToolsTool;
|
package/dist/index.d.cts
CHANGED
|
@@ -1187,6 +1187,7 @@ declare class StdioTransportHandler implements TransportHandler {
|
|
|
1187
1187
|
//#region src/transports/stdio-http.d.ts
|
|
1188
1188
|
interface StdioHttpProxyTransportConfig {
|
|
1189
1189
|
endpoint: URL;
|
|
1190
|
+
resolveEndpoint?: () => Promise<URL>;
|
|
1190
1191
|
}
|
|
1191
1192
|
/**
|
|
1192
1193
|
* Transport that serves MCP over stdio and forwards MCP requests to an HTTP endpoint.
|
|
@@ -1194,7 +1195,8 @@ interface StdioHttpProxyTransportConfig {
|
|
|
1194
1195
|
* connection is lost (e.g. backend crash + restart).
|
|
1195
1196
|
*/
|
|
1196
1197
|
declare class StdioHttpTransportHandler implements TransportHandler {
|
|
1197
|
-
private
|
|
1198
|
+
private endpoint;
|
|
1199
|
+
private readonly resolveEndpoint?;
|
|
1198
1200
|
private stdioProxyServer;
|
|
1199
1201
|
private stdioTransport;
|
|
1200
1202
|
private httpClient;
|
package/dist/index.d.mts
CHANGED
|
@@ -1187,6 +1187,7 @@ declare class StdioTransportHandler implements TransportHandler {
|
|
|
1187
1187
|
//#region src/transports/stdio-http.d.ts
|
|
1188
1188
|
interface StdioHttpProxyTransportConfig {
|
|
1189
1189
|
endpoint: URL;
|
|
1190
|
+
resolveEndpoint?: () => Promise<URL>;
|
|
1190
1191
|
}
|
|
1191
1192
|
/**
|
|
1192
1193
|
* Transport that serves MCP over stdio and forwards MCP requests to an HTTP endpoint.
|
|
@@ -1194,7 +1195,8 @@ interface StdioHttpProxyTransportConfig {
|
|
|
1194
1195
|
* connection is lost (e.g. backend crash + restart).
|
|
1195
1196
|
*/
|
|
1196
1197
|
declare class StdioHttpTransportHandler implements TransportHandler {
|
|
1197
|
-
private
|
|
1198
|
+
private endpoint;
|
|
1199
|
+
private readonly resolveEndpoint?;
|
|
1198
1200
|
private stdioProxyServer;
|
|
1199
1201
|
private stdioTransport;
|
|
1200
1202
|
private httpClient;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as DefinitionsCacheService, E as ConfigFetcherService, S as createProxyLogger, T as findConfigFile, _ as DescribeToolsTool, a as createProxyContainer, b as RuntimeStateService, c as createStdioHttpTransportHandler, d as StdioHttpTransportHandler, f as StdioTransportHandler, g as SearchListToolsTool, h as UseToolTool, i as createHttpTransportHandler, l as createStdioTransportHandler, m as HttpTransportHandler, n as createServer, p as SseTransportHandler, r as createSessionServer, s as createSseTransportHandler, t as TRANSPORT_MODE, u as initializeSharedServices, v as StopServerService, w as generateServerId, x as McpClientManagerService, y as SkillService } from "./src-
|
|
1
|
+
import { C as DefinitionsCacheService, E as ConfigFetcherService, S as createProxyLogger, T as findConfigFile, _ as DescribeToolsTool, a as createProxyContainer, b as RuntimeStateService, c as createStdioHttpTransportHandler, d as StdioHttpTransportHandler, f as StdioTransportHandler, g as SearchListToolsTool, h as UseToolTool, i as createHttpTransportHandler, l as createStdioTransportHandler, m as HttpTransportHandler, n as createServer, p as SseTransportHandler, r as createSessionServer, s as createSseTransportHandler, t as TRANSPORT_MODE, u as initializeSharedServices, v as StopServerService, w as generateServerId, x as McpClientManagerService, y as SkillService } from "./src-Bw4PNDZ8.mjs";
|
|
2
2
|
export { ConfigFetcherService, DefinitionsCacheService, DescribeToolsTool, HttpTransportHandler, McpClientManagerService, RuntimeStateService, SearchListToolsTool, SkillService, SseTransportHandler, StdioHttpTransportHandler, StdioTransportHandler, StopServerService, TRANSPORT_MODE, UseToolTool, createHttpTransportHandler, createProxyContainer, createProxyLogger, createServer, createSessionServer, createSseTransportHandler, createStdioHttpTransportHandler, createStdioTransportHandler, findConfigFile, generateServerId, initializeSharedServices };
|
|
@@ -25,7 +25,7 @@ import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
|
25
25
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
26
26
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
27
27
|
//#region package.json
|
|
28
|
-
var version = "0.10.
|
|
28
|
+
var version = "0.10.3";
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/utils/mcpConfigSchema.ts
|
|
31
31
|
/**
|
|
@@ -1521,14 +1521,14 @@ const PROCESS_REGISTRY_SERVICE_TYPE = "tool";
|
|
|
1521
1521
|
* Checks if an error is a session-related error from an HTTP backend
|
|
1522
1522
|
* (e.g., downstream server restarted and no longer recognizes the session ID).
|
|
1523
1523
|
*/
|
|
1524
|
-
function isSessionError(error) {
|
|
1525
|
-
return getErrorChain(error).some(({ message, code }) => {
|
|
1524
|
+
function isSessionError$1(error) {
|
|
1525
|
+
return getErrorChain$1(error).some(({ message, code }) => {
|
|
1526
1526
|
const normalizedMessage = message.toLowerCase();
|
|
1527
1527
|
const normalizedCode = code?.toLowerCase();
|
|
1528
1528
|
return normalizedMessage.includes("unknown session") || normalizedMessage.includes("session not found") || normalizedMessage.includes("transport closed") || normalizedMessage.includes("connection closed") || normalizedMessage.includes("socket hang up") || normalizedMessage.includes("fetch failed") || normalizedCode === "econnreset";
|
|
1529
1529
|
});
|
|
1530
1530
|
}
|
|
1531
|
-
function getErrorChain(error) {
|
|
1531
|
+
function getErrorChain$1(error) {
|
|
1532
1532
|
const visited = /* @__PURE__ */ new Set();
|
|
1533
1533
|
const chain = [];
|
|
1534
1534
|
let current = error;
|
|
@@ -1632,14 +1632,14 @@ var McpClient = class {
|
|
|
1632
1632
|
while (true) try {
|
|
1633
1633
|
return await operation();
|
|
1634
1634
|
} catch (error) {
|
|
1635
|
-
if (!this.reconnectFn || !isSessionError(error) || recoveryAttempts >= 2) throw error;
|
|
1635
|
+
if (!this.reconnectFn || !isSessionError$1(error) || recoveryAttempts >= 2) throw error;
|
|
1636
1636
|
recoveryAttempts += 1;
|
|
1637
1637
|
this.logger.warn(`Session error for ${this.serverName}, reconnecting: ${error instanceof Error ? error.message : String(error)}`);
|
|
1638
1638
|
while (true) try {
|
|
1639
1639
|
await this.reconnectClient();
|
|
1640
1640
|
break;
|
|
1641
1641
|
} catch (reconnectError) {
|
|
1642
|
-
if (!isSessionError(reconnectError) || recoveryAttempts >= 2) throw reconnectError;
|
|
1642
|
+
if (!isSessionError$1(reconnectError) || recoveryAttempts >= 2) throw reconnectError;
|
|
1643
1643
|
this.logger.warn(`Reconnect attempt ${String(recoveryAttempts)} for ${this.serverName} failed, retrying: ${reconnectError instanceof Error ? reconnectError.message : String(reconnectError)}`);
|
|
1644
1644
|
recoveryAttempts += 1;
|
|
1645
1645
|
}
|
|
@@ -4306,6 +4306,46 @@ function isConnectionError(error) {
|
|
|
4306
4306
|
const message = error.message.toLowerCase();
|
|
4307
4307
|
return CONNECTION_ERROR_PATTERNS.some((pattern) => message.includes(pattern));
|
|
4308
4308
|
}
|
|
4309
|
+
function getErrorChain(error) {
|
|
4310
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4311
|
+
const chain = [];
|
|
4312
|
+
let current = error;
|
|
4313
|
+
while (current && !visited.has(current)) {
|
|
4314
|
+
visited.add(current);
|
|
4315
|
+
if (current instanceof Error) {
|
|
4316
|
+
const currentWithCode = current;
|
|
4317
|
+
chain.push({
|
|
4318
|
+
message: current.message,
|
|
4319
|
+
code: currentWithCode.code
|
|
4320
|
+
});
|
|
4321
|
+
current = currentWithCode.cause;
|
|
4322
|
+
continue;
|
|
4323
|
+
}
|
|
4324
|
+
if (typeof current === "object") {
|
|
4325
|
+
const currentRecord = current;
|
|
4326
|
+
chain.push({
|
|
4327
|
+
message: typeof currentRecord.message === "string" ? currentRecord.message : String(current),
|
|
4328
|
+
code: typeof currentRecord.code === "string" ? currentRecord.code : void 0
|
|
4329
|
+
});
|
|
4330
|
+
current = currentRecord.cause;
|
|
4331
|
+
continue;
|
|
4332
|
+
}
|
|
4333
|
+
chain.push({ message: String(current) });
|
|
4334
|
+
break;
|
|
4335
|
+
}
|
|
4336
|
+
return chain;
|
|
4337
|
+
}
|
|
4338
|
+
/**
|
|
4339
|
+
* Checks if an error is a session-related error from an HTTP backend
|
|
4340
|
+
* (e.g., downstream server restarted and no longer recognizes the session ID).
|
|
4341
|
+
*/
|
|
4342
|
+
function isSessionError(error) {
|
|
4343
|
+
return getErrorChain(error).some(({ message, code }) => {
|
|
4344
|
+
const normalizedMessage = message.toLowerCase();
|
|
4345
|
+
const normalizedCode = code?.toLowerCase();
|
|
4346
|
+
return normalizedMessage.includes("unknown session") || normalizedMessage.includes("session not found") || normalizedMessage.includes("transport closed") || normalizedMessage.includes("connection closed") || normalizedMessage.includes("socket hang up") || normalizedMessage.includes("fetch failed") || normalizedCode === "econnreset";
|
|
4347
|
+
});
|
|
4348
|
+
}
|
|
4309
4349
|
/**
|
|
4310
4350
|
* Transport that serves MCP over stdio and forwards MCP requests to an HTTP endpoint.
|
|
4311
4351
|
* Automatically reconnects to the HTTP backend with exponential backoff when the
|
|
@@ -4313,6 +4353,7 @@ function isConnectionError(error) {
|
|
|
4313
4353
|
*/
|
|
4314
4354
|
var StdioHttpTransportHandler = class {
|
|
4315
4355
|
endpoint;
|
|
4356
|
+
resolveEndpoint;
|
|
4316
4357
|
stdioProxyServer = null;
|
|
4317
4358
|
stdioTransport = null;
|
|
4318
4359
|
httpClient = null;
|
|
@@ -4322,6 +4363,7 @@ var StdioHttpTransportHandler = class {
|
|
|
4322
4363
|
RECONNECT_MAX_MS = 3e4;
|
|
4323
4364
|
constructor(config, logger = console) {
|
|
4324
4365
|
this.endpoint = config.endpoint;
|
|
4366
|
+
this.resolveEndpoint = config.resolveEndpoint;
|
|
4325
4367
|
this.logger = logger;
|
|
4326
4368
|
}
|
|
4327
4369
|
async start() {
|
|
@@ -4392,6 +4434,7 @@ var StdioHttpTransportHandler = class {
|
|
|
4392
4434
|
const delay = Math.min(this.RECONNECT_BASE_MS * 2 ** attempt, this.RECONNECT_MAX_MS);
|
|
4393
4435
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
4394
4436
|
try {
|
|
4437
|
+
if (this.resolveEndpoint) this.endpoint = await this.resolveEndpoint();
|
|
4395
4438
|
await this.httpClient?.close().catch(() => void 0);
|
|
4396
4439
|
const client = await this.createAndConnectClient();
|
|
4397
4440
|
this.httpClient = client;
|
|
@@ -4409,7 +4452,7 @@ var StdioHttpTransportHandler = class {
|
|
|
4409
4452
|
try {
|
|
4410
4453
|
return await fn();
|
|
4411
4454
|
} catch (error) {
|
|
4412
|
-
if (isConnectionError(error)) {
|
|
4455
|
+
if (isConnectionError(error) || isSessionError(error)) {
|
|
4413
4456
|
await this.reconnectWithBackoff();
|
|
4414
4457
|
return await fn();
|
|
4415
4458
|
}
|
|
@@ -48,7 +48,7 @@ let _modelcontextprotocol_sdk_server_sse_js = require("@modelcontextprotocol/sdk
|
|
|
48
48
|
let _modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
49
49
|
let _modelcontextprotocol_sdk_server_index_js = require("@modelcontextprotocol/sdk/server/index.js");
|
|
50
50
|
//#region package.json
|
|
51
|
-
var version = "0.10.
|
|
51
|
+
var version = "0.10.3";
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region src/utils/mcpConfigSchema.ts
|
|
54
54
|
/**
|
|
@@ -1544,14 +1544,14 @@ const PROCESS_REGISTRY_SERVICE_TYPE = "tool";
|
|
|
1544
1544
|
* Checks if an error is a session-related error from an HTTP backend
|
|
1545
1545
|
* (e.g., downstream server restarted and no longer recognizes the session ID).
|
|
1546
1546
|
*/
|
|
1547
|
-
function isSessionError(error) {
|
|
1548
|
-
return getErrorChain(error).some(({ message, code }) => {
|
|
1547
|
+
function isSessionError$1(error) {
|
|
1548
|
+
return getErrorChain$1(error).some(({ message, code }) => {
|
|
1549
1549
|
const normalizedMessage = message.toLowerCase();
|
|
1550
1550
|
const normalizedCode = code?.toLowerCase();
|
|
1551
1551
|
return normalizedMessage.includes("unknown session") || normalizedMessage.includes("session not found") || normalizedMessage.includes("transport closed") || normalizedMessage.includes("connection closed") || normalizedMessage.includes("socket hang up") || normalizedMessage.includes("fetch failed") || normalizedCode === "econnreset";
|
|
1552
1552
|
});
|
|
1553
1553
|
}
|
|
1554
|
-
function getErrorChain(error) {
|
|
1554
|
+
function getErrorChain$1(error) {
|
|
1555
1555
|
const visited = /* @__PURE__ */ new Set();
|
|
1556
1556
|
const chain = [];
|
|
1557
1557
|
let current = error;
|
|
@@ -1655,14 +1655,14 @@ var McpClient = class {
|
|
|
1655
1655
|
while (true) try {
|
|
1656
1656
|
return await operation();
|
|
1657
1657
|
} catch (error) {
|
|
1658
|
-
if (!this.reconnectFn || !isSessionError(error) || recoveryAttempts >= 2) throw error;
|
|
1658
|
+
if (!this.reconnectFn || !isSessionError$1(error) || recoveryAttempts >= 2) throw error;
|
|
1659
1659
|
recoveryAttempts += 1;
|
|
1660
1660
|
this.logger.warn(`Session error for ${this.serverName}, reconnecting: ${error instanceof Error ? error.message : String(error)}`);
|
|
1661
1661
|
while (true) try {
|
|
1662
1662
|
await this.reconnectClient();
|
|
1663
1663
|
break;
|
|
1664
1664
|
} catch (reconnectError) {
|
|
1665
|
-
if (!isSessionError(reconnectError) || recoveryAttempts >= 2) throw reconnectError;
|
|
1665
|
+
if (!isSessionError$1(reconnectError) || recoveryAttempts >= 2) throw reconnectError;
|
|
1666
1666
|
this.logger.warn(`Reconnect attempt ${String(recoveryAttempts)} for ${this.serverName} failed, retrying: ${reconnectError instanceof Error ? reconnectError.message : String(reconnectError)}`);
|
|
1667
1667
|
recoveryAttempts += 1;
|
|
1668
1668
|
}
|
|
@@ -4329,6 +4329,46 @@ function isConnectionError(error) {
|
|
|
4329
4329
|
const message = error.message.toLowerCase();
|
|
4330
4330
|
return CONNECTION_ERROR_PATTERNS.some((pattern) => message.includes(pattern));
|
|
4331
4331
|
}
|
|
4332
|
+
function getErrorChain(error) {
|
|
4333
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4334
|
+
const chain = [];
|
|
4335
|
+
let current = error;
|
|
4336
|
+
while (current && !visited.has(current)) {
|
|
4337
|
+
visited.add(current);
|
|
4338
|
+
if (current instanceof Error) {
|
|
4339
|
+
const currentWithCode = current;
|
|
4340
|
+
chain.push({
|
|
4341
|
+
message: current.message,
|
|
4342
|
+
code: currentWithCode.code
|
|
4343
|
+
});
|
|
4344
|
+
current = currentWithCode.cause;
|
|
4345
|
+
continue;
|
|
4346
|
+
}
|
|
4347
|
+
if (typeof current === "object") {
|
|
4348
|
+
const currentRecord = current;
|
|
4349
|
+
chain.push({
|
|
4350
|
+
message: typeof currentRecord.message === "string" ? currentRecord.message : String(current),
|
|
4351
|
+
code: typeof currentRecord.code === "string" ? currentRecord.code : void 0
|
|
4352
|
+
});
|
|
4353
|
+
current = currentRecord.cause;
|
|
4354
|
+
continue;
|
|
4355
|
+
}
|
|
4356
|
+
chain.push({ message: String(current) });
|
|
4357
|
+
break;
|
|
4358
|
+
}
|
|
4359
|
+
return chain;
|
|
4360
|
+
}
|
|
4361
|
+
/**
|
|
4362
|
+
* Checks if an error is a session-related error from an HTTP backend
|
|
4363
|
+
* (e.g., downstream server restarted and no longer recognizes the session ID).
|
|
4364
|
+
*/
|
|
4365
|
+
function isSessionError(error) {
|
|
4366
|
+
return getErrorChain(error).some(({ message, code }) => {
|
|
4367
|
+
const normalizedMessage = message.toLowerCase();
|
|
4368
|
+
const normalizedCode = code?.toLowerCase();
|
|
4369
|
+
return normalizedMessage.includes("unknown session") || normalizedMessage.includes("session not found") || normalizedMessage.includes("transport closed") || normalizedMessage.includes("connection closed") || normalizedMessage.includes("socket hang up") || normalizedMessage.includes("fetch failed") || normalizedCode === "econnreset";
|
|
4370
|
+
});
|
|
4371
|
+
}
|
|
4332
4372
|
/**
|
|
4333
4373
|
* Transport that serves MCP over stdio and forwards MCP requests to an HTTP endpoint.
|
|
4334
4374
|
* Automatically reconnects to the HTTP backend with exponential backoff when the
|
|
@@ -4336,6 +4376,7 @@ function isConnectionError(error) {
|
|
|
4336
4376
|
*/
|
|
4337
4377
|
var StdioHttpTransportHandler = class {
|
|
4338
4378
|
endpoint;
|
|
4379
|
+
resolveEndpoint;
|
|
4339
4380
|
stdioProxyServer = null;
|
|
4340
4381
|
stdioTransport = null;
|
|
4341
4382
|
httpClient = null;
|
|
@@ -4345,6 +4386,7 @@ var StdioHttpTransportHandler = class {
|
|
|
4345
4386
|
RECONNECT_MAX_MS = 3e4;
|
|
4346
4387
|
constructor(config, logger = console) {
|
|
4347
4388
|
this.endpoint = config.endpoint;
|
|
4389
|
+
this.resolveEndpoint = config.resolveEndpoint;
|
|
4348
4390
|
this.logger = logger;
|
|
4349
4391
|
}
|
|
4350
4392
|
async start() {
|
|
@@ -4415,6 +4457,7 @@ var StdioHttpTransportHandler = class {
|
|
|
4415
4457
|
const delay = Math.min(this.RECONNECT_BASE_MS * 2 ** attempt, this.RECONNECT_MAX_MS);
|
|
4416
4458
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
4417
4459
|
try {
|
|
4460
|
+
if (this.resolveEndpoint) this.endpoint = await this.resolveEndpoint();
|
|
4418
4461
|
await this.httpClient?.close().catch(() => void 0);
|
|
4419
4462
|
const client = await this.createAndConnectClient();
|
|
4420
4463
|
this.httpClient = client;
|
|
@@ -4432,7 +4475,7 @@ var StdioHttpTransportHandler = class {
|
|
|
4432
4475
|
try {
|
|
4433
4476
|
return await fn();
|
|
4434
4477
|
} catch (error) {
|
|
4435
|
-
if (isConnectionError(error)) {
|
|
4478
|
+
if (isConnectionError(error) || isSessionError(error)) {
|
|
4436
4479
|
await this.reconnectWithBackoff();
|
|
4437
4480
|
return await fn();
|
|
4438
4481
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/mcp-proxy",
|
|
3
3
|
"description": "MCP proxy server package",
|
|
4
|
-
"version": "0.10.
|
|
4
|
+
"version": "0.10.4",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"zod": "4.3.6",
|
|
31
31
|
"@agimon-ai/foundation-process-registry": "0.8.0",
|
|
32
32
|
"@agimon-ai/log-sink-mcp": "0.8.0",
|
|
33
|
-
"@agimon-ai/foundation-
|
|
34
|
-
"@agimon-ai/foundation-
|
|
33
|
+
"@agimon-ai/foundation-port-registry": "0.8.0",
|
|
34
|
+
"@agimon-ai/foundation-validator": "0.5.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/js-yaml": "4.0.9",
|