claude-ssh-setup/README.md

72 lines
2.6 KiB
Markdown

# claude-ssh-setup
How Claude Code on this Windows machine reaches the `sae-engineering` server
(`10.0.2.1`, user `sauer`) over SSH.
## TL;DR
OpenSSH on Windows can't load the `.ppk` key (NTFS permissions block it from
Git Bash, and the OpenSSH copy of the key fails the same way). PuTTY's `plink`
reads the PuTTY keystore natively and the host key is already trusted in the
Windows registry. `cmd.exe` mangles `user@host` (treats it as an `AT` job), so
invoke plink through `powershell.exe` instead.
## Connection details
| Field | Value |
| -------- | ---------------------------------------------- |
| Host | `10.0.2.1` |
| User | `sauer` |
| Key | `C:\Users\richa\.ssh\id_ed25519.ppk` (PuTTY) |
| Plink | `C:\Program Files\PuTTY\plink.exe` |
| pscp | `C:\Program Files\PuTTY\pscp.exe` |
## Single command
```bash
powershell.exe -Command "& 'C:\Program Files\PuTTY\plink.exe' -i 'C:\Users\richa\.ssh\id_ed25519.ppk' -batch -l sauer 10.0.2.1 '<command>'"
```
`-batch` disables interactive prompts so the call fails fast in automation
instead of hanging.
## Multiple commands
Chain with `;` and avoid single quotes inside the remote command (the outer
single quotes are already in use):
```bash
powershell.exe -Command "& 'C:\Program Files\PuTTY\plink.exe' -i 'C:\Users\richa\.ssh\id_ed25519.ppk' -batch -l sauer 10.0.2.1 '/bin/cmd1; /bin/cmd2'"
```
For anything more complex, write a script locally and run it with the
file-transfer recipe below.
## File transfer (pscp)
```bash
"/c/Program Files/PuTTY/pscp.exe" -i "C:/Users/richa/.ssh/id_ed25519.ppk" -batch \
localfile sauer@10.0.2.1:/remote/path
```
This is also the workaround when a remote command needs literal quotes or
braces — PowerShell + plink eats them. Write the payload to a local file,
`pscp` it across, then have plink consume it (e.g. `curl --data-binary @file`).
## "Ubuntu Server Mode"
When the user says **"Ubuntu Server Mode"** (or "server mode"), Claude treats
every shell command as if it were running on `10.0.2.1` as `sauer` — wrap each
command with the plink invocation transparently and follow server-side
conventions (`sudo docker compose`, Caddy reload paths, etc.). The server has
its own memory at `~/.claude/projects/-home-sauer/memory/MEMORY.md` — read
that index before making changes. Stay in this mode until told to exit
("back to local", "exit server mode").
## Notifications (server side)
```bash
claude-notify "message" # send to Telegram bridge
claude-inbox --pop # read responses
```