Probably __get()/__set() binds it to be visible in thinker. In the end Tinker is Laravel specific REPL solution so it probably comes with few tricks up it's sleeve. Have you tried with plain class (not model) by adding __get()/__set()?
Yeah I have tried all the magic methods that are in the eloquent Model, I found that having the __isset() magic method allows the Collection where method to work on my custom class which is cool.
I have gone through how the Model setAttribute() method works and it seems to check if you have any mutators and then saves the value to the protected $attributes array.
I have also implemented ArrayAccess interface and the required methods that allow the class to be interacted with like and array.
Also I implemented the Arrayable interface and the toArray() method, which allows a Collection to turn my custom class into an array.
But, still haven't found a way to show the attributes of my custom class in tinker like a Eloquent Model does.