Claude Code Desktop SSH x WSL2 Hands-On Setup Guide for Windows¶
Key Points¶
- SSH configuration is required to fully connect Claude Code Desktop's GUI features (visual diff, parallel sessions, etc.) to your WSL2 development environment
- This guide walks through the pitfalls specific to Windows x WSL2 (port conflicts, network mode, missing binaries) one by one
- Once public key authentication is configured, you can connect with a single click without entering a password
Quick Reference¶
| Step | Task | Estimated Time |
|---|---|---|
| 1 | Update Claude Code Desktop | 5 min |
| 2 | Install OpenSSH Server on WSL2 | 2 min |
| 3 | Change network mode to mirrored | 5 min |
| 4 | Check and resolve port conflicts | 5 min |
| 5 | Start sshd | 1 min |
| 6 | Verify SSH connection from PowerShell | 3 min |
| 7 | Set up public key authentication (recommended) | 5 min |
| 8 | Connect from Claude Code Desktop | 3 min |
Introduction¶
The Code tab in Claude Code Desktop is a feature that lets you perform AI coding with direct access to the file system. It offers GUI features not available in the terminal-based Claude Code CLI, such as visual diff review, parallel sessions, and file attachments.
However, the Code tab's "local" mode operates on the Windows file system. If your development environment is on WSL2, you cannot work with WSL2 projects from the Code tab as-is.
This is where the SSH feature comes in. This article provides a hands-on walkthrough of setting up the SSH feature, using a local WSL2 connection as the target. The knowledge gained here -- key authentication, port configuration, and connection troubleshooting -- can be directly applied to connecting to cloud VMs and remote servers.
Why SSH into Local WSL2?¶
The question "Is there any point in SSH-ing into 127.0.0.1?" is natural. Technically, it uses the same mechanism as "remote connection to another machine" to fully connect Claude Code Desktop's GUI to the Linux environment that is WSL2.
flowchart LR
subgraph windows ["Windows"]
A["Claude Code Desktop<br/>(GUI)"]
end
subgraph wsl2 ["WSL2 Linux"]
B["Project<br/>Docker / Node / Python etc."]
end
A -- "File operations & code<br/>execution via SSH" --> BWhat this enables:
| Goal | Without SSH | With SSH |
|---|---|---|
| Edit code on WSL2 with AI | Terminal CLI only | Operable via Desktop GUI |
| Visual diff review of changes | Not available | Available |
| Parallel sessions for multiple tasks | Manual tmux etc. | Launch in parallel from GUI |
| Share context via file attachments | Not available | Available |
| Use Docker/Linux-specific tools | Available from CLI | Also available from GUI |
In short, this is the connection method for cases where your development environment is on WSL2, but you want to use Claude Code Desktop's GUI features. If you are comfortable with terminal operations and the CLI version suffices, this setup is unnecessary.
Applying to Cloud VM Connections
This article covers connecting to local WSL2, but the steps are nearly identical for connecting to cloud VMs or remote development servers. It is also useful as a dry run before deploying to remote targets.
Overall Flow¶
The following flowchart provides an overview of the entire setup and its branches.
flowchart TD
START([Start Setup]) --> A
A{"Claude Code Desktop<br/>up to date?"}
A -->|No| A1["Help -> Restart to update<br/>to latest version"]
A1 --> A2{"Does resources/<br/>contain<br/>claude-ssh/?"}
A2 -->|No| A3["Binary not bundled<br/>Wait for update"]
A2 -->|Yes| B
A -->|Yes| B
B{"Is openssh-server<br/>installed on<br/>WSL2?"}
B -->|No| B1["sudo apt install<br/>openssh-server"]
B1 --> C
B -->|Yes| C
C{"Is mirrored mode<br/>set in .wslconfig?"}
C -->|No| C1["Add setting -> wsl --shutdown"]
C1 --> D
C -->|mirrored| D
D{"Port 22<br/>conflict?"}
D -->|Yes| D1["Stop Windows SSH<br/>or change WSL2 port"]
D1 --> E
D -->|No| E
E["WSL2: sudo service ssh start"] --> F
F{"Can SSH connect<br/>from PowerShell?"}
F -->|Yes| G
F -->|No| F1["Troubleshoot based on error"]
F1 --> D
G["Set up key authentication (recommended)"] --> H
H["Claude Code Desktop<br/>SSH -> Configure connection"] --> DONE([Complete])
style START fill:#6366f1,color:#fff,stroke:none
style DONE fill:#22c55e,color:#fff,stroke:none
style A3 fill:#ef4444,color:#fff,stroke:noneWith the overall picture in mind, let's proceed through each step.
Step 1: Update Claude Code Desktop¶
Since the SSH feature is relatively new, older versions may not include the SSH remote server binary.
Update procedure:
- Open Claude Code Desktop
- Select Help -> "Restart to update to version X.X.XXXX"
- After restart, check the Help menu again
A single update may not bring you to the latest version
Updates may be applied incrementally, so repeat until no new updates appear in the Help menu.
Verify the binary exists:
dir "$env:LOCALAPPDATA\AnthropicClaude\app-*\resources\claude-ssh\"
If files like claude-ssh-linux-amd64 exist, you are ready. If the folder itself does not exist, further updates are needed.
With the app ready, the next step is to prepare the WSL2 environment.
Step 2: Install OpenSSH Server on WSL2¶
Run the following in the WSL2 terminal.
sudo apt update
sudo apt install openssh-server
After installation, check the configuration file syntax.
sudo sshd -t
If no errors appear, the configuration is valid. While the SSH server itself is ready, network configuration adjustments are needed for the actual connection.
Step 3: Change the WSL2 Network Mode to Mirrored¶
This step changes the overall network configuration of WSL2, so proceed after understanding the scope of impact.
Difference Between NAT Mode and Mirrored Mode¶
WSL2 defaults to NAT mode, where WSL2 has its own virtual network (e.g., 172.x.x.x) with a separate IP address from Windows. In mirrored mode, the Windows network interfaces are mirrored directly to WSL2, and both share the same IP address.
flowchart LR
subgraph nat ["NAT Mode (Default)"]
W1["Windows<br/>192.168.1.x"] --- NAT["NAT Translation"] --- L1["WSL2<br/>172.x.x.x"]
end
subgraph mirrored ["Mirrored Mode"]
W2["Windows<br/>192.168.1.x"] --- M["Mirroring"] --- L2["WSL2<br/>192.168.1.x"]
endWhy Mirrored Mode Is Needed¶
NAT mode tends to cause connection errors from Claude Code Desktop. With mirrored mode, you can reach WSL2 directly via 127.0.0.1, making connections stable. Microsoft officially recommends "using mirrored mode for new features and improved compatibility."
Considerations for Mirrored Mode¶
Check the following before making the change.
| Item | Impact |
|---|---|
| Port conflicts | Since Windows and WSL2 share ports, you cannot use the same port number on both (addressed in Step 4) |
| Docker Desktop | Generally compatible. However, there are reports of behavior changes with container --network host mode |
| VPN usage | There are reports of WSL2 network instability while connected to a corporate VPN |
| IPv6 | localhost ::1 is not supported. Use IPv4 127.0.0.1 |
| Windows requirement | Windows 11 22H2 or later is required |
Reverting is easy
If problems occur, simply delete (or comment out) the networkingMode = mirrored line from .wslconfig and run wsl --shutdown to revert to NAT mode.
Configuration Steps¶
Edit .wslconfig on the Windows side:
notepad "$env:USERPROFILE\.wslconfig"
Add the following and save.
[wsl2]
networkingMode = mirrored
Apply the changes.
wsl --shutdown
Then restart WSL2. You can verify mirrored mode is active by running ip a on the WSL2 side and confirming that it shows the same IP address as Windows.
With the switch complete, the next step is to address port conflicts.
Step 4: Check and Resolve Port Conflicts¶
In mirrored mode, Windows and WSL2 share ports. If the OpenSSH Server is running on the Windows side, port 22 will conflict and WSL2's sshd will be unable to start.
Check for conflicts (PowerShell):
netstat -ano | findstr ":22 "
If results are displayed, port 22 is already in use.
Pattern A: Stop the Windows SSH Server (recommended)¶
This is the simpler approach if you are not using the Windows-side SSH server.
# Run in PowerShell with administrator privileges
Stop-Service sshd
Set-Service sshd -StartupType Disabled
In this case, WSL2's sshd can start on the default port 22.
Pattern B: Run WSL2's sshd on a Different Port¶
If you need to keep the Windows SSH Server running, change the port on the WSL2 side.
sudo sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config
With port conflicts resolved, start sshd.
Step 5: Start sshd¶
sudo service ssh start
Verify it is running.
sudo service ssh status
If sshd is running is displayed, it is operating normally.
Diagnosing if sshd stops immediately after starting:
sudo /usr/sbin/sshd -D -d
This starts sshd in foreground + debug mode, allowing you to see error messages directly. If Address already in use appears, go back to Step 4 to resolve the port conflict.
Once sshd is confirmed to be running, proceed to the connectivity test from the Windows side.
Step 6: Verify SSH Connection from PowerShell¶
Before connecting from Claude Code Desktop, first verify connectivity from the command line. Isolating issues at this stage makes troubleshooting in Step 8 much easier.
# For port 22
ssh WSL_USERNAME@127.0.0.1
# For port 2222
ssh -p 2222 WSL_USERNAME@127.0.0.1
Note the username
The Windows user and WSL2 user may differ. You can check the WSL2 username with the whoami command.
Accept the host key prompt on first connection by typing yes.
If you don't know the password, reset it on the WSL2 side.
sudo passwd $(whoami)
Common Errors and Solutions¶
| Error | Cause | Solution |
|---|---|---|
Connection reset | sshd is not running | Check Step 5 |
Connection timed out | Port conflict or firewall | Check Step 4 |
Permission denied | Wrong username or password | Verify username + reset passwd |
Host key verification failed | Stale entry in known_hosts | ssh-keygen -R 127.0.0.1 |
Once password authentication is confirmed, proceed to setting up public key authentication.
Step 7: Set Up Public Key Authentication (Recommended)¶
Password authentication works, but setting up public key authentication eliminates the need to enter a password each time.
Generate a key pair (Windows PowerShell):
ssh-keygen -t ed25519
Three prompts will be displayed.
Enter file in which to save the key (C:\Users\USERNAME/.ssh/id_ed25519):
Press Enter without typing anything. The default save location will be used as-is. Be careful not to enter a filename or path here, as the key may be saved to an unintended location.
Enter passphrase (empty for no passphrase):
Setting a passphrase. You can skip by pressing Enter with an empty input.
Enter same passphrase again:
Press Enter again.
Should you set a passphrase?
A passphrase encrypts the key file itself, serving as insurance if the key file is leaked. However, you will be prompted for the passphrase every time you connect via SSH. For local WSL2 connections, leaving the passphrase empty (pressing Enter) is fine. If using the key for remote server connections, setting a passphrase is recommended.
Verify the key was generated correctly:
dir "$env:USERPROFILE\.ssh\id_ed25519.pub"
If the file is displayed, it was generated successfully. If you see "cannot find path" message, you may have entered something other than the default during the filename prompt. In that case, redo from ssh-keygen -t ed25519.
Register the Public Key on WSL2¶
Working from the WSL2 terminal side is more reliable. First, copy the public key contents in PowerShell.
cat "$env:USERPROFILE\.ssh\id_ed25519.pub"
Copy the single line starting with ssh-ed25519 AAAA..., then run the following in the WSL2 terminal.
mkdir -p ~/.ssh
echo "PASTE_YOUR_COPIED_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Password authentication works temporarily
Claude Code Desktop shows a password input dialog on first connection. Once entered, the password is cached for the session, so you won't need to re-enter it for a while. However, you will need to re-enter it every time the session expires, so setting up public key authentication is recommended.
Verify you can connect without a password.
ssh WSL_USERNAME@127.0.0.1
The preparation is now complete. The final step is to configure Claude Code Desktop.
Step 8: Connect from Claude Code Desktop¶
- Open Claude Code Desktop
- Select the Code tab
- Select SSH from the connection type dropdown
- The "Add SSH Connection" dialog will appear
Input fields:
| Field | Example | Description |
|---|---|---|
| Name | wsl | Any identifier name |
| SSH Host | WSL_USERNAME@127.0.0.1 | In username@host format. Use the WSL2-side username |
| SSH Port | 2222 | Specify if you changed the port. Leave empty for default port 22 |
| ID File (private key) | ~/.ssh/id_ed25519 | Default is ~/.ssh/id_rsa. Change this if you generated with ed25519 |
- Click the "Add SSH Connection" button
- On first connection, agree to the "Trust this worktree" confirmation
- Select the remote folder and start working
Note the ID file default
The ID file default value is ~/.ssh/id_rsa. If you generated the key with ssh-keygen -t ed25519 in Step 7, you need to change it to ~/.ssh/id_ed25519. Leave it empty if connecting with password authentication.
Password authentication caching
When the initial password authentication succeeds, the session is cached for a while, and you may be able to access the connection even if the ID file setting is incorrect. To verify that public key authentication is working correctly, fully quit and restart Claude Code Desktop before attempting to connect.
Claude Code Desktop stores connection information internally, so there is no need to manually edit ~/.ssh/config on the Windows side.
Tips¶
WSL2's sshd Stops on Every Restart¶
Unless systemd is enabled in WSL2, you need to manually start sshd after every restart. To set up auto-start, you can add the following to .bashrc.
# Add to the end of ~/.bashrc
if ! pgrep -x sshd > /dev/null; then
sudo service ssh start > /dev/null 2>&1
fi
To skip the sudo password prompt, configure it with visudo.
sudo visudo
# Add the following (replace username with your own)
username ALL=(ALL) NOPASSWD: /usr/sbin/service ssh start
Debugging When Connection Fails¶
To view detailed SSH connection logs, use the -v option.
ssh -v WSL_USERNAME@127.0.0.1
This outputs information useful for isolating problems.
What You Can Do with SSH: 5 Use Case Ideas¶
Once SSH is set up, consider these practical applications:
- Debug Docker containers on WSL2 from the GUI — View container logs, edit files, and run docker compose operations with Desktop's visual diff
- Continue development on your home PC via Tailscale while away — Combine a mesh VPN with tmux to work from a cafe or on the go without interrupting your session
- Manage ML experiments on cloud GPU instances — Connect to AWS EC2 or GCP GPU machines to edit training scripts, run experiments, and review results entirely from Desktop
- Safely edit production server config files with visual diff — Visually inspect changes to nginx.conf or systemd unit files before deploying
- Refactor across multiple environments with parallel sessions — Register SSH connections for dev, staging, and production, then switch between them in the GUI to apply the same changes
Summary¶
Setting up Claude Code Desktop SSH on Windows x WSL2 requires passing three checkpoints: changing the network mode, resolving port conflicts, and verifying the binary. While there are many steps, once configured, you can connect with a single click from the SSH dropdown.
Since the SSH feature itself is still new, unexpected errors may occur during connections. In such cases, the most efficient approach is to go back to Step 6 and isolate the issue by verifying connectivity from PowerShell.
Next Step: Applying to Remote Servers¶
This article targeted local WSL2, but the SSH feature's true strength lies in remote connections over the internet.
Application Patterns¶
| Pattern | Overview | Connection Target Example |
|---|---|---|
| Cloud VM | Connect directly to Linux instances on AWS EC2, GCP, etc. | ubuntu@<EC2-hostname> |
| Home PC via Tailscale | Connect to home WSL2 from outside via mesh VPN | user@100.x.x.x (Tailscale IP) |
| Dev Container | Connect to a development container on Docker via SSH | dev@localhost:2222 |
| Via bastion server | Multi-hop SSH with ProxyJump | Corporate networks, etc. |
Remote-Side Requirements¶
Claude Code Desktop's SSH feature works by automatically deploying a dedicated binary (~/.claude/remote/server etc.) to the connection target. The target must meet the following conditions.
| Item | Requirement |
|---|---|
| OS | Linux (x86_64). The claude-ssh-linux-amd64 binary is transferred |
| Shell | bash or sh (POSIX-compatible). There are reports of startup failures with fish shell due to $! syntax incompatibility |
| Permissions | Write permission to the ~/.claude/remote/ directory |
| Network | Outbound communication to the Anthropic API is required (API calls originate from the remote side) |
| ARM support | ARM64 (Raspberry Pi, Graviton, etc.) is unconfirmed in official documentation |
The SSH feature is still new
As of February 2026, the SSH feature was recently added, and multiple known issues including shell compatibility have been reported. It is recommended to check the latest status at GitHub Issues (anthropics/claude-code).