feat(mcp): make max_reconnect_retries configurable per server

Allow MCP servers to override the default reconnect retry limit (5)
via config:

  mcp_servers:
    my-server:
      url: http://localhost:8764
      max_reconnect_retries: 50  # for servers with long maintenance windows

Previously _MAX_RECONNECT_RETRIES was a module-level constant (5),
requiring code changes to adjust. This is problematic for servers
behind load balancers with session expiry (e.g., wiki-brain behind
reverse proxy) where short reconnect limits cause silent failures.

The default remains 5 — fully backward compatible.
This commit is contained in:
SonicBotMan 2026-04-18 19:30:07 +08:00
parent 4610551d74
commit e04364eae0

View file

@ -1033,6 +1033,7 @@ class MCPServerTask:
""" """
self._config = config self._config = config
self.tool_timeout = config.get("timeout", _DEFAULT_TOOL_TIMEOUT) self.tool_timeout = config.get("timeout", _DEFAULT_TOOL_TIMEOUT)
self.max_reconnect_retries = config.get("max_reconnect_retries", _MAX_RECONNECT_RETRIES)
self._auth_type = (config.get("auth") or "").lower().strip() self._auth_type = (config.get("auth") or "").lower().strip()
# Set up sampling handler if enabled and SDK types are available # Set up sampling handler if enabled and SDK types are available
@ -1106,18 +1107,18 @@ class MCPServerTask:
return return
retries += 1 retries += 1
if retries > _MAX_RECONNECT_RETRIES: if retries > self.max_reconnect_retries:
logger.warning( logger.warning(
"MCP server '%s' failed after %d reconnection attempts, " "MCP server '%s' failed after %d reconnection attempts, "
"giving up: %s", "giving up: %s",
self.name, _MAX_RECONNECT_RETRIES, exc, self.name, self.max_reconnect_retries, exc,
) )
return return
logger.warning( logger.warning(
"MCP server '%s' connection lost (attempt %d/%d), " "MCP server '%s' connection lost (attempt %d/%d), "
"reconnecting in %.0fs: %s", "reconnecting in %.0fs: %s",
self.name, retries, _MAX_RECONNECT_RETRIES, self.name, retries, self.max_reconnect_retries,
backoff, exc, backoff, exc,
) )
await asyncio.sleep(backoff) await asyncio.sleep(backoff)