Skip to content

RFC — Phase 6: Remote Agent Backend (over SSH / WebSocket) #24

Description

@GoDiao

RFC — Phase 6: Remote Agent Backend (over SSH / WebSocket)

Status: Draft — open for discussion
Champion: @GoDiao
Related: Original feature request #3Remote Development Support (mirrored from openai/codex#10450)
Sibling RFC: #19 — Phase 4 IM adapters


Why this RFC

DreamCoder v0.4.0 shipped H5 Remote Access (Phase 3): you sit in front of a desktop running DreamCoder and reach into it from your phone. That solves "I'm away from my desk."

It does not solve a different problem that #3 (and many real-world workflows) raise: "my code lives on a remote machine and I don't want to clone it locally." Typical setups:

  • VS Code Remote-SSH style daily workflow
  • GPU / specialized hardware boxes (training, inference, simulation)
  • Cloud / production-like dev VMs
  • Security/compliance contexts where code may not leave the server

What's needed is the opposite topology of H5:

H5 Remote Access (v0.4.0) Remote Agent Backend (this RFC)
Agent runtime local desktop remote host
Codebase location local remote
Remote endpoint phone / browser (thin) server / GPU box (heavy)
Problem solved "I'm away from my desk" "Code isn't on my desk"

The two are complementary — if we land both, DreamCoder works wherever you are and wherever your code is.


Goals

  • Run the DreamCoder agent (Claude Code CLI + tools + PTY + MCP) on a remote machine, against a remote codebase.
  • Use the local DreamCoder desktop GUI as the client UI — chat panel, sessions, settings, terminal pass-through.
  • Authenticate cleanly. Idle remote sessions should not become an attack surface.
  • Be opt-in and reversible — local-only mode stays the default, the remote backend is an additional connection mode.
  • Reuse as much of the existing sidecar / H5 protocol as possible. Avoid forking the codebase.

Non-goals (for v1)

  • Full IDE features (LSP indexing, language servers, refactor across files via remote). Out of scope — Claude Code already calls remote tools fine via PTY.
  • Multi-user collaborative editing on the same remote session.
  • Reinventing SSH / VPN. We assume the user already has SSH access to the host.
  • File sync / mirroring like VS Code Remote-SSH's vfs. The agent operates server-side; the client renders chat + file diffs.

Candidate paths

Three architectural shapes are on the table. They are not mutually exclusive — Path C is arguably a superset.

Path A — SSH reverse tunnel to a remote sidecar

[ Local DreamCoder GUI ] ──(localhost http/ws)──► [ ssh -R tunnel ] ──► [ dreamcoder-sidecar on remote ]
                                                                              │
                                                                              ▼
                                                                       remote codebase + claude CLI

How: User configures a remote host. DreamCoder spawns ssh -R 0:127.0.0.1:<port> user@host 'dreamcoder-sidecar --headless --bind 127.0.0.1:<port>'. The local GUI talks to localhost as if it were the local sidecar.

  • ✅ Auth is "free" — SSH does it.
  • ✅ No new ports exposed on the public internet.
  • ✅ Works through corporate firewalls if SSH already does.
  • ❌ Need to bootstrap dreamcoder-sidecar onto the remote (one-time install or auto-upload binary).
  • ❌ Tunnel lifetime tied to a process — reconnect logic needed.
  • ❌ Windows SSH server story is messier than Linux.

Path B — Remote-installed sidecar, local GUI connects via WebSocket

[ remote host ]  dreamcoder-sidecar --serve --auth=token  ◄──(wss + token)── [ Local DreamCoder GUI ]

How: User installs dreamcoder-sidecar on the remote (binary or cargo install or bun install -g), starts it as a service, and pairs the local GUI to it (host + token, like the H5 pairing flow but in reverse direction).

  • ✅ Survives across multiple local clients (laptop + work desktop pairing to the same remote box).
  • ✅ Reuses H5's token rotation, QR pairing UX, request classifier.
  • ❌ Now there's a port to expose on the remote — needs TLS, ideally behind reverse-proxy or only on a private network.
  • ❌ Operational story: who keeps the sidecar daemon alive? (systemd template? launchd? pm2?)

Path C — Reuse H5 protocol, run headless DreamCoder on remote, local GUI as the "phone"

