Remote SSH command requires a terminal

Theory

SSH sessions can be started with – or without – the remote server allocating a pseudo-terminal (PTY) device.

Usually when you connect to a remote host via SSH (without specifying a command), you run your default login shell after authenticating correctly. When running this shell on a remote host, a pseudo-terminal is automatically allocated for the interactive shell. This allows the shell to write to the user’s screen so that it can do things such as display its prompt.

During the interactive session, the SSH_TTY environment variable is set to the device node of the remote PTY device, e.g., /dev/pts/10 and when the pseudo-terminal exits, ssh prints the following message:

Connection to <remotehost> closed.

For non-interactive SSH sessions, i.e., specifying a command to run on the remote host, no pseudo-terminal is allocated and the command output is sent to the stdout of the local terminal. This default behaviour works well when running commands that simply read input from stdin and print to stdout and/or stderr, e.g., ls, ps, etc. In this case the SSH_TTY environment variable is not set and I’ve also noticed that the TERM environment variable is set to dumb. When operating without a pseudo-terminal, the escape characters such as ~C are not supported; this makes it safe for programs to transfer binary files which may contain these sequences.

However, programs such as vim or top need to be able to redraw the screen using various terminal capabilities (typically using the ncurses library). For this, they require a terminal device – or a device which emulates a terminal. The ssh client features a -t option which forces the allocation of a pseudo-terminal. This -t option is described in the SSH man page:

Force pseudo-tty allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.

Conclusion

So, adding the -t option to your SSH command is all you need to do to provide Vim with a terminal device that it can use:

ssh -t me@myserver vim