Doing Claude Code Right on a Remote Server — Ditch the Local Clone, Use tmux + Screenshot Auto-Hand-off
A remote Ubuntu server + AI coding agent workflow. Why I ditched the local clone, tmux multi-sessions instead of the VS Code extension, and filling the image-input gap in a pure terminal with an ss sync + cc function.
A write-up of refining a workflow for using Claude Code on an Ubuntu server running Docker Magento. For anyone working with a "remote server + AI coding agent."
TL;DR
- Don't use a local clone. There's no Magento locally, so the agent can't verify its own work with
bin/magento. Edit directly on the server + test immediately, no commits. - tmux instead of the VS Code extension. SSH into the server once → split panels in tmux for multiple Claude Code instances. Sessions survive a dropped SSH (reconnect with
tmux attach). - Image input: mirror a screenshot folder to the server + a wrapper (
cc) that auto-attaches the latest file.
# 서버 ~/.bashrc — 최신 스크린샷을 자동으로 집어 claude에 첨부
SHOT_DIR="$HOME/ss"
cc() {
local latest
latest=$(ls -t "$SHOT_DIR"/*.png 2>/dev/null | head -1)
if [ -n "$latest" ]; then
echo "🖼 첨부: $(basename "$latest")"
claude "$@" "$latest"
else
claude "$@"
fi
}On the Mac, mirror CleanShot's save location one-way to the server's ~/ss with Mutagen → in tmux, cc "why is this layout broken?" auto-includes the shot you just took.
Can't I just work from a local clone? — No
- The commit becomes a "precondition for testing." With local as the source, checking one line means commit → push → server pull every time. Once a commit becomes the means of "let's see if it works," the loop slows and history gets dirty with
wip,fix. A commit should mean "verified, saved." - The clincher: there's no Magento locally. Claude Code's power isn't just editing code but running commands and checking results right there (compile → logs → error → re-fix). Locally the agent can't verify its own work — a clear downgrade.
I split the mental model in two. The inner loop (development) is direct editing + immediate testing on the server, no commits. The outer loop (deployment) is push after verifying → pull in production. Since I edit the server directly, staging is always current, so the "local→staging sync" problem disappears entirely — that was a self-inflicted problem that only arises if you choose local editing.
Compile on every change? Mostly no
Only some changes need a command in Magento.
.phtml, block/model PHP, JS, Tailwind source → save and refresh, instantly visible (developer mode + Docker bind-mount)..xmllayout, translations → justcache:flush.di:compile→ only when adding a new dependency/plugin/preference todi.xml, orsetup:upgradefor a new module.
Everyday logic and template work needs zero commands. For theme work, keep npm run watch (Tailwind) running and CSS builds on every save. And when it's genuinely needed, tell Claude Code "fix it, run the necessary Magento commands, and check the result" and it decides, runs them, and even checks the errors — the very reason for running the agent on the server.
The real reason the VS Code extension felt clunky
The clunkiness wasn't from "working on a server" but from "going through the VS Code extension." Claude Code is a terminal-native tool; the extension is an add-on, and the CLI is the real thing. So the direction is clear — skip the extension and launch several instances directly in the server terminal with tmux.
ssh server (한 번)
└─ tmux
├─ 패널1: ModuleA 에서 claude
├─ 패널2: ModuleB 에서 claude
└─ 패널3: tail -f var/log/ (로그)
A tmux session is attached to the server, not the SSH, so it doesn't die when the internet drops or you close the laptop. Close the lid at a cafe, tmux attach at home, and your conversation continues right where it was.
What about isolation (git worktree)? Tools like Conductor create worktrees to prevent conflicts when multiple agents touch the same files at once. Independent work split into per-module folders doesn't conflict without worktrees, and Magento has a single running instance (DB, cache, compiled) even if you split the code, so it's a bottleneck in the end. If the work doesn't need isolation, bare tmux is enough.
Pasting images: ss sync + cc
One reason I couldn't drop VS Code was clipboard image paste, which a pure terminal doesn't do by default. There's the CleanShot public-URL route, but putting Magento admin/order/API-key screens on the public internet bothered me, so I went with local sync (the cc function in the TL;DR above). It's two steps — "capture → cc." Tokens are driven by image resolution, not the transport (URL/file), so a habit of region capture is a habit of saving tokens.
A tmux session manager already exists
Pure tmux can't show "which session finished." Tools that fill that gap: craftzdog/tmux-claude-session-manager (per-project sessions + a finished/working status popup, using Claude Code hooks), NTM (named sessions, broadcast, conflict detection, plus sessions that survive SSH drops when run on a remote server — a good fit for remote), nielsgroen/claude-tmux (a tmux popup TUI for switching and monitoring sessions). The order: start with bare tmux to get a feel, and once sessions grow and "what's running, what finished?" gets frustrating, add a manager layer then.
Lessons
- Remote Claude Code becomes clunky only if you pick the wrong conduit. Keep direct server work (DB/Magento access, agent self-verification) but swap the conduit from the extension to tmux, and you gain multi-sessions and session persistence.
- Don't use an isolation tool for work that doesn't need isolation. In that case tmux is the answer.
- The terminal's weakness (image input) can be filled with a file sync + wrapper function — no need to envy GUI tools.