"Mutation" refers to an existing variable changing its contents. You could observe this if you had a reference to a variable, looked at it once, noting its value as X, and then later looked at the same variable again, noting its value is now Y. That isn't what's happening in a list comprehension.
First, let's talk about one thing that I hope you will agree is not mutation: calling a function multiple times with different values. Suppose we have
(defn triple [x]
(* x 3))
If we write [(triple 1) (triple 2)], do we say that x has mutated? Of course not. There were two different invocations of the function triple, each with a different value for x, but those weren't the same variable: they were different instantiations of x.
A list comprehension is the same thing. The body is a function, which is evaluated once for each of the inputs. It doesn't look like a function, because there's no fn, but it really is one, both technically (it macroexpands into the body of a fn) and philosophically (it handles inputs the same way as our triple function above). (for [x xs] (f x)) is no different from writing (map f xs), which needs no mutation.
Usually when newcomers worry about mutation in Clojure, they are worried about let, which allows you to replace existing bindings:
(let [x 1
_ (prn x)
x 2]
(prn x))
This prints 1 2: doesn't this prove that x has mutated? No, it doesn't: the old x is still there, it's just shadowed so you can't refer to it anymore. You can prove this by using a function to let you refer to the old x:
(let [x 1
f (fn [] x)
x 2]
(prn (f) x))
This still prints 1 2 even though both prints happen after x was bound to 2. This is because f still sees the old x. The new x is an unrelated variable with the same name; you might as well have called it y and renamed all references to it.