# remote-code-bridge

> Run `code .` on a remote Linux box and open it in VS Code on your own machine.

- Price: free, open source
- Warranty: none; built with AI assistance and provided as is
- Platforms: Windows, macOS, Linux
- Status: Stable · v2.1.0
- Built with: Python 3.8+, OpenSSH, VS Code Remote-SSH, systemd, launchd, Task Scheduler, GitHub Actions
- Author: Kshitiz Wagle (https://kshitizwagle.com.np)
- Source: https://github.com/kshitizwagle/remote-code-bridge
- Page: https://projects.kshitizwagle.com.np/remote-code-bridge
- Last updated: 2026-10-13

## Overview

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.

## Highlights

- **Every SSH session works**: Open ten terminals to the same remote and `code .` works in all of them, with no port-forwarding conflicts.
- **Heals itself**: After sleep, network changes or a remote reboot it reconnects on its own; dead links are noticed within about 45 seconds.
- **Private by design**: 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.
- **Leaves no trace**: Records exactly what it installed, so `remote-code-bridge uninstall` removes it on both machines and leaves your SSH config alone.

## FAQ

### Is remote-code-bridge free?

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.

### What does remote-code-bridge run on?

remote-code-bridge runs on Windows, macOS, and Linux.

### How do I get remote-code-bridge?

Get the source from https://github.com/kshitizwagle/remote-code-bridge; the README there covers installation and usage.

### Is remote-code-bridge ready to use?

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.

### Is there a warranty or support for remote-code-bridge?

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.

### Who makes remote-code-bridge?

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.

## README

---

# remote-code-bridge

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](https://github.com/kshitizwagle/remote-code-bridge/blob/master/docs/SECURITY.md) before you rely on it.

```text
remote: code .  →  SSH tunnel  →  bridge on your machine  →  code --remote ssh-remote+devbox /remote/path
```

```sh
uv tool install remote-code-bridge
remote-code-bridge install devbox
```

## Features

- **Works from Windows, macOS, and Linux.** Your machine (where VS Code runs) can be any of the three; the remote is any Linux box you reach over SSH.
- **Every SSH session works, however many you open.** Open ten terminals to the same remote, close them in any order, let VS Code's own Remote-SSH connection come and go: `code .` works in all of them. No more "remote port forwarding failed for listen port" errors.
- **Heals itself.** One small bridge on your machine owns the tunnel, not any single terminal. After sleep, Wi-Fi changes, a dropped connection, or a remote reboot it reconnects on its own (dead links are noticed within about 45 seconds) and clears any leftover from the old connection first.
- **Handles bursts.** Many `code` commands at the same moment queue up for an instant instead of failing.
- **Feels like the real `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.
- **Installs like any Python tool.** `uv tool install remote-code-bridge` (or `pip install`) from PyPI. One command then sets up the remote, and the remote only needs `python3`.
- **Your choice of how it runs.** Let it start at login as a background service (a systemd user service on Linux, a launchd agent on macOS, a Scheduled Task on Windows that keeps running on battery with no time limit), or run `remote-code-bridge serve` yourself when you want it.
- **Uninstalls without a trace.** Each machine keeps a record of exactly what was installed: files, folders it had to create, lines added to shell startup files, the service. `remote-code-bridge uninstall` removes exactly that, on both machines, and leaves everything that was there before.
- **Knows your aliases.** Finds a reachable Linux remote in your `~/.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.
- **Leaves your SSH config alone.** Nothing is added to `~/.ssh/config`. Installations from version 1 are cleaned up automatically.
- **Private by design.** The bridge listens only on your machine's `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](https://github.com/kshitizwagle/remote-code-bridge/blob/master/docs/SECURITY.md).
- **Tiny and dependency-free.** Plain Python 3.8+, standard library only.

## Requirements

- **Your machine:** Python 3.8+, [uv](https://docs.astral.sh/uv/) (or pip), OpenSSH, VS Code with its `code` command in `PATH`, and the Remote - SSH extension.
- **The remote:** Linux with `python3` 3.8+.
- **SSH login without a prompt** from your machine to the remote: a key without a passphrase, or your key loaded into ssh-agent (`ssh-add`; on Windows start the *OpenSSH Authentication Agent* service first). The bridge connects by itself, so it can't type a password.

## Install

```sh
uv tool install remote-code-bridge
remote-code-bridge install devbox
```

Replace `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:

```sh
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>

```sh
python3 -m pip install --user remote-code-bridge
remote-code-bridge install devbox
```

`pipx 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.

### What installation sets up

| 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.

## Everyday commands

```sh
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 remote
```

`update` 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:

```sh
uv tool uninstall remote-code-bridge
```

**Coming 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`.

## Troubleshooting

| 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).

## How it works

1. The bridge listens on `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.
2. `code .` on the remote resolves the path, notes whether it is a folder, and sends an authenticated `POST /open` through that socket.
3. The bridge checks the token, alias, path, and flags, then starts `code --folder-uri vscode-remote://ssh-remote+devbox/path` (or `--file-uri`) without a shell.

See [Architecture](https://github.com/kshitizwagle/remote-code-bridge/blob/master/docs/ARCHITECTURE.md) and [Security](https://github.com/kshitizwagle/remote-code-bridge/blob/master/docs/SECURITY.md) for details.

## Development

```sh
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 command
```

Run 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`):

```sh
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`.

## License

MIT
