Skip to content

Claude Code Complete Guide

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

StepTaskEstimated Time
1Update Claude Code Desktop5 min
2Install OpenSSH Server on WSL22 min
3Change network mode to mirrored5 min
4Check and resolve port conflicts5 min
5Start sshd1 min
6Verify SSH connection from PowerShell3 min
7Set up public key authentication (recommended)5 min
8Connect from Claude Code Desktop3 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" --> B

What this enables:

GoalWithout SSHWith SSH
Edit code on WSL2 with AITerminal CLI onlyOperable via Desktop GUI
Visual diff review of changesNot availableAvailable
Parallel sessions for multiple tasksManual tmux etc.Launch in parallel from GUI
Share context via file attachmentsNot availableAvailable
Use Docker/Linux-specific toolsAvailable from CLIAlso 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:none

With 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:

  1. Open Claude Code Desktop
  2. Select Help -> "Restart to update to version X.X.XXXX"
  3. 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"]
    end

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

ItemImpact
Port conflictsSince Windows and WSL2 share ports, you cannot use the same port number on both (addressed in Step 4)
Docker DesktopGenerally compatible. However, there are reports of behavior changes with container --network host mode
VPN usageThere are reports of WSL2 network instability while connected to a corporate VPN
IPv6localhost ::1 is not supported. Use IPv4 127.0.0.1
Windows requirementWindows 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.

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

ErrorCauseSolution
Connection resetsshd is not runningCheck Step 5
Connection timed outPort conflict or firewallCheck Step 4
Permission deniedWrong username or passwordVerify username + reset passwd
Host key verification failedStale entry in known_hostsssh-keygen -R 127.0.0.1

Once password authentication is confirmed, proceed to setting up public key authentication.

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

  1. Open Claude Code Desktop
  2. Select the Code tab
  3. Select SSH from the connection type dropdown
  4. The "Add SSH Connection" dialog will appear

Input fields:

FieldExampleDescription
NamewslAny identifier name
SSH HostWSL_USERNAME@127.0.0.1In username@host format. Use the WSL2-side username
SSH Port2222Specify if you changed the port. Leave empty for default port 22
ID File (private key)~/.ssh/id_ed25519Default is ~/.ssh/id_rsa. Change this if you generated with ed25519
  1. Click the "Add SSH Connection" button
  2. On first connection, agree to the "Trust this worktree" confirmation
  3. 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:

  1. Debug Docker containers on WSL2 from the GUI — View container logs, edit files, and run docker compose operations with Desktop's visual diff
  2. 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
  3. 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
  4. Safely edit production server config files with visual diff — Visually inspect changes to nginx.conf or systemd unit files before deploying
  5. 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

PatternOverviewConnection Target Example
Cloud VMConnect directly to Linux instances on AWS EC2, GCP, etc.ubuntu@<EC2-hostname>
Home PC via TailscaleConnect to home WSL2 from outside via mesh VPNuser@100.x.x.x (Tailscale IP)
Dev ContainerConnect to a development container on Docker via SSHdev@localhost:2222
Via bastion serverMulti-hop SSH with ProxyJumpCorporate 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.

ItemRequirement
OSLinux (x86_64). The claude-ssh-linux-amd64 binary is transferred
Shellbash or sh (POSIX-compatible). There are reports of startup failures with fish shell due to $! syntax incompatibility
PermissionsWrite permission to the ~/.claude/remote/ directory
NetworkOutbound communication to the Anthropic API is required (API calls originate from the remote side)
ARM supportARM64 (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).