This guide covers how to use Emdash's SSH feature to work with remote projects on remote servers via SSH/SFTP.
Emdash supports remote development by connecting to servers via SSH. This allows you to:
- Run coding agents on remote machines
- Access and edit files on remote servers through SFTP
- Execute Git operations on remote repositories
- Use worktrees for parallel development on remote hosts
When you add a remote project:
- Emdash establishes an SSH connection to your server
- Files are accessed via SFTP for browsing and editing
- Git operations run over SSH commands
- Coding agents execute in remote worktrees
- All connections use your system's SSH agent or configured keys
Before adding a remote project in Emdash, set up your server with the required tools.
# Ubuntu/Debian
sudo apt update && sudo apt install -y git
# Configure identity (required for commits)
git config --global user.name "Your Name"
git config --global user.email "your@email.com"The gh CLI is required for creating PRs, viewing check runs, and other GitHub operations from the Emdash UI.
# Ubuntu/Debian
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] \
https://cli.github.com/packages stable main" \
| sudo tee /etc/apt/sources.list.d/github-cli-stable.list > /dev/null
sudo apt update && sudo apt install -y gh
# Authenticate (choose GitHub.com → HTTPS → Login with web browser)
gh auth loginGit push and pull require SSH authentication to GitHub from the server. Create a dedicated key:
# Generate a passphrase-free key for non-interactive use
ssh-keygen -t ed25519 -C "server-github" -f ~/.ssh/id_github -N ""
# Add the key to your GitHub account
gh ssh-key add ~/.ssh/id_github.pub --title "My Server"
# Configure git to use this key (use absolute path, not ~)
HOME_DIR=$(eval echo ~)
git config --global core.sshCommand "ssh -i ${HOME_DIR}/.ssh/id_github"
# Trust GitHub's host key
ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null
# Verify it works
ssh -T git@github.comImportant: Use the absolute path (e.g., /home/user/.ssh/id_github) in core.sshCommand, not ~. Emdash runs commands in a non-interactive shell where tilde expansion may not work.
Alternatively, configure SSH directly in ~/.ssh/config:
Host github.com
IdentityFile /home/user/.ssh/id_github
IdentitiesOnly yes
# Clone an existing repo (use SSH URL for push access)
git clone git@github.com:your-org/your-repo.git
# Or initialize a new repo
mkdir ~/my-project && cd ~/my-project && git initNote: If your repo was cloned with HTTPS, switch to SSH for push access:
git remote set-url origin git@github.com:your-org/your-repo.gitAt least one CLI agent must be installed on the server. For example:
# Claude Code
curl -fsSL https://claude.ai/install.sh | bash
# Or install another supported agent- Open Settings → SSH Connections
- Click "Add Connection"
- Enter connection details:
Name: My Server
Host: server.example.com
Port: 22
Username: your-username
Auth Type: [Select method]
Before saving, click "Test Connection" to verify:
- Network connectivity
- Authentication credentials
- Host key verification
- Go to Projects → Add Project
- Select "Remote Project" tab
- Choose your configured SSH connection
- Enter the remote path to your project:
Connection: My Server
Project Path: /home/user/projects/my-app
- Emdash will validate the path and detect Git configuration
| Option | Description | Default |
|---|---|---|
| Name | Display name for this connection | Required |
| Host | Server hostname or IP address | Required |
| Port | SSH port (usually 22) | 22 |
| Username | SSH username | Required |
Emdash uses sensible defaults for connection reliability:
- Ready Timeout: 20 seconds (connection establishment)
- Keepalive Interval: 60 seconds (connection health check)
- Keepalive Count Max: 3 retries before disconnect
These settings ensure stable long-running agent sessions.
Emdash supports three authentication methods, listed from most to least secure:
Uses your system's SSH agent for key-based authentication without storing private keys in Emdash.
Requirements:
- SSH agent running (
ssh-agent) - Key added to agent (
ssh-add ~/.ssh/id_ed25519) SSH_AUTH_SOCKenvironment variable set
Setup:
# Start SSH agent (if not already running)
eval "$(ssh-agent -s)"
# Add your key
ssh-add ~/.ssh/id_ed25519
# Verify
ssh-add -lmacOS Note: macOS automatically manages the SSH agent via Keychain. Your keys are typically available after first use.
Specify a private key file directly. Emdash reads the key file but stores passphrases securely in your system keychain.
Supported Key Formats:
- OpenSSH format (
id_rsa,id_ed25519,id_ecdsa) - PEM format
- Keys with or without passphrases
Configuration:
Auth Type: Private Key
Private Key Path: /Users/you/.ssh/id_ed25519
Passphrase: [if key is encrypted]
Security: Passphrases are stored in your OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service), not in Emdash's database.
Direct password authentication. Stored securely in your system keychain.
When to use:
- Servers without key-based auth configured
- Temporary/testing connections
- Legacy systems
Security Note: Password authentication is less secure than key-based methods. Consider setting up SSH keys for production use.
Emdash verifies server identity using SSH host keys to prevent man-in-the-middle attacks.
When connecting to a new server, you'll see a host key fingerprint:
Host Key Verification
Server: server.example.com:22
Fingerprint: SHA256:ABC123xyz...
Algorithm: ssh-ed25519
[Trust Host] [Cancel]
Verify the fingerprint matches your server's actual key before trusting.
Emdash uses your system's ~/.ssh/known_hosts file for host key storage. This means:
- Host keys trusted in Emdash are also trusted by your CLI SSH
- Host keys verified via CLI SSH are trusted in Emdash
- No separate host key management needed
If a server's host key changes (e.g., after rebuild), you'll see:
WARNING: Host key has changed!
This could indicate a man-in-the-middle attack.
Previous: SHA256:ABC123...
Current: SHA256:XYZ789...
[View Details] [Accept New Key] [Cancel]
Only accept the new key if you know why the host key changed (e.g., server was rebuilt).
Symptoms: "Connection timed out" or long delays
Solutions:
- Verify host and port are correct
- Check firewall rules (port 22 open)
- Test with CLI:
ssh -v user@host - Check if VPN is required
Symptoms: "Authentication failed" or "Permission denied"
For Password Auth:
- Verify username and password
- Check if account is locked or expired
For Key Auth:
- Verify key file exists and is readable
- Check key permissions (should be 600)
- Ensure public key is in server's
~/.ssh/authorized_keys
For Agent Auth:
- Verify
SSH_AUTH_SOCKis set:echo $SSH_AUTH_SOCK - Check key is loaded:
ssh-add -l - Reload key if needed:
ssh-add ~/.ssh/id_ed25519
Symptoms: "Host key verification failed"
Solutions:
- Check if server was recently rebuilt
- Verify fingerprint with server admin
- Remove old entry:
ssh-keygen -R hostname - Reconnect and accept new key
Symptoms: Can connect but file operations fail
Solutions:
- Verify SFTP is enabled on server (
Subsystem sftpin sshd_config) - Check disk space on remote server
- Verify permissions on project directory
- Try manual SFTP:
sftp user@host
Symptoms: Git commands return errors
Solutions:
- Ensure Git is installed on remote server:
ssh user@host git --version - Check repository permissions
- Verify Git config (user.name, user.email) on remote
- For private repos, ensure SSH agent forwarding or deploy keys
Symptoms: File browsing or editing is slow
Solutions:
- Check network latency:
ping server - Consider connection multiplexing in ~/.ssh/config:
Host server
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Keys are more secure and convenient:
# Generate Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "emdash@workstation"
# Copy to server
ssh-copy-id user@server- Never commit private keys to Git
- Use strong passphrases for keys
- Store keys in
~/.ssh/with 600 permissions - Use hardware security keys (YubiKey) for high-security environments
Always verify host key fingerprints on first connection. For known servers, distribute fingerprints securely:
# Get server fingerprint
ssh-keyscan -t ed25519 server.example.comCreate ~/.ssh/config for server-specific settings:
Host prod-server
HostName prod.example.com
User deploy
IdentityFile ~/.ssh/prod_ed25519
StrictHostKeyChecking accept-new
ServerAliveInterval 60
Host dev-server
HostName 192.168.1.100
User developer
ForwardAgent yes
Only enable agent forwarding when needed:
Host trusted-server
ForwardAgent yes
Rotate SSH keys periodically:
- Generate new keys every 6-12 months
- Remove old keys from
authorized_keys - Update Emdash connections with new key paths
Review your ~/.ssh/known_hosts periodically:
# List known hosts
ssh-keygen -l -f ~/.ssh/known_hosts
# Remove stale entries
ssh-keygen -R old-server.example.com- macOS/Linux:
~/.ssh/config - Windows:
%USERPROFILE%\.ssh\config - Known hosts:
~/.ssh/known_hosts(Windows:%USERPROFILE%\.ssh\known_hosts)
# Test connection
ssh -v user@host
# Check loaded keys
ssh-add -l
# Add key to agent
ssh-add ~/.ssh/id_ed25519
# Remove key from agent
ssh-add -d ~/.ssh/id_ed25519
# Remove host from known_hosts
ssh-keygen -R hostname
# Get server fingerprint
ssh-keyscan -t ed25519 hostname- Connection configs: Local SQLite database
- Passwords/Passphrases: System keychain (via keytar)
- Host keys:
~/.ssh/known_hosts(shared with system SSH) - Private keys: Never stored by Emdash (only paths are stored)
For technical details on SSH implementation, see SSH Architecture.