When the normalized intensity in mesh3d is close to the border of two colors in the scale, interpolation is thrown off

when you want to map an interval of real values, [a,b], onto a discrete colorscale,
then you have to normalize the interval [a, b] through the map f(t)=(t-a)/(b-a) ∈ [0,1].
If c ∈(a,b) is the break point for colors, then the discrete colorscale
is defined as follows:

dclrsc =[[0, "rgb(0, 128, 0)"], [(c-a)/(b-a), "rgb(0, 128, 0)"], [(c-a)/(b-a)], "rgb(255, 0, 0)"],
    [1, "rgb(255, 0, 0)"]]

Your interval is [a, b]=[0.2, 0.7], and the normalising function is f(t)=(t-0.2)/0.5.
f evaluated at the break point is f(0.501)=0.602

Hence your discrete colorscale should be:

dclrsc=  [[0, "rgb(0, 128, 0)"], 
          [0.602, "rgb(0, 128, 0)"], 
          [0.602, "rgb(255, 0, 0)"],
          [1, "rgb(255, 0, 0)"]]  
        
import plotly.graph_objects as go
x = [1, 2, 3, 1, 2, 3, 1, 2, 3]
y = [1, 1, 1, 2, 2, 2, 3, 3, 3]
z = [1, 3, 2, 1, 3, 2, 1, 3, 2]
i = [0, 3, 6]
j = [1, 4, 7]
k = [2, 5, 8]
intesity = [0.2, 0.5, 0.7] 
        
fig=go.Figure(go.Mesh3d(
    x=x,
    y=y,
    z=z,
    i=i,
    j=j,
    k=k,
    intensity=intesity,
    intensitymode="cell",
    colorscale=dclrsc,
))
fig.show()

I explained this algorithm, from time to time, for each user conributing to this long thread of 20 comments: Colors for discrete ranges in heatmaps