[ remote host ]  dreamcoder --headless (full server, H5 endpoint)  ◄──(wss, H5 protocol)── [ local GUI in "client" mode ]

How: We already have connectHeadless.ts and createDirectConnectSession.ts from v0.4.0. The remote box runs the full DreamCoder server in headless mode (no Tauri shell, just the bun server). The local desktop GUI gets a "Connect to remote DreamCoder" mode and talks the same H5 protocol the phone speaks today.

  • ✅ Maximum code reuse — protocol, auth, token rotation, request classifier are already live.
  • ✅ One mental model for both directions: the desktop is just a richer H5 client.
  • ✅ Symmetrical — same binary works as host or client.
  • ❌ Headless-mode server needs hardening: process lifecycle, log rotation, multi-session isolation, resource limits.
  • ❌ The desktop GUI's existing assumption that the sidecar is 127.0.0.1 needs auditing — anywhere we trust loopback today must be re-checked under remote topology.

Tentative recommendation

Default: Path C with Path A as a 5-minute fallback.

  • C maximizes leverage from the v0.4.0 H5 stack and gives users a single coherent story.
  • A is trivially achievable for power users today as a documented recipe ("run DreamCoder over SSH tunnel") even before C ships — could be the v0.5 stop-gap while C bakes.
  • B is what C looks like in production when paired with auto-start service templates; it's a deployment shape, not a separate architecture.

Open questions

  1. Auth model: Token + TLS cert pinning? mTLS? Reuse H5's rotating token? OAuth-device-code? What's the minimum bar that won't get someone fired by their security team?
  2. Discovery: How does the local GUI find the remote? Manual host:port + token? mDNS on private networks? A small "DreamCoder Hub" relay (opt-in)?
  3. File operations: Do we surface remote file diffs in the GUI (currently we read locally)? Stream them over the wire? Cache?
  4. Terminal: portable-pty lives on the remote in this design — does the existing xterm.js client need protocol changes for remote PTY resize / signal forwarding?
  5. MCP servers: Remote-side or local-side? Probably remote (they need filesystem access), but some MCP servers are local-only by design (e.g. Apple Notes). Do we support both ends simultaneously?
  6. Updater: How does dreamcoder-sidecar (or headless DreamCoder) get updated on the remote? Pinned version + manual update? Auto-update from a configured endpoint?
  7. Computer Use: On a headless Linux box without a display server, screenshot mode is moot. UIA tree mode is Windows-only. Does Computer Use just disable itself in remote mode, or do we ship something like xvfb-based headless screenshotting?
  8. Resource limits: One remote box, multiple DreamCoder sessions, multiple users — what's the isolation story? Per-session subprocess? cgroup? Just trust the OS user account?

Proposed work breakdown (subject to scope)

  1. Spike: prove Path C in a branch — local desktop GUI connects to a headless DreamCoder over WebSocket on a LAN box. (1-2 days)
  2. Auth hardening: extend H5 token model to remote topology; remove any lingering "trust loopback" assumptions. (~1 week)
  3. Headless lifecycle: systemd unit + launchd plist + Windows service templates; log rotation; PID file. (~3 days)
  4. GUI side: "Add remote connection" flow — host + paste token, save profile, switch profile. Mirror the existing H5 setup UX. (~1 week)
  5. Path A docs: write the SSH-tunnel recipe for users who want it today. (~half a day)
  6. Computer Use mode: gate / disable on headless Linux for v1. (~1 day)
  7. MCP: decide local-vs-remote per server in settings; default = remote. (~3 days)
  8. Docs + sample setup: "Install DreamCoder on a GPU server" walkthrough. (~2 days)

How to participate

  • 💬 Comment on this issue with answers to any of the open questions, or push back on the candidate paths.
  • 🔬 Try the SSH-tunnel recipe once we publish it (Path A) and report back what breaks — that data informs the auth/lifecycle hardening for Path C.
  • 🛠 Pick up a sub-task from the work breakdown if you want to ship something. Mentor available — @GoDiao.

cc @v2less (original requester in #3) — you're the source for this RFC. Would love your take on the candidate paths and which workflow shape best matches your day-to-day.

cc @pocca2048 — credit to your codex#10450 issue, which #3 mirrored. Cross-pollination welcome if you're around.

Tagging interested area: rfc, enhancement, area:remote, phase-6.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions