Skip to content

Commit d738f86

Browse files
committed
perf: force sse reconnect when calling backend tools
1 parent e20a701 commit d738f86

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

src/mcp-proxy.ts

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -463,38 +463,39 @@ export const createServer = async () => {
463463

464464
// Loop includes the initial attempt (attempt 0) plus maxRetries
465465
for (let attempt = 0; attempt <= maxRetries; attempt++) {
466-
if (attempt > 0) {
467-
const delay = retryDelayBaseMs * Math.pow(2, attempt - 1) + (Math.random() * retryDelayBaseMs * 0.5);
468-
logger.log(`Tool call failed for '${requestedExposedName}'. Attempt ${attempt}/${maxRetries}. Retrying in ${delay.toFixed(0)}ms...`);
469-
await sleep(delay);
470-
466+
if (attempt >= 0) {
467+
if (attempt > 0) {
468+
const delay = retryDelayBaseMs * Math.pow(2, attempt - 1) + (Math.random() * retryDelayBaseMs * 0.5);
469+
logger.log(`Tool call failed for '${requestedExposedName}'. Attempt ${attempt}/${maxRetries}. Retrying in ${delay.toFixed(0)}ms...`);
470+
await sleep(delay);
471+
}
471472
// For SSE, attempt reconnect before retrying the call if the last error was a connection error
472-
if (clientForTool.transportType === 'sse' && isConnectionError(lastError)) {
473-
logger.log(`SSE connection error for tool '${requestedExposedName}' on server '${clientForTool.name}'. Attempting reconnect before retry.`);
474-
const clientTransportConfig = currentActiveServersConfig[clientForTool.name];
475-
if (!clientTransportConfig) {
476-
logger.error(`Cannot retry SSE: TransportConfig for server '${clientForTool.name}' not found.`);
477-
// If config is missing, we can't reconnect, so break retry loop
478-
break;
479-
}
480-
const refreshed = await refreshBackendConnection(clientForTool.name, clientTransportConfig);
481-
if (refreshed) {
482-
logger.log(`Successfully reconnected to server '${clientForTool.name}' via SSE.`);
483-
// Update clientForTool and toolInfo references after refresh
484-
const newMapEntry = toolToClientMap.get(originalQualifiedName);
485-
if (!newMapEntry) {
486-
logger.error(`Tool '${originalQualifiedName}' not found in map after successful SSE refresh for server '${clientForTool.name}'.`);
487-
// If tool disappears after refresh, something is wrong, break retry loop
488-
break;
489-
}
490-
clientForTool = newMapEntry.client;
491-
toolInfo = newMapEntry.toolInfo;
492-
} else {
493-
logger.error(`SSE Reconnection to server '${clientForTool.name}' failed.`);
494-
// If reconnect fails, throw an error to exit the retry loop and propagate
495-
throw new McpError(-32000, `SSE Reconnection to server '${clientForTool.name}' failed for tool '${requestedExposedName}'.`);
496-
}
497-
}
473+
// For SSE, attempt reconnect before retrying the call if the last error was a connection error OR if it's the first attempt
474+
if (clientForTool.transportType === 'sse') {
475+
if (attempt === 0 || isConnectionError(lastError)) { // Force reconnect on first attempt for SSE, or if there was a connection error
476+
logger.log(`SSE connection handling for tool '${requestedExposedName}' on server '${clientForTool.name}'. Attempting reconnect.`);
477+
const clientTransportConfig = currentActiveServersConfig[clientForTool.name];
478+
if (!clientTransportConfig) {
479+
logger.error(`Cannot proceed with SSE: TransportConfig for server '${clientForTool.name}' not found.`);
480+
throw new McpError(-32000, `SSE TransportConfig for server '${clientForTool.name}' not found for tool '${requestedExposedName}'.`);
481+
}
482+
const refreshed = await refreshBackendConnection(clientForTool.name, clientTransportConfig);
483+
if (refreshed) {
484+
logger.log(`Successfully reconnected to server '${clientForTool.name}' via SSE.`);
485+
// Update clientForTool and toolInfo references after refresh
486+
const newMapEntry = toolToClientMap.get(originalQualifiedName);
487+
if (!newMapEntry) {
488+
logger.error(`Tool '${originalQualifiedName}' not found in map after successful SSE refresh for server '${clientForTool.name}'.`);
489+
throw new McpError(-32000, `Tool '${originalQualifiedName}' disappeared after SSE refresh for server '${clientForTool.name}'.`);
490+
}
491+
clientForTool = newMapEntry.client;
492+
toolInfo = newMapEntry.toolInfo;
493+
} else {
494+
logger.error(`SSE Reconnection to server '${clientForTool.name}' failed.`);
495+
throw new McpError(-32000, `SSE Reconnection to server '${clientForTool.name}' failed for tool '${requestedExposedName}'.`);
496+
}
497+
}
498+
}
498499
}
499500

500501
try {

0 commit comments

Comments
 (0)