Repository navigation
[FEATURE]: Named Remote Connections with Session Origin Tracking #6461
Description
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
github-actions commentedon Dec 30, 2025
This issue might be a duplicate of existing issues. Please check:
opencode serveInstance #878: Feature Request: Connect TUI to Existingopencode serveInstance - requests ability to connect TUI to headless serverFeel free to ignore if your feature request addresses these in different ways or has specific additional requirements.
FlippingBinary commentedon Dec 30, 2025
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).thdxr commentedon Mar 25, 2026
To stay organized issues are automatically closed after 90 days of no activity. If the issue is still relevant please open a new one.