diff --git a/tools/mcp_tool.py b/tools/mcp_tool.py index 69917ec6a8a..e4448bacd25 100644 --- a/tools/mcp_tool.py +++ b/tools/mcp_tool.py @@ -415,6 +415,13 @@ def _is_method_not_found_error(exc: BaseException) -> bool: an empty result. Structurally inspect ``McpError.error.code`` first, then fall back to a substring match so detection survives SDK version drift and servers that surface the condition as a plain message. + + The substring fallback matters when a server reports method-not-found + without a structural ``-32601`` code (e.g. surfaced as a plain exception + string). Besides the canonical "method not found", many JSON-RPC + implementations phrase it as "Unknown method: " — agentmemory's MCP + server is one such case (#50028). Without matching that phrasing the + ping→list_tools fallback never latches and the keepalive reconnect-loops. """ # Structural: mcp.shared.exceptions.McpError carries ErrorData.code. err = getattr(exc, "error", None) @@ -427,6 +434,7 @@ def _is_method_not_found_error(exc: BaseException) -> bool: return ( str(_JSONRPC_METHOD_NOT_FOUND) in msg or "method not found" in msg + or "unknown method" in msg or "not found: ping" in msg )