> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boat.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# VS Code, Cursor and SSH config

> Open a sandbox in VS Code Remote-SSH or Cursor with an ~/.ssh/config entry, and refresh the address and host key after each resume.

VS Code Remote-SSH and Cursor use the normal OpenSSH client. They read `~/.ssh/config`. The Boat CLI does not write that file. Use the script below to write one entry per sandbox.

<Warning>
  Each resume and each fork moves the sandbox to a new machine. The address and the SSH host key change. Run the script again after each resume.
</Warning>

## Before you start

* An API key with the `ssh` action in `BOAT_API_KEY`. Read [API keys](/api-keys).
* An SSH key pair at `~/.ssh/id_ed25519`. Create one with `ssh-keygen -t ed25519` if you have none.
* `curl` and `jq`.
* On Windows, run the script in Git Bash. VS Code reads the same `C:\Users\<you>\.ssh\config`.

## 1. Save the script

Save this as `boat-ssh-config.sh`:

```bash boat-ssh-config.sh theme={null}
#!/usr/bin/env bash
# Usage: bash boat-ssh-config.sh <sandbox-id>
# Authorizes ~/.ssh/id_ed25519 on the sandbox and writes ~/.ssh/boat/<id>.conf.
set -euo pipefail
id="$1"
key=~/.ssh/id_ed25519

resp="$(curl -fsS -X POST "https://boat.dev/api/v1/sandboxes/$id/sshkey" \
  -H "Authorization: Bearer $BOAT_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"key\":\"$(cat "$key.pub")\"}")"

# sshEndpoint ("host:port") is set when the sandbox has no public IPv4 of its own
endpoint="$(echo "$resp" | jq -r '.sshEndpoint // empty')"
if [ -n "$endpoint" ]; then
  host="${endpoint%:*}"; port="${endpoint##*:}"
else
  host="$(echo "$resp" | jq -r .machineIp)"; port=22
fi

mkdir -p ~/.ssh/boat
echo "$id $(echo "$resp" | jq -r .hostKey)" > ~/.ssh/boat/"$id".known_hosts
cat > ~/.ssh/boat/"$id".conf <<EOF
Host $id
  HostName $host
  Port $port
  User user
  IdentityFile "$key"
  HostKeyAlias $id
  UserKnownHostsFile "$HOME/.ssh/boat/$id.known_hosts"
  StrictHostKeyChecking yes
EOF
echo "Wrote ~/.ssh/boat/$id.conf"
```

## 2. Include the entries in your SSH config

Add this line at the **top** of `~/.ssh/config`, before any `Host` line:

```text ~/.ssh/config theme={null}
Include ~/.ssh/boat/*.conf
```

## 3. Write the entry and connect

```bash theme={null}
bash boat-ssh-config.sh bx_f7k2q9hd
ssh bx_f7k2q9hd true    # test: prints nothing and exits 0
```

* **VS Code**: install the Remote - SSH extension. Run **Remote-SSH: Connect to Host...** and pick `bx_f7k2q9hd`.
* **Cursor**: run **Remote-SSH: Connect to Host...** and pick `bx_f7k2q9hd`.
* Other tools that read `~/.ssh/config` work the same way.

Open the folder `/home/user/<your-repo>`.

## After a resume or a fork

1. Run `bash boat-ssh-config.sh <id>` again. It writes the new address and the new host key.
2. Reconnect the editor.

For a fork, use the id of the fork. Each sandbox gets its own entry.

If you skip step 1, SSH stops with `REMOTE HOST IDENTIFICATION HAS CHANGED` or cannot connect. Do not delete the key check. Run the script.

## Good to know

* An open editor does not delay auto-stop. To keep the sandbox up for a work day, run `boat extend <id> --hours 8`. Read [Auto-stop](/long-running-tasks/auto-stop).
* The editor installs its server in `/home/user/.vscode-server` or a similar folder. Snapshots keep it, so the next connection after a resume is faster.
* Your key stays authorized after a stop, a resume and a fork. The script authorizes it again anyway. This is safe.
* `boat ssh <id>` needs none of this. It finds the address and the host key itself.

## Related

* [SSH](/ssh-access)
* [Forward a port](/ssh-access#forward-a-port)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.