Clip to Claude
Paste images from your macOS or Windows clipboard into Claude Code running on a remote server over VS Code's Remote-SSH.
Copy a screenshot, press the shortcut in the terminal, and Claude Code receives it as a real image — not a file path it has to go and read.
Why you need it
Claude Code can already read your clipboard when you press Ctrl+V — but only when it is running on the same machine as the clipboard. Connect to a server over Remote-SSH and that stops working: the CLI is now on Linux, and your own computer's clipboard does not exist there.
This extension closes that gap. It runs on your own computer, grabs the image, sends it to the server over the SSH connection VS Code already has open, and hands the path to Claude Code.
Requirements
- A macOS or Windows computer running VS Code
- VS Code 1.125 or newer
- Connected to your server with Remote-SSH, with a folder or a file open there
- The extension installed locally, not on the server
That last point matters and the extension enforces it: it has to run on your machine to reach your clipboard. In the Extensions view it will show under Local — Installed even while you are connected to a server. That is correct.
Opening a normal local VS Code window and typing ssh into a terminal will not work. The image travels through VS Code's own connection, so a local window would write the file to your own computer and hand Claude Code a path that does not exist on the server.
Installing
Install from the Marketplace, or:
code --install-extension lamkashingpaul.clip-to-claude
It installs on your own computer, and only there — the extension declares that it must run locally, so VS Code will not offer to put it on the server even while you are connected to one. In the Extensions view it appears under Local — Installed. That is correct, and it is what lets the extension see your clipboard.
Nothing needs installing on the server.
A short walkthrough opens after installing. To reopen it later, run Welcome: Open Walkthrough… from the Command Palette and pick Get started with Clip to Claude.
Usage
- Copy an image
- Click into the terminal running Claude Code
- Press
Cmd+Alt+V on a Mac, or Ctrl+Alt+Shift+V on Windows
Claude Code shows [Image [#1](https://github.com/lamkashingpaul/clip-to-claude/issues/1)]. Keep typing your question around it — the image is inserted wherever your cursor is, and you can add more than one.
If you see a file path as plain text instead of [Image [#1](https://github.com/lamkashingpaul/clip-to-claude/issues/1)], something went wrong; see Troubleshooting.
What you can copy
If your own computer treats it as an image, it works.
| What you copied |
What happens |
A screenshot — Cmd+Ctrl+Shift+4, or Win+Shift+S and PrintScreen |
Sent as a PNG |
| An image from Chrome, Edge, Safari, Figma, Slack, Preview or Photos |
Sent as a PNG, keeping transparency when the app offers it |
| An image file selected in Finder or File Explorer |
Sent exactly as it is on disk, so a JPEG stays a JPEG |
| A file that is not an image |
Refused, with a message naming the file. Nothing is sent |
| Text, or an empty clipboard |
"No image on the clipboard" |
Your clipboard is never modified. After pasting a screenshot into Claude Code you can still paste the same screenshot into Slack, a document, or anywhere else.
Privacy
Reading someone's clipboard is an intrusive thing for an extension to do, so it is worth being precise about what this one does.
- Your clipboard is read only when you ask. Pressing the shortcut or running one of the commands reads it; nothing else does. It is not polled in the background and not touched when VS Code starts.
- Your image goes to your server and nowhere else, through the SSH connection VS Code already has open. There is no upload, no intermediate service and no account.
- The extension makes no network requests of its own. No telemetry, no analytics, no update checks, no third parties.
- Your clipboard is never overwritten. The one thing that would change it — the Copy Path button offered when no terminal is open — only acts if you click it.
- Images stay on your server, in
clipToClaude.imageDirectory, and are deleted after clipToClaude.retentionDays.
Commands
| Command |
macOS |
Windows |
What it does |
| Paste Clipboard Image into Terminal |
Cmd+Alt+V in a terminal |
Ctrl+Alt+Shift+V in a terminal |
The main workflow |
| Insert Clipboard Image Path at Cursor |
Cmd+Alt+V in an editor |
Ctrl+Alt+Shift+V in an editor |
Writes the file path into a document instead |
| Run Clipboard Diagnostics |
— |
— |
Reports what the extension can see, for when something is not working |
To change a shortcut, use VS Code's Keyboard Shortcuts editor. (There is deliberately no shortcut setting — VS Code cannot take keybindings from configuration, and a setting that quietly did nothing would be worse than none.)
The Windows shortcut avoids Ctrl+Alt+V on purpose. On many European keyboard layouts AltGr arrives as Ctrl+Alt, and a shortcut there would win over the character you were trying to type — which is why VS Code ships no Ctrl+Alt defaults of its own.
Settings
| Setting |
Default |
What it does |
clipToClaude.imageDirectory |
/tmp/clip-to-claude |
Where images are written on the server. Claude Code copies the image into the conversation as soon as you paste, so deleting these files later never breaks an image you already sent. |
clipToClaude.retentionDays |
7 |
Old images are cleaned up after each successful paste. 0 keeps them forever. |
clipToClaude.maxImageMegabytes |
10 |
Refuses very large images rather than appearing to hang while they upload. |
clipToClaude.captureTimeoutMs |
15000 |
How long to wait for the clipboard helper. Starting PowerShell from cold can take a second or more on a Windows machine with aggressive anti-virus. |
clipToClaude.osascriptTimeoutMs was renamed to clipToClaude.captureTimeoutMs in 1.1.0, now that the helper is not always osascript. A value set under the old name is still honoured.
Troubleshooting
Run Clip to Claude: Run Clipboard Diagnostics from the Command Palette — it prints what the extension can see to its output channel.
| Message |
What to do |
| "No image on the clipboard" |
You copied text, a non-image, or nothing. Copy an image and retry. |
| "The clipboard holds a file Claude Code cannot read as an image" |
You copied a file that is not a PNG, JPEG, GIF or WebP. Open it and copy the image itself. |
| "This window is not connected to a remote" |
You are in a local VS Code window. Connect with Remote-SSH — running ssh in a terminal is not the same thing. |
| "Nothing identifies which host to write to" |
You are connected but nothing is open. Open a folder, or just one file on the server. |
| "No active terminal" |
Open the terminal running Claude Code first. |
A plain file path appears instead of [Image [#1](https://github.com/lamkashingpaul/clip-to-claude/issues/1)] |
The image reached the server but Claude Code did not attach it. Please open an issue with the diagnostics output. |
Questions
I use the Claude Code sidebar, not the terminal. Do I need this?
No. The sidebar already accepts pasted images over Remote-SSH, because it runs inside your local VS Code window and receives the paste directly. This extension exists for people who run Claude Code in the terminal, where that is not possible.
Do images pile up on my server?
They are deleted after seven days by default, and the default location is /tmp, which most systems clear on reboot. Cleanup can never affect an image you already sent: Claude Code copies it into the conversation the moment you paste, so the file on disk stops mattering immediately.
Does it work with Dev Containers, WSL or Codespaces?
It is built and tested against Remote-SSH. The mechanism is not SSH-specific and should apply to any VS Code remote, but nothing else has been tested — reports welcome.
Does it work in Cursor, Windsurf or other VS Code forks?
Untested. It uses only public VS Code APIs, so there is a good chance it does. Please say so either way.
Linux client?
Not yet. macOS and Windows clients are both supported; only the clipboard-reading step is platform-specific, and it sits behind an interface, so Linux is one more file plus one branch.
Will macOS ask me for permission?
No. The extension reads the clipboard through AppKit without sending Apple events, which is what would otherwise trigger an automation prompt.
Does it run PowerShell on Windows?
Yes — one bundled script, resources/windows/capture-clipboard-image.ps1, launched with -NoProfile and no console window. It reads the clipboard, writes the image to a temporary file, and prints a single status line. It takes nothing from the command line and makes no network requests. If your machine's Group Policy forbids running script files, the extension re-runs the same script as an encoded command, which policy does not apply to.
How it works
Not needed to use the extension — this is here for the curious, and because several of these details are less obvious than they look.
Getting the path into Claude Code. Claude Code only turns a path into an image when it arrives as a paste. The same characters typed one at a time stay ordinary text. VS Code's extension API has no way to ask for a paste, so the extension wraps the path in the terminal's bracketed-paste markers by hand and writes it straight to the terminal. That is the whole of what it sends: Claude Code spaces consecutive [Image #N] chips itself, so the extension adds nothing around the paste.
Reading the clipboard on macOS. macOS offers several ways to do this, and the obvious one is not good enough: AppleScript's clipboard access cannot see images copied from Chrome, Figma, Slack or any other Chromium-based app. So the extension asks AppKit directly, which handles those as well as PNG, TIFF, JPEG and HEIC. It reads the clipboard without sending Apple events, so macOS never asks you to grant automation permission.
Reading the clipboard on Windows. A bundled PowerShell script, rather than a native module — there is nothing to compile and nothing to keep in step with Electron's ABI. It prefers the registered PNG clipboard format, which browsers and Electron apps publish alongside the older bitmap formats: those bytes are byte-exact and the only ones that keep an alpha channel, because Windows' DIB alpha is premultiplied and readers disagree about how to interpret it. A copied file is passed through untouched, and anything else — a PrintScreen capture, a Snipping Tool snip — is re-encoded to PNG.
Whichever platform it came from, the file's extension is decided by looking at the image's own leading bytes rather than by trusting the helper, so nothing that is not an image can reach a file named .png.
Why a folder or file has to be open. Images are written to an absolute path that has nothing to do with your project, so the workspace is not the point. VS Code will tell an extension the kind of remote it is connected to but never which remote, and that has to come from a URI that already points at the server — a workspace folder, the terminal's working directory, or any open file. A window containing nothing but a terminal that launched straight into Claude Code offers none of these, which is why one open file is enough to fix it.
Development
The extension runs on your own computer, so work from a local clone:
git clone https://github.com/lamkashingpaul/clip-to-claude.git
cd clip-to-claude
pnpm install
Press F5 to open a development window running your build, then connect that window to the server with Connect Current Window to Host… and open a folder on it. Connecting the current window rather than a new one is what keeps your build loaded; CONTRIBUTING.md explains how to confirm it stayed.
pnpm run compile # tsc
pnpm run lint # biome
pnpm test # 45 tests; launches VS Code, so it needs a GUI
pnpm run package # builds the .vsix
pnpm run install-local # installs the .vsix you just built
To test what users actually install:
pnpm run package && pnpm run install-local
The build always writes to the same clip-to-claude.vsix, so install-local cannot pick up a stale one. Naming the file by hand silently reinstalls the previous build the first time you bump the version, which is a confusing thing to debug.
The clipboard helpers live in resources/ rather than src/, because .vscodeignore excludes src/** and they would otherwise be missing from the packaged extension while still working under F5. The extension checks for the one it needs at startup and logs an error if it has gone astray.
Neither helper can be exercised on the other platform: the macOS one needs a real pasteboard with an image on it, and the Windows one needs a Windows clipboard. A clean tsc says nothing about either. CONTRIBUTING.md has the manual pass for both.
Known limitations
- macOS and Windows clients only. Linux is not supported yet. The clipboard code is isolated behind an interface, so adding it disturbs nothing else.
- The server must be Linux or macOS. Both the image directory and the pasted path have to be absolute POSIX paths, so a Windows server is refused with a clear message rather than handled incorrectly. This is deliberate — VS Code never tells an extension which operating system the remote runs, so supporting it would mean guessing.
- The extension cannot tell whether the terminal you are in is actually running Claude Code. Paste into an ordinary shell and the path is typed at the prompt, but never executed.
- Images go to
/tmp by default and do not survive a reboot. Point clipToClaude.imageDirectory somewhere else to keep them.
- Running Claude Code on your own computer rather than a server? You do not need this —
Ctrl+V already works. On Windows the extension refuses outright, because the path it hands Claude Code is a POSIX one and a local Windows target could never match it.
License
MIT