anthropics / anthropics/claude-code
[FEATURE] Manage SSH connections and remote sessions from agent view
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [x] I have searched [existing requests](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20label%3Aenhancement) and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
### Problem Statement
SSH is a first-class environment in Claude Code Desktop: you add a connection from the environment dropdown, Desktop installs Claude Code on the remote host on first connect, and the session runs there with permission modes, connectors, plugins and MCP. Connections are stored under `sshConfigs` in `~/.claude/settings.json`, admins can pre-configure them through managed settings, and `sshHostAllowlist` restricts which hosts users may reach.
None of that exists in the CLI. There is no notion of a registered remote host: you `ssh user@host` yourself, then run `claude` over there. That works, and I am not asking for a replacement — but it means every remote session is invisible to `claude agents`. Agent view is otherwise the single place where I see what my agents are doing, peek at them, reply, attach, and dispatch new work. Today that view stops at the machine I am sitting on.
My day-to-day is several dev VMs and GPU boxes, each with its own toolchain, plus my laptop. I end up with one terminal multiplexer per host and no unified picture. The `sshConfigs` data already exists in my settings file; the CLI just doesn't read it.
Worth noting that the architecture already has a concept of peer machines: cross-session messaging can reach sessions on other machines, and `isolatePeerMachines` exists to limit it. So "sessions living on more than one host" is not foreign to the design — what's missing is connection management and dispatch.
### Proposed Solution
Make agent view the single place to see and start sessions regardless of where they run.
1. `claude agents` reads `sshConfigs` from `~/.claude/settings.json` — the same key Desktop already writes — and lists those hosts as available dispatch targets.
2. Dispatch to a host from the TUI picker, and from the shell: `claude agents dispatch --host dev-vm --dir /srv/app "run the migration suite"`.
3. Remote sessions appear in the session list with a host badge, filterable by host, with the existing peek / reply / attach behaviour working over the connection.
4. `claude ssh add|list|remove` to manage entries from the terminal, writing the same `sshConfigs` schema so CLI and Desktop stay in sync rather than diverging.
5. Honour `sshHostAllowlist` in the CLI too. It is currently documented as read by Desktop only, which means an org that sets a boundary on one surface has none on the other.
Point 1 alone would already be most of the value. Points 2–5 are the natural follow-ons.
### Alternative Solutions
- **`ssh` + tmux per host.** What I do now. Sessions are invisible to agent view, there is no unified list, and reconnect discipline is per-host and manual.
- **The Desktop app.** Does exactly this today, but I want the terminal workflow: scripting, non-interactive runs, and no GUI on the box I work from.
- **MCP SSH servers or a custom skill.** These let a local session run commands on a remote host. That is a different thing: I want Claude Code running *on* the host, with that host's filesystem, interpreters and dependencies, not shell commands shipped over a wire.
- **Cloud sessions.** Not applicable. These machines are mine and were chosen for specific hardware and dependencies; some of the work isn't in a Git repo at all.
### Priority
High - Significant impact on productivity
### Feature Category
Interactive mode (TUI)
### Use Case Example
Example scenario:
Today, without the feature:
1. I keep three machines in play: my laptop, a dev VM where the app and its
dependencies live, and a build box with the toolchain I can't install locally.
2. I open a terminal, `ssh dev-vm`, start tmux, run `claude` in the project
directory, and hand it a refactor.
3. I open a second terminal, `ssh build-box`, same dance, and set Claude off
on a long test run there.
4. I keep working locally in a third `claude` session.
5. Now I want to know what the other two are doing. `claude agents` on my
laptop shows me exactly one session: the local one. The other two exist
only inside tmux panes on machines I have to reattach to by hand, one
SSH connection at a time.
6. Half an hour later I've lost track of which box is running what, and I
reattach to each in turn to find out.
With the feature:
1. My hosts are already defined in `sshConfigs` in `~/.claude/settings.json`
(or I add them with `claude ssh add`).
2. From agent view I dispatch the refactor to `dev-vm` and the test run to
`build-box`, each with its own working directory.
3. `claude agents` lists all three sessions in one place, each tagged with its
host, and I can peek, reply, or attach to any of them without opening a
single SSH connection myself.
4. When the test run finishes I see it in the same list I was already watching,
instead of discovering it on my next manual reattach.
Time saved: the per-host reconnect ritual disappears, and more importantly I
stop losing the thread of what is running where. The mental overhead of
multi-host work is currently linear in the number of hosts; this makes it flat.
### Additional Context
Technical considerations and constraints
- Authentication should defer to the user's existing setup rather than
reinventing it: ssh-agent, `~/.ssh/config` aliases, ProxyJump/ProxyCommand,
and identity files. Desktop already resolves hosts through `ssh -G`, so the
same resolution path would work here.
- Host key verification should behave like ordinary `ssh` — fail closed on a
changed key rather than prompting past it.
- Remote install: Desktop installs Claude Code on the host automatically on
first connect. The CLI could reuse that mechanism, or simply require that
`claude` already be on the remote PATH and say so clearly when it isn't.
- Session resilience matters more here than locally. A dropped link shouldn't
kill remote work; the supervisor process that already backs background
sessions seems like the right place for this to live.
- Config compatibility is the main ask: whatever the CLI writes should be the
same `sshConfigs` schema Desktop reads, so the two surfaces don't drift into
separate host registries.
- `sshHostAllowlist` is currently documented as read by Desktop only, and
explicitly not by the CLI or IDE extensions. If the CLI gains SSH sessions,
it should honour the allowlist too — otherwise an organisation that sets a
boundary on one surface has none on the other.
Similar features in other tools
- VS Code Remote-SSH: registers hosts and runs the full workspace remotely
while the UI stays local. Closest analogue to what's being asked for.
- JetBrains Gateway: same model, thin local client against a remote backend.
- tmux/mosh: what everyone uses today. Solves persistence, solves nothing
about discovery or a unified session list.
Scope note
Points 2–5 of the proposal are follow-ons. If only one thing ships, having
`claude agents` read `sshConfigs` and list remote sessions would cover most of
the value on its own.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the existing `claude agents` entry point and inspect how `sshConfigs` and `sshHostAllowlist` are represented in `~/.claude/settings.json`; compare this with Desktop's SSH handling and host resolution through `ssh -G`. Define the smallest first slice around listing configured hosts and remote sessions, with the existing host-key verification behavior preserved; no files or tests are named in the issue.
Written by the indexing model from the issue text.
Assessment
- Domain
- cli, distributed-systems, networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100