I think it works if all threads read/write commands queues in a synchronized environment, as you suggest.
If I understood your approach basically you have a server thread that pool all active clients queue, process each command, and send a response throw client connection.
The only thing to take care in such solution is to synchronize queues (both clients and server), well... it not soo difficult, but debugging can be a nightmare if something do not work as expected (there are something wrong in client threads? in server thread? in queues synchronization?).
When I developed a mud server I choose to do it in a different way.
Each player is an object that "speak" with the clinet throw a connection (so one player one thread as in your solution, but only for I/O), a player receive a command string and pass the command to a command manager with a reference to itself. No queue in the "client side", only a command queue in the "server side" (server thread).
When the command manager receive this instruction process it and, if there are some feedback for player, use the payer reference to perform back comunications.
It's a quite similar approach, but I have only one command queue and I don't have a thread that "pool" each active connection; my server thread waits command from players and process it in a First In First Out way.
I don't know if this is the "best way to do this"(TM)
, just an idea.
I think develop a mud environment is an interesting exercise, there are a lot of possibilities to do the same things
Have a good job