GitPedia

Cc clip

Paste images into remote Claude Code & Codex CLI over SSH — clipboard bridging for macOS and Windows.

From ShunmeiCho·Updated June 17, 2026·View on GitHub·

Paste images over SSH for Claude Code, Codex CLI, and opencode — plus desktop notifications for Claude Code, Codex CLI, opencode, and Antigravity. The project is written primarily in Go, distributed under the MIT License license, first published in 2026. Key topics include: ai-coding, anthropic, claude-code, cli, clipboard.

Latest release: v0.9.0
June 16, 2026View Changelog →
<p align="center"> <b>English</b> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a> </p> <p align="center"> <img src="docs/logo.png" alt="cc-clip logo" width="200"> </p> <h1 align="center">cc-clip</h1> <p align="center"> <b>Paste images over SSH for Claude Code, Codex CLI, and opencode — plus desktop notifications for Claude Code, Codex CLI, opencode, and Antigravity.</b> </p> <p align="center"> <a href="https://github.com/ShunmeiCho/cc-clip/releases"><img src="https://img.shields.io/github/v/release/ShunmeiCho/cc-clip?color=D97706" alt="Release"></a> <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT"></a> <a href="https://go.dev"><img src="https://img.shields.io/badge/Go-1.25+-00ADD8.svg" alt="Go"></a> <a href="https://github.com/ShunmeiCho/cc-clip/stargazers"><img src="https://img.shields.io/github/stars/ShunmeiCho/cc-clip?style=social" alt="Stars"></a> </p> <p align="center"> <img src="docs/marketing/demo-quick.gif" alt="cc-clip demo" width="720"> <br> <em>Install → setup → paste. Clipboard works over SSH.</em> </p> <p align="center"> <b>What's new in v0.9.0:</b> per-target setup (<code>--claude</code> / <code>--codex</code> / <code>--opencode</code> / <code>--agy</code> / <code>--all</code>), plus notification wiring for Codex CLI, opencode, and Antigravity. <b>Upgrading from v0.8.x?</b> <code>--codex</code> is now <b>Codex-only</b> — use <code>--all</code> for Claude&nbsp;+&nbsp;Codex. See the <a href="docs/upgrading.md#upgrading-from-v08x-to-v090">upgrade guide</a>. </p>
<details> <summary><b>Table of Contents</b></summary> </details>

The Problem

When running Claude Code, Codex CLI, or opencode on a remote server via SSH, image paste often doesn't work and notifications don't reach you. The remote clipboard is empty — no screenshots, no diagrams. And when your coding agent finishes a task or needs approval, you have no idea unless you're staring at the terminal.

The Solution

text
Image paste: Claude Code (macOS): Mac clipboard → cc-clip daemon → SSH tunnel → xclip shim → Claude Code Claude Code (Windows): Windows clipboard → hotkey/send → SSH upload → remote file path → Claude Code Windows direct (unreleased): Windows clipboard → cc-clip daemon → SSH tunnel → xclip shim → Claude Code Codex CLI: Mac clipboard → cc-clip daemon → SSH tunnel → x11-bridge/Xvfb → Codex CLI opencode: local clipboard → cc-clip daemon → SSH tunnel → xclip/wl-paste shim → opencode Notifications (Claude Code + Codex CLI + opencode + Antigravity): Claude Code hook → cc-clip-hook → SSH tunnel → local daemon → macOS/cmux notification Codex notify → cc-clip notify → SSH tunnel → local daemon → macOS/cmux notification opencode idle → cc-clip plugin run opencode-notify → SSH tunnel → local daemon → macOS/cmux notification Antigravity stop → cc-clip-notify agy plugin → SSH tunnel → local daemon → macOS/cmux notification

One tool. No changes to Claude Code, Codex, opencode, or Antigravity. Clipboard paste works for Claude Code, Codex CLI, and opencode; notifications are wired for all four (Antigravity is notify-only).

This is still an SSH clipboard bridge, not magic. Setup intentionally touches SSH config, installs remote clipboard shims, and relies on RemoteForward; the Troubleshooting section documents the SSH and shell gotchas cc-clip knows about.

