Skip to content

[FEATURE]: Named Remote Connections with Session Origin Tracking #6461

Closed as not planned

Description

@isaiahdahl

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Problem Statement

Modern development increasingly happens inside isolated environments—Docker containers for different services, remote staging servers, VMs with specific toolchains, Kubernetes pods. Each environment has its own dependencies, tools, and file access. An AI coding agent must run inside the environment where the code lives because that’s where the tools work: the container with Node 22, the php server with it's own cli commands, the ML environment with GPU drivers.

OpenCode already has the primitives for this architecture:

opencode serve runs a headless daemon
opencode attach connects a local TUI to a remote daemon
But there’s significant friction in using these primitives for real multi-environment workflows.

What Multi-Environment Development Looks Like Today

Consider a typical microservices project with three containers:

Terminal 1: Start daemon in frontend container

docker exec -it frontend-app opencode serve --port 4001

Terminal 2: Start daemon in API container

docker exec -it backend-api opencode serve --port 4002

Terminal 3: Attach to one of them

opencode attach http://localhost:4001 # Which service was this again?

The next day, you return to your machine:

Are those daemons still running?
What ports did you use?
Which container was on which port?
Your sessions are scattered across environments with no way to see them together

For SSH environments, the friction multiplies:

Start daemon on staging

ssh deploy@staging.example.com "cd /var/www/app && opencode serve --port 4096"

Create tunnel in another terminal

ssh -L 4096:localhost:4096 deploy@staging.example.com

Attach in a third terminal

opencode attach http://localhost:4096
This isn’t a power-user workflow—it’s the default experience for anyone using OpenCode with containers or remote hosts.

The Core Friction Points

No persistent connection memory — You must remember which URL corresponds to which environment. Ports are arbitrary numbers with no semantic meaning.
Manual daemon lifecycle — Every reconnection requires checking if the daemon is running, restarting it if not, and re-establishing any tunnels.
Sessions lack environment context — opencode session list shows a flat list. There’s no way to see “show me my staging sessions” or understand where a session ran.
No shareable environment definitions — Teams can’t commit environment configurations to version control.

Why External Tooling Doesn’t Fully Solve This

Shell aliases and scripts can help with connection management:

alias oc-frontend='docker exec -it frontend-app opencode serve --port 4001 & sleep 2 && opencode attach http://localhost:4001'
But this doesn’t solve:

Session organization — Sessions still have no environment metadata
Cross-machine consistency — Aliases live in dotfiles, not project config
Status visibility — No unified view of what’s running where
Team sharing — Each developer maintains their own scripts
The session organization problem specifically cannot be solved externally—it requires OpenCode to track where sessions originated.


Proposed Solution

Extend the existing attach command to support named connections with transport handlers, automatic daemon lifecycle management, and session origin tracking.

1. Transport URIs and Named Connections

Support URIs that specify how to connect to an environment:

Docker container

opencode attach docker://frontend-app --workdir /app

SSH host

opencode attach ssh://deploy@staging.example.com --workdir /var/www/app

Kubernetes pod

opencode attach k8s://pod-name --namespace default --workdir /app

####Plain URL (existing behavior)
opencode attach http://localhost:4096
Save connections with friendly names:

Save a connection

opencode attach --save frontend docker://frontend-app --workdir /app
opencode attach --save staging ssh://deploy@staging.example.com --workdir /var/www/app

List saved connections

opencode attach --list

Saved connections:
  frontend    docker://frontend-app:/app
  staging     ssh://deploy@staging.example.com:/var/www/app

2. Connect by Name with Auto-Start

Once saved, connect by name:

opencode attach frontend

This command:

Looks up the saved connection frontend
Checks if a daemon is already running in that environment
If not, starts opencode serve via the appropriate transport (docker exec, ssh, kubectl exec)
Establishes any necessary tunneling
Attaches the local TUI to the remote daemon
First connection shows the setup:

$ opencode attach frontend

