Remote Work over SSH
Connection details live in ssh.md in the project folder. Read it before every remote session. Never guess hosts, users, ports, key paths, or passwords.
When to Activate
- The user asks to connect to, log into, or run something on a remote machine
- The user asks to inspect, edit, build, or test a remote project
- The user mentions a server, VPS, or remote host and expects SSH access
Step 1: Locate ssh.md
The project folder is git rev-parse --show-toplevel, or the current directory if that fails. ssh.md always lives at <project folder>/ssh.md.
If it doesn't exist, create it from the template and tell the user to fill it in:
- Find
ssh.example.md. It sits in this skill's folder, which depends on the agent. Check these paths in order and use the first that exists:.agents/skills/remote-work-ssh/,.claude/skills/remote-work-ssh/,.opencode/skills/remote-work-ssh/,~/.agents/skills/remote-work-ssh/,~/.claude/skills/remote-work-ssh/,~/.config/opencode/skills/remote-work-ssh/. If none exists, runfind ~ -path '*remote-work-ssh*' -name ssh.example.md 2>/dev/null | head -n 1. - Copy it to
<project folder>/ssh.md. - Add
ssh.mdto the project's.gitignoreif it's missing. Create.gitignoreif needed. - Stop and tell the user to fill in
ssh.md.
Step 2: Validate the Configuration
ssh.md contains one YAML block. Check these fields:
authmust bealias,key, orpassword.remote_project_pathmust be set.- Fields for the chosen method must be set:
auth | Required fields |
|---|---|
alias | alias |
key | host, user, identity_file (port defaults to 22) |
password | host, user, password_env (port defaults to 22) |
If a required field is missing or auth is unknown, stop and report exactly which field is wrong. Do not fall back to another method.
Step 3: Connect
alias
Resolve the entry first, then connect:
ssh -G <alias> | grep -E '^(hostname|user|port) '
ssh -o BatchMode=yes <alias> 'hostname && whoami'
key
- Confirm
identity_fileexists. If it doesn't, stop. - Use only that key:
ssh -o BatchMode=yes -o IdentitiesOnly=yes -i <identity_file> -p <port> <user>@<host> 'hostname && whoami'
- If
proxy_jumpis set, add-J <proxy_jump>.
password
- Check that
sshpassis installed withcommand -v sshpass. If it's missing, stop and tell the user to install it. - Check that the environment variable named by
password_envis set, without printing its value. - Pass the value to
sshpassthrough theSSHPASSenvironment variable and-e. Do not put the password in a command-line argument or in any output. - Disable key-based attempts so only the password is used:
SSHPASS="$(printenv <password_env>)" sshpass -e ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password -p <port> <user>@<host> 'hostname && whoami'
- If
proxy_jumpis set, add-J <proxy_jump>. - Do not use
BatchMode=yeshere, because it disables password authentication.
Host keys (all methods)
- If the host key is unknown or has changed, stop. Show the fingerprint and ask the user to verify it.
- Never set
StrictHostKeyChecking=noor similar options that skip verification.
Step 4: Work in the Remote Project
- Run every command inside
remote_project_path, for examplessh ... 'cd <remote_project_path> && <command>'. Quote the path. - Before assuming a tool exists on the remote machine, check its manifests or run
command -v <tool>. - Do not write outside
remote_project_pathunless the user asks.
Safety Rules
- Ask before destructive commands such as
rm -rf, force pushes, dropping databases, disk operations, or service restarts. - Never print, copy, log, or commit passwords, key contents, or tokens.
- Do not store credentials in any file other than the project's
ssh.mdor the environment. - Do not run commands on the remote machine that the user has not asked for.
Unsupported Operations
- Storing passwords in tracked files or in this skill
- Handling interactive MFA or one-time codes on the user's behalf
- Disabling host key verification
- Connecting to hosts that are not defined in
ssh.md