Prerequisites

  • Local machine: macOS 13+ or Windows 10/11
  • Remote server: Linux (amd64 or arm64) accessible via SSH
  • SSH config: You must have a Host entry in ~/.ssh/config for your remote server
  • Remote clipboard path: xclip for X11 consumers, wl-paste for Wayland consumers, or Xvfb when using Codex CLI with --codex or --all

If you don't have an SSH config entry yet, add one:

# ~/.ssh/config
Host myserver
    HostName 10.0.0.1       # your server's IP or domain
    User your-username
    IdentityFile ~/.ssh/id_rsa  # optional, if using key auth

If you are on Windows and want the SSH/Claude Code workflow, use the dedicated guide:

Quick Start

Step 1: Install cc-clip

macOS / Linux:

bash
curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | sh

Windows:

Follow the dedicated guide:

Windows support is experimental. The default Windows workflow remains the
explicit send/hotkey upload path. The SSH RemoteForward + remote shim
path is not included in the latest stable release. Test it only
from a source build of a commit that includes this feature, or from a later
prerelease/release whose changelog explicitly mentions Windows direct clipboard
support.

On macOS / Linux, add ~/.local/bin to your PATH if prompted:

bash
# Add to your shell profile (~/.zshrc or ~/.bashrc) export PATH="$HOME/.local/bin:$PATH" # Reload your shell source ~/.zshrc # or: source ~/.bashrc

Verify the installation:

bash
cc-clip --version

macOS "killed" error? If you see zsh: killed cc-clip, macOS Gatekeeper is blocking the binary. Fix: xattr -d com.apple.quarantine ~/.local/bin/cc-clip

Step 2: Setup (one command)

bash
cc-clip setup myserver

This single command handles everything:

  1. Installs local dependencies (pngpaste)
  2. Configures SSH (RemoteForward, ControlMaster no)
  3. Starts the local daemon (via macOS launchd)
  4. Deploys the binary and shim to the remote server
<details> <summary>See it in action (macOS)</summary> <p align="center"> <img src="docs/marketing/demo-macos.gif" alt="cc-clip macOS demo" width="720"> </p> </details>

Which setup command do I run?

Pick the row that matches your remote workflow. These are the only decisions you need to make:

Your remote CLICommandWhat it addsRemote sudo needed?
Claude Code (default)cc-clip setup myserverxclip / wl-paste shim❌ No
Codex CLI onlycc-clip setup myserver --codexCodex only — Xvfb + x11-bridge on the remote, no Claude shim (see below)Yes — passwordless sudo for apt/dnf install xvfb, or run it manually first
Claude Code + Codex CLIcc-clip setup myserver --allClaude shim plus Codex (Xvfb + x11-bridge)Yes — same Xvfb requirement as --codex
opencodecc-clip setup myserver (paste); add --opencode for idle notificationsxclip / wl-paste shim, plus opencode-notify when --opencode is set❌ No
Antigravity (agy)cc-clip setup myserver --agyagy-notify plugin (notify-only)❌ No
Windows local machineSee Windows Quick Starthotkey/send upload path by default; unreleased direct remote shim path is source/prerelease testing only❌ No

Upgrading from v0.8.x? --codex changed meaning. In v0.8.x it added Codex on top of the Claude shim; in v0.9.0 it installs Codex only. To get both Claude and Codex on one host, use --all. Full notes: Upgrading from v0.8.x to v0.9.0.

Prerequisite for Codex targets (--codex or --all — the two rows above that need sudo): Xvfb must be installed on the remote. cc-clip setup with a Codex target will try sudo apt install xvfb (Debian/Ubuntu) or sudo dnf install xorg-x11-server-Xvfb (RHEL/Fedora) for you — but if passwordless sudo isn't available, it aborts and prints the exact command to run manually. Re-run the same Codex-target command after you've installed Xvfb.

If your remote permits neither passwordless sudo nor a one-off manual install, stick with cc-clip setup myserver (without --codex). Clipboard paste still works for Claude Code and opencode; only the Codex CLI path needs Xvfb.

Rule of thumb: Add a Codex target (--codex for Codex-only, or --all for Claude + Codex) only if you actually run Codex CLI on the remote. It is otherwise unnecessary overhead.

Step 3 (Codex CLI only): what --codex adds