Connecting to frontend (docker://frontend-app)...
✓ Container is running
✓ Started daemon on port 4001
✓ Connected
Subsequent connections are instant:

$ opencode attach frontend

Connecting to frontend...
✓ Daemon already running
✓ Connected

3. Session Origin Tracking

Sessions automatically record which environment they originated from:

$ opencode session list

ID          Origin      Title                        Updated
ses_abc123  staging     Fix API rate limiting        2 min ago
ses_def456  frontend    Refactor auth components     1 hour ago
ses_ghi789  api         Debug payment webhook        3 hours ago
ses_xyz000  local       Update README                1 day ago

Filter by origin:

$ opencode session list --origin staging

ID          Origin      Title                        Updated
ses_abc123  staging     Fix API rate limiting        2 min ago
ses_old456  staging     Deploy hotfix                3 days ago

4. Connection Status Overview

See the state of all saved connections:

$ opencode attach --status

Connection    Status          Port    Sessions
frontend      ● running       4001    3 sessions
api           ● running       4002    5 sessions
staging       ○ disconnected  -       4 sessions
ml            ○ stopped       -       2 sessions

5. Project Configuration

Define environments in opencode.json for team sharing:

{
  "environments": {
    "frontend": {
      "transport": "docker",
      "container": "frontend-app",
      "workdir": "/app"
    },
    "api": {
      "transport": "docker", 
      "container": "backend-api",
      "workdir": "/app"
    },
    "staging": {
      "transport": "ssh",
      "host": "staging.example.com",
      "user": "deploy",
      "workdir": "/var/www/app"
    }
  }
}

Project-defined environments merge with user-saved connections. Teams commit shared environments; individuals add their own.


CLI Summary

All functionality extends the existing attach command:

Command Description
opencode attach Connect to environment via transport URI
opencode attach Connect to saved environment by name
opencode attach --save Save a connection with a friendly name
opencode attach --list List saved connections
opencode attach --status Show running state of all connections
opencode attach --remove Remove a saved connection
opencode session list --origin Filter sessions by environment

Supported Transports

URI Scheme Description Example
docker:// Docker container docker://container-name
ssh:// SSH host ssh://user@host
k8s:// Kubernetes pod k8s://pod-name
podman:// Podman container podman://container-name
http:// Direct URL (existing) http://localhost:4096

New transports can be added as the ecosystem evolves.


Implementation Notes

Transport Handler Interface

Each transport implements:

interface TransportHandler {
  // Check if the environment is available (container running, host reachable)
  checkAvailable(): Promise<boolean>
  
  // Check if opencode daemon is already running in the environment
  checkDaemonRunning(): Promise<{ running: boolean; port?: number }>
  
  // Start opencode serve in the environment, return the port
  startDaemon(): Promise<number>
  
  // Establish connection (e.g., SSH tunnel) and return local URL
  connect(remotePort: number): Promise<string>
  
  // Clean up (close tunnels, etc.)
  disconnect(): Promise<void>
}

Session Metadata

Add origin field to session storage:

interface Session {
  id: string
  title: string
  // ... existing fields
  origin?: string  // Name of the environment, e.g., "frontend", "staging"
}

When a session is created via a named connection, the origin is automatically populated.

Daemon Discovery

For checking if a daemon is running:

Docker: docker exec pgrep -f "opencode serve" or attempt HTTP health check
SSH: Similar check over SSH
K8s: kubectl exec equivalent
Alternatively, maintain a lightweight state file in the environment that records the daemon port.


Non-Goals

This proposal intentionally avoids:

Auto-installation of OpenCode on remotes — Security implications, and users can install OpenCode themselves. The connect command should fail clearly if OpenCode isn’t available in the environment.
Auto-discovery of containers/hosts — Explicit configuration is clearer than magic detection. Users know their environments.
Container orchestration — This doesn’t replace docker-compose or Kubernetes. It connects to containers that are already running.
Complex process supervision — Just “check if running, start if not.” No restart policies or health monitoring.


Use Cases

Microservices Development

Each service runs in its own container with its own dependencies. Developer connects to whichever service they’re currently working on:

opencode attach frontend # Working on React app
opencode attach api # Switch to backend work
opencode attach ml # Debug recommendation engine
Sessions stay organized by service.

Staging/Production Debugging

Quick connection to remote environments with session history preserved:

opencode attach staging

... debug issue, session saved with origin "staging"

Later, review what was done:

opencode session list --origin staging

Polyglot Projects

Different containers with different language toolchains. The Python ML container has different tools than the Go API container. Each environment gets its own agent instance with appropriate tool access.

Team Onboarding

New developer clones repo, environments are already defined:

git clone repo
cd repo
opencode attach --list

Shows: frontend, api, worker (from opencode.json)

opencode attach frontend

Just works


Summary

This feature extends OpenCode’s existing remote capabilities into a coherent workflow for multi-environment development. The key additions are:

Transport URIs — docker://, ssh://, k8s:// schemes for connecting to environments
Named connections — Save and reuse connection configurations
Automatic lifecycle — Start daemon if not running, establish tunnels as needed
Session origin tracking — Sessions know where they came from
Project configuration — Shareable environment definitions in opencode.json
All functionality extends the existing attach command rather than introducing new command namespaces, keeping the CLI surface area minimal while significantly improving the multi-environment experience.

Activity

  1. added
    discussionUsed for feature requests, proposals, ideas, etc. Open discussion
    on Dec 30, 2025
  2. github-actions commented on Dec 30, 2025

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Feel free to ignore if your feature request addresses these in different ways or has specific additional requirements.

  3. FlippingBinary commented on Dec 30, 2025

    @FlippingBinary

    This might also be very useful for cross-platform development with remote agents on different platforms, especially if they could be orchestrated as if they were local (like how oh-my-opencode's Sisyphus orchestrates local agents and background tasks).

  4. thdxr commented on Mar 25, 2026

    @thdxr
    Member

    To stay organized issues are automatically closed after 90 days of no activity. If the issue is still relevant please open a new one.

  5. removed
    discussionUsed for feature requests, proposals, ideas, etc. Open discussion
    on May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions