把圖片貼進遠端 coding agent(透過 SSH)¶
Terminology rule (zh-TW pages)
技術名詞首次出現以「中文 (English original)」格式呈現,例:逸出序列
(escape sequence)。不自創翻譯——若無公認譯名直接保留英文
(如 clipboard、daemon)。代碼、API 名、CLI flag、套件名、檔名一律不翻。
狀態:僅調研 — 尚未採用任何方案。 本文件盤點如何把本機剪貼簿裡的圖片(截圖)送進一個透過 SSH 跑在遠端機器上的 coding agent(Claude Code,以及 Neovim 相關工作流)。它是 clipboard.md 的「圖片版續集」:OSC 52 解決了遠端剪貼簿同步的文字那一半,但它無法載送圖片或檔案 (file) payload,所以需要另一套機制。
等我們真的選定並接進 dotfiles 後,本文件會從「盤點」升級成「這是怎麼串接的」(並補上 .zh-TW.md 鏡像,與 docs/tools/ 其他文件一致——你現在讀的就是)。
核心限制¶
| 資料在哪 | 今天怎麼跨 SSH | |
|---|---|---|
| yank 的文字 | 遠端 app → 本機剪貼簿 | OSC 52 — 逸出序列沿 TTY 往上送回本機終端機(見 clipboard.md) |
| 截圖圖片 | 本機剪貼簿 → 遠端 agent | ❌ 沒有內建機制——OSC 52 只能載文字;圖片 bytes 根本沒離開你的筆電 |
這個不對稱就是問題全貌。裝著截圖的剪貼簿在你的本機;需要「看到」圖片的 agent 跑在遠端。OSC 52 方向相反(遠端→本機),而且只載 base64 文字。所以下面每個方案骨子裡都是同一招:把本機的圖片 bytes 落成遠端檔案系統上的一個檔案,再把那個路徑交給 agent(agent 透過自己的 Read 工具從路徑讀圖)。它們的差別只在於 bytes 怎麼傳、以及這趟來回自動化到什麼程度。
那 terminal 圖片協議(kitty graphics / sixel / iTerm2 inline)為什麼不行? 那些是輸出 (output) 協議——讓遠端程式把圖畫進你的終端機。它們不提供遠端程式去擷取你本機剪貼簿裡圖片的手段。一樣是方向反了。(我們已為顯示面開了
allow-passthrough on;那對輸入毫無幫助。)
方案分類¶
0. 基準線 — 手動落檔 + 路徑引用(零工具)¶
把截圖存到遠端看得到的地方,然後在 agent prompt 裡引用路徑。
scp ~/shot.png remote:/tmp/ # 或拖進 sshfs / VS Code 掛載
# 然後在遠端的 Claude Code 裡:
# @/tmp/shot.png 這個 layout 哪裡有問題?
- 優點: 到處都能用,無 daemon、無 tunnel,撐得過 tmux/mosh。這是永遠可用的退路。
- 缺點: 每次都要手動;打斷心流。下面所有方案都只是這條基準線的自動化。
1. 網路 daemon + SSH reverse tunnel(Zeitler 家族)¶
對純 terminal / tmux 工作流最對味。一個小 daemon 跑在你本機讀本機剪貼簿;遠端那側透過 SSH 反向 tunnel(RemoteForward)連到它,把 bytes 寫成暫存檔。我們本來就維護長期 SSH 設定,加一行 RemoteForward 成本很低。
1a. claude-ssh-image-skill — ccimgd + ccimg + /paste-image skill¶
AlexZeitler/claude-ssh-image-skill · MIT · Go(靜態 binary)· 對原始問題最直接的答案。
架構(base64-over-TCP,不用 scp):
/paste-image(遠端 Claude skill)
└─ Bash: ccimg(遠端 client)
└─ TCP 127.0.0.1:9998 ──(SSH -R 反向 tunnel)──▶ ccimgd(本機 daemon)
└─ 讀本機剪貼簿
(wl-paste / xclip / pngpaste)
◀── JSON { ok, image: <base64 PNG> } ─────────────────
└─ ccimg 寫出 /tmp/…png,印出路徑
└─ Claude 的 Read 工具載入該路徑 → 圖片進入 session
安裝(README 原文照抄):
# 建置兩個 binary(需要 Go)
git clone https://github.com/AlexZeitler/claude-ssh-image-skill.git
cd claude-ssh-image-skill && ./build.sh
# 本機 daemon — Linux
cp daemon/ccimgd-linux-amd64 ~/.local/bin/ccimgd
cp daemon/ccimgd.service ~/.config/systemd/user/
systemctl --user daemon-reload && systemctl --user enable --now ccimgd
# 本機 daemon — macOS
brew install pngpaste
cp daemon/ccimgd-darwin-arm64 /usr/local/bin/ccimgd
cp daemon/com.ccimgd.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.ccimgd.plist
# 遠端:client binary + skill
scp client/ccimg-linux-amd64 remote:~/.local/bin/ccimg
scp skill/paste-image.md remote:~/.claude/commands/paste-image.md
反向 tunnel(寫進 ~/.ssh/config 讓它自動):
……或臨時:ssh -R 9998:localhost:9998 remote-server。把 "Bash(ccimg)" 加進遠端 ~/.claude/settings.json 的 permissions.allow 就能免確認執行 client。用法:本機複製一張圖,然後在遠端 Claude session 執行 /paste-image。
- 剪貼簿後端: Wayland
wl-paste、X11xclip、macOSpngpaste(自動偵測)。 - 對我們的契合度: ★ terminal/tmux 最佳解。Port 9998 刻意跟 sshimg.nvim 的 9999 錯開,好讓兩個 daemon 並存。
- 代價: 反向 tunnel 要一直開著;本機 daemon 要在跑;只吃 PNG。
1b. sshimg.nvim — imgd + Neovim plugin(scp 傳輸)¶
AlexZeitler/sshimg.nvim · MIT · Python daemon + Lua plugin。同一作者,目標換成 Neovim 而非 Claude,傳輸也不同:走 scp 而非 base64-over-TCP。
# 本機 daemon
cp daemon/imgd.py ~/.local/bin/imgd && chmod +x ~/.local/bin/imgd
cp daemon/imgd.service ~/.config/systemd/user/imgd.service
systemctl --user enable --now imgd
ssh -R 9999:localhost:9999 yourserver # 反向 tunnel(port 9999)
-- lazy.nvim
{ "AlexZeitler/sshimg.nvim", opts = {
port = 9999, host = "127.0.0.1",
-- <leader>pa → 存進 ./assets/ ; <leader>pp → 存在目前檔案旁
} }
在遠端的 Markdown buffer 按 <leader>pa / <leader>pp → plugin 把本機剪貼簿圖片 scp 過去,並在游標處插入 。
- 依賴: 本機 =
wl-paste+scp+ Python 3(依 README 僅 Wayland);遠端 = Neovim + Python 3。 - 對我們的契合度: ★ 補足我們的 Neovim-over-SSH 設定(見
clipboard.md§3「編輯器 — Neovim」的 SSH 條件式 OSC 52 provider)。它會把真檔案寫進 repo 樹裡,這正是之後讀那份 Markdown 的 agent 想要的。缺點:如文件所述只支援 Wayland 剪貼簿讀取;開箱沒有 macOS/X11 路徑。
背景文章(把 1a+1b 串起來):Paste clipboard images into Claude Code over SSH。
2. GUI 編輯器橋接 — 讓編輯器掌管剪貼簿¶
如果 agent 是從 VS Code Remote-SSH 驅動,貼圖問題直接消失:VS Code 跑在本機、掌管本機剪貼簿,所以正常的 Ctrl/Cmd+V 貼進 Claude Code 擴充的輸入框,圖片就會透過編輯器的遠端通道帶過去——不用 daemon、不用 tunnel。
- 官方: Claude Code VS Code 擴充 走 Remote-SSH。除了兩個擴充之外零設定;還附帶圖形化 diff / plan review。
- 社群 CLI-in-terminal 變體(當你在 VS Code 內建終端機裡跑 Claude CLI 而非用擴充時):例如 marcucio/claude-image-paste 讀本機剪貼簿、透過 Remote-SSH 檔案系統上傳、貼出對應的遠端路徑。Marketplace 上還有幾個做同樣把戲的(
claude-remote-image-paste、claude-paste-image)。 - 對我們的契合度: ★ 雙軌工作流裡 VS Code 那側的最佳解。對純 tmux SSH session 毫無作用。
3. 本機剪貼簿 → 路徑注入器(與終端機無關)¶
這類工具以熱鍵擷取或讀取本機剪貼簿,落成檔案,再把檔案路徑打字進目前 focus 的終端機。因為它們注入的是文字(一段路徑),所以跟任何鍵盤輸入一樣能越過 SSH。
| 工具 | 平台 | 機制 | 備註 |
|---|---|---|---|
| Invoke | 跨平台 | 熱鍵截圖 → ~/.screenshots/… → 貼出路徑 |
付費(約 $49 一次性);零 SSH 設定;但路徑是本機的——只有在終端機 app 能把它對映到遠端可見路徑(掛載)、或你接受本機擷取流程時才有用 |
| Clipport | macOS + iTerm2 | clipportd daemon 透過既有 SSH 連線上傳剪貼簿圖片、插入遠端路徑 |
單鍵;iTerm2 貼上熱鍵 → helper;僅 macOS/iTerm2,專有協議(非 OSC 52) |
- 對我們的契合度: 視情況。若你統一到 macOS + iTerm2,Clipport 的單鍵 UX 最俐落(我們沒有——跨 macOS + Linux 用 Ghostty/Alacritty)。
4. 雲端 — 直接繞開 SSH¶
Claude Code on the web 把 agent 跑在 Anthropic 的 sandbox;你直接把圖貼進瀏覽器(本機剪貼簿,流程裡沒有 SSH)。
- 對我們的契合度: 只有在程式碼能放進 Anthropic 雲端時。對任意遠端機器 / 私有基礎設施不是通用解。
對比矩陣¶
| 方案 | 目標 | 本機依賴 | 遠端依賴 | 傳輸 | 需 tunnel? | 平台 | 契合度 |
|---|---|---|---|---|---|---|---|
0 · 手動 scp + @path |
任何 agent | — | — | scp/掛載 | 否 | 全部 | 退路 |
| 1a · claude-ssh-image-skill | Claude Code CLI | ccimgd + wl-paste/xclip/pngpaste | ccimg + skill | base64/TCP :9998 | 反向 | Wayland/X11/macOS | ★ terminal |
| 1b · sshimg.nvim | Neovim | imgd + wl-paste + scp + py3 | nvim + py3 | scp :9999 | 反向 | Wayland(依文件) | ★ nvim |
| 2 · VS Code Remote-SSH | Claude 擴充 / CLI | VS Code | Remote-SSH server | 編輯器通道 | 否 | 全部 | ★ VS Code |
| 3 · Invoke / Clipport | 任何終端 agent | daemon | — | 路徑注入 / 上傳 | 否 | Invoke: 全部 · Clipport: mac+iTerm2 | 視情況 |
| 4 · Claude Code web | web agent | 瀏覽器 | —(雲端) | HTTPS | 否 | 全部 | 僅雲端 |
對本設定的契合評估(供之後決策)¶
- 我們是雙軌(機主 tmux/terminal 與 VS Code/Neovim 都用),所以答案很可能是兩個互補選擇、而非一個:terminal/tmux Claude 用 1a,編輯器那側用 2(VS Code)或 1b(Neovim)。1a 與 1b 天生可並存(port 9998 vs 9999)。
- 反向 tunnel 是反覆成本。 我們本來就精修
~/.ssh/config;每台機器一行RemoteForward就是整個家族 1 方案的入場費。值得決定是否跨主機統一一個 port(例如 9998)。 - 剪貼簿後端分散: 我們的機器橫跨 macOS、Wayland、X11。1a 三者都自動偵測;1b 依文件僅 Wayland——若機主要走 Neovim 路徑且在 macOS/X11 上,這是個要衡量的缺口。
- 既有基礎設施幫的是顯示面(
allow-passthrough on、set-clipboard on),與輸入正交;這些都不需改動。 - 建置 / 信任: 家族 1 都是小型 MIT Go/Python,會從原始碼自建、以使用者層級的 systemd/launchd service 跑,讀剪貼簿並在 localhost 監聽——信任面跟
xCLI 相同。不需 root。 - 安全備註: 一個隨叫隨應地把你剪貼簿圖片吐出來的 localhost daemon,任何能打到遠端那個被 forward 的 port 的東西都碰得到——也就是 tunnel 開著時、在那台機器上有帳號的任何人。單人機可接受;共用主機要三思。
採用前的未決問題¶
- 一個工具還是兩個(terminal + 編輯器)?反向 tunnel 的 port 要不要統一?
- 透過 ansible
devtoolsrole 打包(自建 Go binary + 裝 user service),還是內附預建 binary? - 若要 1b,Neovim 路徑的 macOS/X11 故事怎麼辦(上游僅 Wayland)——打 patch,還是限縮成只用 Claude-CLI(1a)?
- 把反向 tunnel 的
RemoteForward包進受管的 SSH 設定,還是留成各主機本地?
外部參考¶
- claude-ssh-image-skill (ccimgd/ccimg) · MIT
- sshimg.nvim · MIT
- 文章:Paste clipboard images into Claude Code over SSH
- 文章:Introducing sshimg.nvim
- Clipport · 說明文
- Invoke — 把截圖貼進終端機
- Claude Code in VS Code · Claude Code on the web
相關文件¶
clipboard.md— OSC 52 文字剪貼簿同步(文字那一半;說明為何圖片無法搭 OSC 52)tmux/README.md—allow-passthrough/ 終端機圖片顯示面aicapture.md— 文字 scrollback → agent 的擷取層(相鄰的「餵 context 給 agent」工具)