Codex CLI reads the clipboard via X11 directly (through the arboard crate) rather than shelling out to xclip, so the transparent shim cannot intercept it. --codex closes that gap by adding, on the remote:

  1. Xvfb — a headless X server. Requires sudo: cc-clip tries sudo apt install xvfb or sudo dnf install xorg-x11-server-Xvfb automatically if you have passwordless sudo. If not, it aborts with the exact command to run manually, then you re-run the same Codex-target command (--codex for Codex-only, or --all if this host also runs Claude Code).
  2. cc-clip x11-bridge — a background process that claims the Xvfb clipboard and serves image data on demand, fetched through the same SSH tunnel as the Claude Code path.
  3. DISPLAY=127.0.0.1:N — an injection into your shell rc on the remote, so Codex's next process picks it up automatically. (TCP-loopback form, not the Unix-socket :N form, because Codex CLI's sandbox blocks /tmp/.X11-unix/.)

You do not need to understand any of this to use Codex paste — it's listed so you know what --codex touches on your server and how to diagnose it later.

<details> <summary>Windows local? Use the dedicated guide</summary> <p align="center"> <img src="docs/marketing/demo-windows.gif" alt="cc-clip Windows demo" width="720"> </p>

Note: Windows defaults to the hotkey/upload workflow. The Windows guide
documents the SSH RemoteForward + remote shim workflow as an unreleased
experimental option for source/prerelease testing only.

</details>

Step 4: Connect and use

Open a new SSH session to your server (the tunnel activates on SSH connection):

bash
ssh myserver

Then use Claude Code, Codex CLI, or opencode as normal — Ctrl+V (or whatever the agent binds to clipboard paste) now pastes images from your Mac clipboard.

Important: The image paste works through the SSH tunnel. You must connect via ssh myserver (the host you set up). The tunnel is established on each SSH connection.

Verify it works

Generic end-to-end check from your local machine (works for Claude Code, Codex, and opencode):

bash
# Copy an image to your Mac clipboard first (Cmd+Shift+Ctrl+4), then: cc-clip doctor --host myserver

Codex-specific verify

If you used --codex or --all, these four commands on the remote server confirm the Codex-specific components are healthy. Copy an image on your Mac first, then SSH in:

bash
ssh myserver # 1. DISPLAY is injected echo $DISPLAY # expected: 127.0.0.1:0 (or :1, :2, …) # 2. Xvfb is running ps aux | grep Xvfb | grep -v grep # 3. x11-bridge is running ps aux | grep 'cc-clip x11-bridge' | grep -v grep # 4. Clipboard negotiation works end-to-end xclip -selection clipboard -t TARGETS -o # expected: image/png

If any step fails, the most common fix is cc-clip connect myserver --codex --force (use --all --force if this host also runs Claude Code) from your local machine — see the full recipe under Troubleshooting → "Ctrl+V doesn't paste images (Codex CLI)".

setup vs connect — which to run when

You only need to know these three moves. For a host that also runs Codex CLI, use --all (Claude + Codex) in place of the plain command; use --codex instead if you want that host to be Codex-only.

