Help us improve
Share bugs, ideas, or general feedback.
From external-gitcode-ascend-skills
Guides connecting to remote servers via SSH, with multiple authentication methods (SSH keys, sshpass, tmux, paramiko/fabric), Docker container access, file transfer, and troubleshooting.
npx claudepluginhub ascend-ai-coding/awesome-ascend-skills --plugin migration-ascend-torchnpu-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/external-gitcode-ascend-skills:remote-server-guideThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
A workflow for connecting to remote servers, executing commands, and managing containers over SSH. This skill is tool-agnostic — it helps you pick the right SSH tool for the job and walks through the full lifecycle from connection to cleanup.
Establishes SSH connections to remote servers for executing commands, checking logs, restarting services, and managing Docker containers via bash scripts.
Manages SSH connections, executes remote commands, transfers files, and runs background jobs on servers. Automatically wraps docker/kubectl in container environments.
Connects to cloud instances via SSH/CLI and diagnoses access blockers. Supports AWS EC2, Aliyun ECS, bastions, file transfer, log inspection, and process checks within authorization boundaries.
Share bugs, ideas, or general feedback.
A workflow for connecting to remote servers, executing commands, and managing containers over SSH. This skill is tool-agnostic — it helps you pick the right SSH tool for the job and walks through the full lifecycle from connection to cleanup.
| Method | Security | Convenience | Best For |
|---|---|---|---|
| SSH Key | Highest | High | Production, frequent use |
| tmux (interactive) | High (password never exposed to AI) | Medium | One-time access, security-conscious users |
| sshpass | Medium (password in command) | High | Quick scripts, trusted environment |
| paramiko/fabric | Medium | Medium | Python automation |
Before connecting, collect from the user:
ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -i <key-path> <user>@<host> -p <port> "echo 'Connection successful'"
If the user needs password auth, first detect available tools:
which sshpass >/dev/null 2>&1 && echo "sshpass: available" || echo "sshpass: not found"
python3 -c "import paramiko" 2>/dev/null && echo "paramiko: available" || echo "paramiko: not found"
python3 -c "import fabric" 2>/dev/null && echo "fabric: available" || echo "fabric: not found"
which tmux >/dev/null 2>&1 && echo "tmux: available" || echo "tmux: not found"
If the user is concerned about password security, always recommend tmux interactive — the password is typed by the user directly and never seen by the AI.
Tool selection guidance:
| Scenario | Recommended Tool | Reason |
|---|---|---|
| Security-conscious user | tmux | Password never exposed to AI |
| One-time access | tmux | No credential storage needed |
| Quick shell script | sshpass | Simple, no dependencies |
| Python application | paramiko | Full control, lower level |
| Deployment automation | fabric | High-level API, cleaner code |
| Need SFTP | paramiko or fabric | Built-in support |
| Interactive terminal | tmux or sshpass | Native TTY support |
If no tools are available, offer to install one:
# tmux (Ubuntu/Debian)
sudo apt-get install -y tmux
# sshpass (Ubuntu/Debian)
sudo apt-get install -y sshpass
# paramiko
pip install paramiko
# fabric
pip install fabric
Verify the connection works before proceeding.
sshpass:
sshpass -p '<password>' ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no <user>@<host> -p <port> "echo 'Connection successful'"
tmux (interactive):
tmux new-session -d -s remote_session "ssh -o StrictHostKeyChecking=no <user>@<host> -p <port>"
# Tell user: "Please run: tmux attach -t remote_session and enter your password"
# After user confirms, verify:
tmux capture-pane -t remote_session -p
paramiko:
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname='<host>', port=<port>, username='<user>', password='<password>')
print('Connection successful')
client.close()
fabric:
from fabric import Connection
conn = Connection(host='<host>', user='<user>', connect_kwargs={'password': '<password>'})
conn.run('echo "Connection successful"', hide=True)
conn.close()
If connection fails, troubleshoot:
Ask the user where commands will run:
npu-docker-launcher for NPU servers)Important: tmux vs other tools behave very differently for container work.
tmux (persistent session): Enter the container shell once, then send all subsequent commands directly — they execute inside the container automatically. The session maintains state (working directory, environment variables, shell context).
# List containers
tmux send-keys -t remote_session "docker ps" Enter
tmux capture-pane -t remote_session -p
# Enter container ONCE — all subsequent commands run inside the container
tmux send-keys -t remote_session "docker exec -it <container-name> bash" Enter
# Now you are INSIDE the container — just send commands directly, no need to repeat docker exec
tmux send-keys -t remote_session "cd /workspace" Enter
tmux send-keys -t remote_session "python inference.py" Enter
tmux send-keys -t remote_session "cat result.txt" Enter
tmux capture-pane -t remote_session -p
# Exit container when done (returns to host shell)
tmux send-keys -t remote_session "exit" Enter
Other tools (stateless): Each command is a separate SSH connection with no shared state. You must prefix every command with docker exec:
# Every command needs the full docker exec prefix
ssh <user>@<host> "docker exec <container-name> ls /workspace"
ssh <user>@<host> "docker exec <container-name> python inference.py"
ssh <user>@<host> "docker exec <container-name> cat result.txt"
Use the selected SSH tool consistently for all operations.
tmux: Since tmux maintains a persistent shell session, just send the command directly. If you previously entered a container, the command runs inside the container.
tmux send-keys -t remote_session "<command>" Enter
tmux capture-pane -t remote_session -p
Other tools (stateless, each command is independent):
| Tool | On host | In container |
|---|---|---|
| SSH key | ssh -i <key> <user>@<host> "<command>" | ssh -i <key> <user>@<host> "docker exec <container> <command>" |
| sshpass | sshpass -p '<pwd>' ssh <user>@<host> "<command>" | sshpass -p '<pwd>' ssh <user>@<host> "docker exec <container> <command>" |
| paramiko | client.exec_command("<command>") | client.exec_command("docker exec <container> <command>") |
| fabric | conn.run("<command>") | conn.run("docker exec <container> <command>") |
| Tool | Upload | Download |
|---|---|---|
| scp | scp <local> <user>@<host>:<remote> | scp <user>@<host>:<remote> <local> |
| sshpass+scp | sshpass -p '<pwd>' scp <local> <user>@<host>:<remote> | sshpass -p '<pwd>' scp <user>@<host>:<remote> <local> |
| paramiko | sftp.put('local', 'remote') | sftp.get('remote', 'local') |
| fabric | conn.put('local', 'remote/') | conn.get('remote', 'local') |
For complex operations, upload a script and execute it:
# Upload script
scp setup.sh <user>@<host>:/tmp/
# Execute
ssh <user>@<host> "bash /tmp/setup.sh"
# Cleanup
ssh <user>@<host> "rm /tmp/setup.sh"
When done, clean up resources:
client.close(), conn.close())tmux kill-session -t remote_session)# Create SSH session (user inputs password)
tmux new-session -d -s remote_session "ssh -o StrictHostKeyChecking=no <user>@<host> -p <port>"
# User runs: tmux attach -t remote_session
# Execute command after connection
tmux send-keys -t remote_session "<command>" Enter
# Get output
tmux capture-pane -t remote_session -p
# Kill session when done
tmux kill-session -t remote_session
# Execute command
sshpass -p '<password>' ssh <user>@<host> "<command>"
# Upload file
sshpass -p '<password>' scp <local> <user>@<host>:<remote>
# Docker exec on remote
sshpass -p '<password>' ssh <user>@<host> "docker exec <container> <command>"
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname='<host>', username='<user>', password='<password>')
# Execute command
stdin, stdout, stderr = client.exec_command('<command>')
print(stdout.read().decode())
# SFTP
sftp = client.open_sftp()
sftp.put('local.txt', '/remote/path/remote.txt')
sftp.get('/remote/file.txt', 'local.txt')
client.close()
from fabric import Connection
conn = Connection(host='<host>', user='<user>',
connect_kwargs={'password': '<password>'})
result = conn.run('<command>', hide=True)
print(result.stdout)
conn.put('local.txt', '/remote/path/')
conn.get('/remote/file.txt', 'local.txt')
conn.close()
| Error | Cause | Solution |
|---|---|---|
| Connection refused | SSH not running | Check SSH service on remote |
| Permission denied | Wrong credentials | Verify username/password/key |
| Host key verification failed | First connection | Add -o StrictHostKeyChecking=no |
| Network unreachable | Network issue | Check firewall, VPN |
| Tool not found | Not installed | Run installation command |
| Container not found | Wrong name | docker ps -a to list all |
SSHPASS env varchmod 600 ~/.ssh/id_rsaFor in-depth usage of each tool, consult: