Every SSH session works
Open ten terminals to the same remote and code . works in all of them, with no port-forwarding conflicts.
Run code . on a remote Linux box and open it in VS Code on your own machine.
remote-code-bridge makes `code .` work in any SSH session to a Linux machine. One small bridge on your computer owns the tunnel, not any single terminal, so opening many sessions, closing them in any order, or losing the network doesn't break it: it reconnects on its own. It is pure Python with no dependencies, installs with `uv tool install`, and uninstalls without leaving anything behind. The bridge only listens on 127.0.0.1, and every request carries a random token.
Open ten terminals to the same remote and code . works in all of them, with no port-forwarding conflicts.
After sleep, network changes or a remote reboot it reconnects on its own; dead links are noticed within about 45 seconds.
Listens only on 127.0.0.1, uses a 64-character token that never appears on a command line, and passes only safe flags to VS Code.
Records exactly what it installed, so remote-code-bridge uninstall removes it on both machines and leaves your SSH config alone.
Yes. remote-code-bridge is free to use and open source. The full source code is on GitHub at https://github.com/kshitizwagle/remote-code-bridge.
remote-code-bridge runs on Windows, macOS, and Linux.
Get the source from https://github.com/kshitizwagle/remote-code-bridge; the README there covers installation and usage.
remote-code-bridge is in stable · v2.1.0 and was last updated on 13 Oct 2026. Report problems on GitHub: https://github.com/kshitizwagle/remote-code-bridge/issues.
No. remote-code-bridge was built with AI assistance and is provided as is, without warranty. Kshitiz Wagle is not liable for damage or loss. Use it at your own risk.
remote-code-bridge is built and maintained by Kshitiz Wagle, a software engineer in Lalitpur, Nepal. Role: Author; built with AI coding agents (disclosed in the README). Portfolio: https://kshitizwagle.com.np.
Run code . on a Linux machine you reached through SSH, and that directory opens in VS Code on your Windows, macOS, or Linux machine.
Disclaimer: this project, its code, tests, and documentation, was written by AI coding agents. Read the code and the security notes before you rely on it.
remote: code . → SSH tunnel → bridge on your machine → code --remote ssh-remote+devbox /remote/pathuv tool install remote-code-bridge
remote-code-bridge install devboxcode . works in all of them. No more "remote port forwarding failed for listen port" errors.code commands at the same moment queue up for an instant instead of failing.code. code ., code some/dir, code -r / --reuse-window, code -n / --new-window, code -g file:line / --goto. Relative paths and .. are resolved on the remote.uv tool install remote-code-bridge (or pip install) from PyPI. One command then sets up the remote, and the remote only needs python3.remote-code-bridge serve yourself when you want it.remote-code-bridge uninstall removes exactly that, on both machines, and leaves everything that was there before.~/.ssh/config (following Include files), asks which one when several different remotes are reachable, and treats aliases that reach the same machine (say devbox and devbox.lan) as one. ProxyCommand/ProxyJump jump hosts are fine.~/.ssh/config. Installations from version 1 are cleaned up automatically.127.0.0.1. On the remote, the tunnel is a socket in a directory only your account can open. Every request carries a random 64-character token that never appears on a command line. VS Code is started without a shell, and only safe flags are passed through. See Security.code command in PATH, and the Remote - SSH extension.python3 3.8+.ssh-add; on Windows start the OpenSSH Authentication Agent service first). The bridge connects by itself, so it can't type a password.uv tool install remote-code-bridge
remote-code-bridge install devboxReplace devbox with your SSH alias from ~/.ssh/config, or leave it out to let the installer find a reachable Linux alias. It asks whether to start the bridge automatically when you log in; answer up front with --service or --no-service. It then checks end to end that code . will work.
Then, in any SSH session on the remote:
cd ~/project
code .If you chose not to install the service, keep remote-code-bridge serve running on your machine while you work.
<summary>Without uv</summary>
python3 -m pip install --user remote-code-bridge
remote-code-bridge install devboxpipx install remote-code-bridge works too. To pin a version, install remote-code-bridge==2.1.0. To run unreleased code, install git+https://github.com/kshitizwagle/remote-code-bridge instead.
| Where | What |
|---|---|
| Remote | ~/.local/bin/remote-code-bridge (a single-file copy of the program), a ~/.local/bin/code link to it, ~/.config/remote-code-bridge/ (settings and the install record), a socket directory (~/.cache/remote-code-bridge/, or under $XDG_RUNTIME_DIR or /tmp), and a ~/.local/bin PATH line in your shell startup file. It refuses to replace a code command that isn't its own. |
| Your machine | ~/.config/remote-code-bridge/ (settings and the install record), a log directory, and, if you chose it, the login service. The remote-code-bridge command itself belongs to uv or pip. |
| Both | A random 64-character token shared by the two sides. It travels to the remote over SSH standard input, never on a command line. |
Re-running remote-code-bridge install is always safe: it keeps your token, settings, and service choice.
remote-code-bridge status # either machine: is the bridge running, is the tunnel up?
remote-code-bridge serve # run the bridge yourself (if you didn't choose the service)
remote-code-bridge update # upgrade the package, update the remote, restart the service
remote-code-bridge uninstall # remove everything it installed, here and on the remoteupdate asks PyPI for the latest release and, if it is newer than what you run, installs it with whatever installed it (uv or pip), then re-runs install for the saved alias. Prefer it to uv tool upgrade remote-code-bridge, which upgrades only your machine: the remote keeps the old version until you run remote-code-bridge install again. An installation from the GitHub URL moves to PyPI on its first update. On Windows it finishes in a new window, because a running program can't replace its own files there.
uninstall lists what it will remove and asks before doing it (--yes skips the question). It removes the service, then the remote side over SSH, then your machine's side. If the remote can't be reached it stops and changes nothing; --host-only cleans just your machine (then run ~/.local/bin/remote-code-bridge uninstall on the remote yourself). The program itself is uv's or pip's to remove, and the last step tells you how:
uv tool uninstall remote-code-bridgeComing from version 1: install with uv tool install --force remote-code-bridge (--force replaces the old remote-code-bridge command), then run remote-code-bridge install. It keeps your token and removes version 1's RemoteForward include from ~/.ssh/config.
| You see | Do this |
|---|---|
no tunnel from your host on the remote | Run remote-code-bridge status on your machine. It must be awake and logged in, and the bridge must be running (the service, or remote-code-bridge serve). |
tunnel: auth_failed | The bridge can't log in without a prompt: ssh-add your key (Windows: start the OpenSSH Authentication Agent service), then check ssh -o BatchMode=yes devbox true. |
tunnel: backoff with a forwarding error | The remote sshd must allow forwarding to Unix sockets (AllowStreamLocalForwarding yes, the default; no DisableForwarding). |
token: rejected | Run remote-code-bridge install again from your machine. |
remote-code-bridge: command not found after uv tool install | Run uv tool update-shell and open a new terminal. |
Logs: ~/.local/state/remote-code-bridge/bridge.log (Linux), ~/Library/Logs/remote-code-bridge.log (macOS), %LOCALAPPDATA%\remote-code-bridge\bridge.log (Windows).
127.0.0.1:39731 on your machine and keeps one SSH connection to the remote: ssh -N -R ~/.cache/remote-code-bridge/bridge.sock:127.0.0.1:39731 devbox. That puts a Unix socket on the remote, in a directory only you can open, that leads back to the bridge.code . on the remote resolves the path, notes whether it is a folder, and sends an authenticated POST /open through that socket.code --folder-uri vscode-remote://ssh-remote+devbox/path (or --file-uri) without a shell.See Architecture and Security for details.
uv run --with pytest --with pytest-cov python -m pytest # unit and integration tests (fake ssh, no network)
uvx ruff check . && uvx ruff format --check .
./scripts/smoke-test.sh # the single-file copy sent to remotes: serve + code
./scripts/native-linux-install-update-test.sh # Docker, real sshd: install, sessions, update, uninstall
uv tool install --force . # try your working copy as the real commandRun the pieces by hand without installing (REMOTE_CODE_BRIDGE_TUNNEL=0 skips the SSH tunnel; the client then uses TCP 127.0.0.1:PORT):
export REMOTE_CODE_BRIDGE_TOKEN="$(python3 -m remote_code_bridge generate-token)"
REMOTE_CODE_BRIDGE_DRY_RUN=1 REMOTE_CODE_BRIDGE_TUNNEL=0 REMOTE_CODE_BRIDGE_DEFAULT_HOST=devbox \
python3 -m remote_code_bridge serve
# another terminal, same token:
REMOTE_CODE_BRIDGE_HOST_ALIAS=devbox python3 -m remote_code_bridge open .Configuration lives in ~/.config/remote-code-bridge/host.env and remote.env; non-empty REMOTE_CODE_BRIDGE_* environment variables override them. Don't set a different REMOTE_CODE_BRIDGE_TOKEN in your shell for an installed setup; it would override the saved one.
Releases: bump version in pyproject.toml and __version__ in remote_code_bridge/__init__.py (a test fails if they differ), then push a v* tag (or use Actions → release → Run workflow). The workflow tests that commit, checks both versions match the tag, builds with uv build, publishes to PyPI through trusted publishing, and attaches the wheel and sdist to a GitHub release. Users get it with remote-code-bridge update, which only ever installs published releases. To test unreleased changes end to end, run RCB_PACKAGE_SPEC=/path/to/checkout remote-code-bridge update.
MIT