[FEATURE]: Named Remote Connections with Session Origin Tracking
Feature hasn't been suggested before.
- [x] 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
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 [email protected] "cd /var/www/app && opencode serve --port 4096"
Create tunnel in another terminal
ssh -L 4096:localhost:4096 [email protected]
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://[email protected] --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://[email protected] --workdir /var/www/app
List saved connections
opencode attach --list
Saved connections:
frontend docker://frontend-app:/app
staging ssh://[email protected]:/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
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.