SituationCommand (Claude Code only)Command (also running Codex CLI)
First-time install on this hostcc-clip setup myservercc-clip setup myserver --all
Broken state (DISPLAY empty, x11-bridge missing, tunnel won't probe)cc-clip connect myserver --forcecc-clip connect myserver --all --force
Daemon rotated token and the remote still has the old onecc-clip connect myserver --token-onlycc-clip connect myserver --token-only

setup is the first-time path (deps + SSH config + daemon + deploy). connect is the repair/redeploy path — same deploy steps, but it assumes SSH config and the local daemon are already in place.

On Windows, the equivalent quick check is:

Why cc-clip?

ApproachWorks over SSH?Any terminal?Image support?Setup complexity
Native Ctrl+VLocal onlySomeYesNone
X11 ForwardingYes (slow)N/AYesComplex
OSC 52 clipboardPartialSomeText onlyNone
cc-clipYesYesYesOne command

How It Works

mermaid
graph LR subgraph local ["Local Mac"] A["Clipboard"] --> B["pngpaste"] B --> C["cc-clip daemon<br/>127.0.0.1:18339"] end subgraph win ["Local Windows"] J["Clipboard"] --> N["cc-clip hotkey / send<br/>(default)"] J -. "experimental direct" .-> K["cc-clip daemon<br/>127.0.0.1:18339"] end subgraph remote ["Remote Linux"] F["Claude Code"] -- "Ctrl+V" --> E["xclip / wl-paste shim"] M["opencode"] -- "Ctrl+V" --> E E -- "curl" --> D["127.0.0.1:18339"] N -- "ssh upload + paste path" --> L["~/.cache/cc-clip/uploads"] L -- "remote image path" --> F G["Codex CLI"] -- "Ctrl+V / arboard" --> H["Xvfb CLIPBOARD"] H -- "SelectionRequest" --> I["x11-bridge"] I -- "HTTP" --> D end C == "SSH RemoteForward" ==> D K -. "experimental SSH RemoteForward" .-> D style local fill:#1a1a2e,stroke:#e94560,color:#eee style remote fill:#1a1a2e,stroke:#0f3460,color:#eee style A fill:#e94560,stroke:#e94560,color:#fff style F fill:#0f3460,stroke:#0f3460,color:#fff style G fill:#0f3460,stroke:#0f3460,color:#fff style M fill:#0f3460,stroke:#0f3460,color:#fff
  1. macOS Claude path: the local daemon reads your Mac clipboard via pbpaste / pngpaste, serves clipboard data over HTTP on loopback, and the remote xclip / wl-paste shim fetches text or images through the SSH tunnel
  2. opencode path: same shim as the Claude Code path — opencode reads the clipboard through xclip (X11) or wl-paste (Wayland), so cc-clip's shim transparently serves the local clipboard without any opencode-specific configuration
  3. Windows default path: the local hotkey / send --paste flow reads your Windows clipboard, uploads the image over SSH, pastes the remote file path into the active terminal, and restores the image clipboard afterward
  4. Windows experimental direct path: the local daemon reads your Windows clipboard through native Win32 clipboard APIs, serves text or images over HTTP on loopback, and the remote xclip / wl-paste shim fetches clipboard data through the SSH tunnel. This path is not included in the latest stable release.
  5. Codex CLI path: x11-bridge claims CLIPBOARD ownership on a headless Xvfb, serves images on-demand when Codex reads the clipboard via X11 (via the arboard crate, which cannot be shim-intercepted like xclip)
  6. Notification path: remote Claude Code hooks, Codex notify, opencode idle, and Antigravity stop events flow through cc-clip-hook / cc-clip notify / plugin → SSH tunnel → local daemon → macOS Notification Center or cmux

SSH Notifications

Remote hook events (Claude finishing, tool approval requests, image paste events, Codex task completion) travel through the same SSH tunnel as the clipboard and surface as native macOS / cmux notifications on your local machine. This solves the usual SSH notification failures — TERM_PROGRAM not forwarded, terminal-notifier absent on the remote, tmux swallowing OSC sequences.

EventNotification
Claude finishes responding"Claude stopped" + last message preview
Claude needs tool approval"Tool approval needed" + tool name
Codex task completes"Codex" + completion message
Image pasted via Ctrl+V"cc-clip #N" + fingerprint + dimensions

Coverage by CLI:

CLIWired by cc-clip connect?
Claude Code✅ Managed hooks in ~/.claude/settings.json
Codex CLI✅ If a Codex target (--codex/--all) is selected and ~/.codex/ exists
opencode✅ If --opencode/--all is selected and opencode is detected ¹
Antigravity (agy)✅ If --agy/--all is selected and agy is detected ¹

¹ "Wired" means cc-clip connect installs the integration. Plugin generation and runner paths are covered by tests, but host event delivery for opencode and Antigravity has not yet been smoke-verified on a representative host — please report issues.

Full setup, adapter details, manual fallback, nonce registration, and troubleshooting: docs/notifications.md.

Security

LayerProtection
NetworkLocal daemon binds loopback only (127.0.0.1); SSH exposes only a remote loopback tunnel
Clipboard authBearer token with 30-day sliding expiration (auto-renews on use)
Notification authDedicated nonce per-connect session (separate from clipboard token)
Args hygieneNeither the auth token nor the hook payload appears in command-line args (token via stdin, payload via a temp file)
Notification trustHook notifications marked verified; generic JSON shows [unverified] prefix
TransparencyManaged clipboard reads are intercepted; unrelated xclip / wl-paste calls pass through

On a shared remote host, loopback is still shared by local users on that host. The token file is written 0600, but cc-clip does not try to protect you from other users who can read your files, ptrace your processes, or otherwise act as your Unix account. See SECURITY.md for the explicit threat model.

For the Windows direct RemoteForward/shim path, the daemon token lets the remote
shim request the current local Windows clipboard text and image content
while the SSH tunnel is open. Use that path only with trusted remote hosts.

Daily Usage

After initial setup, your daily workflow is:

bash
# 1. SSH to your server (tunnel activates automatically) ssh myserver # 2. Use Claude Code or Codex CLI normally claude # Claude Code codex # Codex CLI # 3. Ctrl+V pastes images from your Mac clipboard

The local daemon runs as a macOS launchd service and starts automatically on login. No need to re-run setup.

Windows workflow

On Windows, the default workflow is the explicit hotkey/upload path. It is less
magical than the macOS/Linux direct shim model, but it is more predictable
across Windows Terminal, tmux, SSH clients, and Windows clipboard providers.

For first-time setup and day-to-day usage, use:

That guide documents the Windows direct RemoteForward + xclip/wl-paste shim
path as an unreleased experimental option for source/prerelease testing only.
Do not rely on it as the default until it has more real-world coverage across
Windows versions and clipboard providers. The daemon token lets the remote shim
request local Windows clipboard text and images while the SSH tunnel is open.

Commands

The 10 you'll actually use:

CommandDescription
cc-clip setup <host>Full setup: deps, SSH config, daemon, deploy
cc-clip setup <host> --codexFull setup, Codex CLI only (no Claude shim; use --all for both)
cc-clip connect <host> --forceRepair/redeploy (when DISPLAY, x11-bridge, or tunnel is stuck)
cc-clip connect <host> --token-onlySync rotated token without redeploying binaries
cc-clip doctor --host <host>End-to-end health check
cc-clip statusShow local component status
cc-clip service install / service uninstallManage macOS launchd daemon auto-start
cc-clip notify --title T --body BSend a generic notification through the tunnel
cc-clip send [<host>] [<file>] --pasteWindows: upload clipboard image or saved file and paste remote path
cc-clip hotkey [<host>]Windows: register the remote upload/paste hotkey

Full command reference, including all flags and environment variables: docs/commands.md. Or run cc-clip --help for the authoritative list from the installed binary.

Configuration

All settings have sensible defaults. Override via environment variables. Full list in docs/commands.md:

SettingDefaultEnv Var
Port18339CC_CLIP_PORT
Token TTL30dCC_CLIP_TOKEN_TTL
Debug logsoffCC_CLIP_DEBUG=1

Platform Support

LocalRemoteStatus
macOS (Apple Silicon / Intel)Linux (amd64/arm64)Stable
Windows 10/11Linux (amd64/arm64)Experimental (send / hotkey default; direct shim path unreleased/source/prerelease only)

Supported Remote CLIs

cc-clip works with any coding agent that reads the clipboard via xclip or wl-paste on Linux. No per-CLI configuration is needed — the transparent shim intercepts clipboard reads from any process that invokes these binaries.

CLIImage pasteNotifications
Claude Code✅ out of the box (xclip / wl-paste shim)✅ via cc-clip-hook in Stop / Notification hooks
Codex CLI✅ out of the box (Xvfb + x11-bridge; needs --codex or --all)✅ wired during cc-clip connect if a Codex target is selected and ~/.codex/ exists
opencode✅ out of the box (xclip shim on X11, wl-paste shim on Wayland)✅ wired during cc-clip connect with --opencode/--all (delivery not yet host-verified)
Any other xclip/wl-paste consumer✅ should just work — please open a discussion if it doesn't

cc-clip setup HOST installs the xclip and wl-paste shims regardless of which CLI you use; opencode picks them up automatically the next time it reads the clipboard.

Requirements

Local (macOS): macOS 13+ (pngpaste, auto-installed by cc-clip setup)

Local (Windows): Windows 10/11 with PowerShell, ssh, and scp available in PATH

Remote: Linux with SSH access, curl, bash, and at least one clipboard backend: xclip for X11 consumers or wl-paste for Wayland consumers. The macOS tunnel/shim path is auto-configured by cc-clip setup / cc-clip connect; the Windows tunnel/shim path is unreleased and experimental, and the Windows upload/hotkey path remains the default.

Remote (Codex targets --codex / --all): Additionally requires Xvfb. Auto-installed if passwordless sudo is available, otherwise: sudo apt install xvfb (Debian/Ubuntu) or sudo dnf install xorg-x11-server-Xvfb (RHEL/Fedora).

Alternatives and When Not to Use cc-clip

Use a simpler path when it fits:

  • VS Code Remote-SSH: use the editor's built-in clipboard behavior if your workflow already lives in VS Code.
  • OSC52: good for text clipboard sync, but not a reliable binary image paste path for these CLI agents.
  • scp or manual file upload: best when image paste is rare and preserving Ctrl+V is not worth extra setup.
  • General clipboard bridges such as lemonade or piknik: better if you want a broad, bidirectional clipboard system instead of a narrow agent image-paste bridge.
  • Untrusted shared jump hosts: avoid cc-clip if other local users on the remote host should not be able to reach a loopback tunnel protected only by your user-scoped token.

cc-clip is for the narrow case where you run coding agents over SSH and want image paste, plus optional notifications, to behave like a local session without changing the agent itself.

Troubleshooting

bash
# One command to check everything cc-clip doctor --host myserver

cc-clip: real claude binary not found in PATH after running v0.7.0

If you installed cc-clip v0.7.0 against a remote whose claude was installed via Anthropic's Native Installer (curl https://claude.ai/install.sh), v0.7.0 had a bug (#55) that overwrote the real claude binary at the symlink target. To recover:

cc-clip setup <host> --auto-recover

This detects the corrupted state, migrates the original binary back from ~/.local/bin/claude.cc-clip-bak, and installs the (fixed) v0.7.1+ wrapper. The --auto-recover flag is mutually exclusive with --token-only — they describe different intents.

If ~/.local/bin/claude.cc-clip-bak is missing on the remote, the binary cannot be recovered automatically. Reinstall Claude Code via curl https://claude.ai/install.sh and re-run cc-clip setup.

<details> <summary><b>"zsh: killed" after installation</b></summary>

Symptom: Running any cc-clip command immediately shows zsh: killed cc-clip ...

Cause: macOS Gatekeeper blocks unsigned binaries downloaded from the internet.

Fix:

bash
xattr -d com.apple.quarantine ~/.local/bin/cc-clip

Or reinstall (the latest install script handles this automatically):

bash
curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | sh
</details> <details> <summary><b>"cc-clip: command not found"</b></summary>

Cause: ~/.local/bin is not in your PATH.

Fix:

bash
# Add to your shell profile echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc source ~/.zshrc

Replace ~/.zshrc with ~/.bashrc if you use bash.

</details> <details> <summary><b>Ctrl+V doesn't paste images (Claude Code)</b></summary>

Step-by-step verification:

bash
# 1. Local: Is the daemon running? curl -s http://127.0.0.1:18339/health # Expected: {"service":"cc-clip","status":"ok"} # 2. Remote: Is the tunnel forwarding? ssh myserver "curl -s http://127.0.0.1:18339/health" # Expected: {"service":"cc-clip","status":"ok"} # 3. Remote: Is the shim taking priority? ssh myserver "which xclip" # Expected: ~/.local/bin/xclip (NOT /usr/bin/xclip) # 4. Remote: Does the shim intercept correctly? # (copy an image to Mac clipboard first) ssh myserver 'CC_CLIP_DEBUG=1 xclip -selection clipboard -t TARGETS -o' # Expected: image/png

If step 2 fails, you need to open a new SSH connection (the tunnel is established on connect).

If step 3 fails, the PATH fix didn't take effect. Log out and back in, or run: source ~/.bashrc

</details> <details> <summary><b>New SSH tab says "remote port forwarding failed for listen port 18339"</b></summary>

Symptom: A newly opened SSH tab warns remote port forwarding failed for listen port 18339, and image paste in that tab does nothing.

Cause: cc-clip uses a fixed remote port (18339) for the reverse tunnel. If another SSH session to the same host already owns that port, or a stale sshd child is still holding it, the new tab cannot establish its own tunnel.

Fix:

bash
# Inspect the remote port without opening another forward: ssh -o ClearAllForwardings=yes myserver "ss -tln | grep 18339 || true"
  • If another live SSH tab already owns the tunnel, use that tab/session, or close it before opening a new one.
  • If the port is stuck after a disconnect, follow the stale sshd cleanup steps below.
  • If you truly need multiple concurrent SSH sessions with image paste, give each host alias a different cc-clip port instead of sharing 18339.
</details> <details> <summary><b>Ctrl+V doesn't paste images (Codex CLI)</b></summary>

Most common cause: DISPLAY environment variable is empty. You must open a new SSH session after setup — existing sessions don't pick up the updated shell rc file.

Step-by-step verification (run these on the remote server):

bash
# 1. Is DISPLAY set? echo $DISPLAY # Expected: 127.0.0.1:0 (or 127.0.0.1:1, etc.) # If empty → open a NEW SSH session, or run: source ~/.bashrc # 2. Is the SSH tunnel working? curl -s http://127.0.0.1:18339/health # Expected: {"service":"cc-clip","status":"ok"} # If fails → open a NEW SSH connection (tunnel activates on connect) # 3. Is Xvfb running? ps aux | grep Xvfb | grep -v grep # Expected: a Xvfb process # If missing → re-run from local: cc-clip connect myserver --all --force (use --codex --force if Codex-only) # 4. Is x11-bridge running? ps aux | grep 'cc-clip x11-bridge' | grep -v grep # Expected: a cc-clip x11-bridge process # If missing → re-run from local: cc-clip connect myserver --all --force (use --codex --force if Codex-only) # 5. Does the X11 socket exist? ls -la /tmp/.X11-unix/ # Expected: X0 file (matching your display number) # 6. Can xclip read clipboard via X11? (copy an image on Mac first) xclip -selection clipboard -t TARGETS -o # Expected: image/png

Common fixes:

Step failsFix
Step 1 (DISPLAY empty)Open a new SSH session. If still empty: source ~/.bashrc
Step 2 (tunnel down)Open a new SSH connection — tunnel is per-connection
Steps 3-4 (processes missing)cc-clip connect myserver --all --force (or --codex --force if Codex-only) from local
Step 6 (no image/png)Copy an image on Mac first: Cmd+Shift+Ctrl+4

Note: DISPLAY uses TCP loopback format (127.0.0.1:N) instead of Unix socket format (:N) because Codex CLI's sandbox blocks access to /tmp/.X11-unix/. If you previously set up cc-clip with an older version, re-run cc-clip connect myserver --all --force (or --codex --force if Codex-only) to update.

</details> <details> <summary><b>Setup fails: "killed" during re-deployment</b></summary>

Symptom: cc-clip setup was working before, but now shows zsh: killed when re-running.

Cause: The launchd service is running the old binary. Replacing the binary while the daemon holds it open can cause conflicts.

Fix:

bash
cc-clip service uninstall curl -fsSL https://raw.githubusercontent.com/ShunmeiCho/cc-clip/main/scripts/install.sh | sh cc-clip setup myserver
</details> <details> <summary><b>More issues</b></summary>

See Troubleshooting Guide for detailed diagnostics, or run cc-clip doctor --host myserver.

</details>

Contributing

Contributions welcome! For bug reports and feature requests, open an issue.

For code contributions (building from source requires Go 1.25.10+, per go.mod):

bash
git clone https://github.com/ShunmeiCho/cc-clip.git cd cc-clip make build && make test
  • Bug fixes: Open a PR directly with a clear description of the fix
  • New features: Open an issue first to discuss the approach
  • Commit style: Conventional Commits (feat:, fix:, docs:, etc.)

Claude Code — Clipboard:

Claude Code — Notifications:

Codex CLI — Clipboard:

Codex CLI — Notifications:

opencode — Clipboard:

opencode — Notifications:

Terminal / Multiplexer:

License

MIT

Contributors

Showing top 4 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from ShunmeiCho/cc-clip via the GitHub API.Last fetched: 6/17/2026