Support OSC 52/5522 clipboard for image paste over SSH

Resolved 💬 2 comments Opened Apr 2, 2026 by MichielMAnalytics Closed Apr 2, 2026

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

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