Summary
Claude Code cannot paste images via Ctrl+V when running over SSH in a headless Linux VM. This is because Claude Code shells out to xclip to read the clipboard, but the VM has no display server (X11/Wayland), so xclip fails.
The fix: Claude Code should speak OSC 52 (text) and OSC 5522/Kitty clipboard protocol (images) directly, instead of shelling out to xclip. These escape sequences travel transparently through SSH — the user's terminal reads the local clipboard and responds.
Proof that it works
We built an xclip shim that speaks OSC 52/5522 and tested it end-to-end:
- ✅ Text clipboard via OSC 52 — works through SSH in Ghostty, iTerm2, Kitty
- ✅ Image clipboard via OSC 5522 — works through SSH in Kitty (
xclip -t image/png -o > file.png produces valid PNG)
- ✅ TARGETS query — Claude Code discovers
image/png is available and attempts to read it
- ❌ Race condition — Claude Code spawns
xclip as a subprocess that reads from /dev/tty. But Claude Code (a TUI app) also reads from the terminal. The response bytes get split between the two readers.
The race condition is unfixable from a subprocess. Both Claude Code and the xclip subprocess read from the same PTY. The terminal's response goes to whichever process reads first.
Proposed solution
Instead of:
Ctrl+V → spawn xclip subprocess → xclip opens /dev/tty → race condition
Do:
Ctrl+V → Claude Code sends OSC 5522 query directly → reads response from its own terminal fd → no race
Claude Code already owns the terminal. It should send the escape sequence and read the response itself, in-process. No subprocess needed.
Protocol details
Detection (from $TERM):
xterm-kitty / kitty* → OSC 5522 supported (images + text)
- Others with OSC 52 support → text only
OSC 52 text read:
Send: ESC ] 52 ; c ; ? BEL
Response: ESC ] 52 ; c ; <base64 text> BEL
OSC 5522 image read (Kitty clipboard protocol):
Send: ESC ] 5522 ; type=read ; <base64("image/png")> ST
Response: ESC ] 5522 ; type=read:status=OK ST
ESC ] 5522 ; type=read:status=DATA:mime=<b64 mime>;<b64 chunk> ST
...more DATA packets...
ESC ] 5522 ; type=read:status=DONE ST
Chunks are ≤4096 bytes pre-encoding. Full spec: https://sw.kovidgoyal.net/kitty/clipboard/
Terminal support
| Terminal |
OSC 52 (text) |
OSC 5522 (images) |
| Kitty |
✅ |
✅ |
| Ghostty |
✅ |
PR in progress |
| iTerm2 |
✅ |
❌ |
| WezTerm |
✅ |
❌ |
Impact
This is a growing use case — remote AI coding (Claude Code, Codex, Copilot) over SSH. As more terminals adopt OSC 5522 (Ghostty PR is active), this becomes the standard way to forward clipboard over SSH.
References
Summary
Claude Code cannot paste images via Ctrl+V when running over SSH in a headless Linux VM. This is because Claude Code shells out to
xclipto read the clipboard, but the VM has no display server (X11/Wayland), soxclipfails.The fix: Claude Code should speak OSC 52 (text) and OSC 5522/Kitty clipboard protocol (images) directly, instead of shelling out to
xclip. These escape sequences travel transparently through SSH — the user's terminal reads the local clipboard and responds.Proof that it works
We built an
xclipshim that speaks OSC 52/5522 and tested it end-to-end:xclip -t image/png -o > file.pngproduces valid PNG)image/pngis available and attempts to read itxclipas a subprocess that reads from/dev/tty. But Claude Code (a TUI app) also reads from the terminal. The response bytes get split between the two readers.The race condition is unfixable from a subprocess. Both Claude Code and the xclip subprocess read from the same PTY. The terminal's response goes to whichever process reads first.
Proposed solution
Instead of:
Do:
Claude Code already owns the terminal. It should send the escape sequence and read the response itself, in-process. No subprocess needed.
Protocol details
Detection (from
$TERM):xterm-kitty/kitty*→ OSC 5522 supported (images + text)OSC 52 text read:
OSC 5522 image read (Kitty clipboard protocol):
Chunks are ≤4096 bytes pre-encoding. Full spec: https://sw.kovidgoyal.net/kitty/clipboard/
Terminal support
Impact
This is a growing use case — remote AI coding (Claude Code, Codex, Copilot) over SSH. As more terminals adopt OSC 5522 (Ghostty PR is active), this becomes the standard way to forward clipboard over SSH.
References