Your shell command will be picking up on whatever the
default-directory is for the current buffer, and
emacsclient sets the server buffer as the current buffer by default. The current buffer needn't be displayed in a window at all, so although there will still be a "selected window" for the frame, you will need to select that window explicitly (which will make its buffer the current buffer for the duration).
emacsclient -e "(with-selected-window (selected-window) (external-shell-in-dir))"
Of course that may or may not have selected the frame you intended, so you might want to wrap
with-selected-frame around that, assuming you have a reliable way to choose it.
You may find it helpful to test the likes of:
emacsclient -e "(current-buffer)"
emacsclient -e "(selected-window)"
emacsclient -e "(selected-frame)"
emacsclient -e "(frame-list)"
If it's feasible for your use-case, I think using
with-current-buffer and an explicit buffer to act on would be a more robust approach.