Context
Currently, the OpenCode UI and server run together in the same Kubeflow Notebook pod. For the new Kubernetes sandbox feature, we need the ability to connect the UI to an external OpenCode server running in a separate sandbox pod.
Use Case
┌─────────────────────┐ ┌─────────────────────┐
│ Kubeflow Notebook │ │ Sandbox Pod │
│ (UI only) │ ──────► │ (OpenCode Server) │
│ │ API │ │
└─────────────────────┘ └─────────────────────┘
- User accesses UI from Kubeflow Notebook
- UI connects to OpenCode server running in isolated sandbox
- Enables better security isolation and resource management
Architecture: Proxy Approach
The Problem
The browser can only communicate with the Notebook pod through Kubeflow's ingress. The Sandbox pod has no external route:
Browser
│
▼
┌─────────────────────────────────────────────────────────┐
│ Kubeflow Gateway / Ingress │
│ (only /notebook/ns/name/* is routed) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ Notebook Pod (UI) │ │ Sandbox Pod │
│ /notebook/ns/name/* │ ✗ │ (not exposed!) │
└─────────────────────────┘ └─────────────────────────┘
Solution: User-facing Server Picker + Backend Proxy
Frontend (User-facing):
- User can add/edit/remove external server URLs in Settings
- Server list with health indicators
- Switch between servers
Backend (Proxy):
- UI sends requests to local backend with target server info
- Backend proxies to the user-specified external server
- No direct browser-to-sandbox connection needed
Browser Notebook Pod Sandbox Pod
│ │ │
│ /api/proxy?target=... │ │
│ ─────────────────────────►│ │
│ │ http://sandbox-svc:4096 │
│ │ ──────────────────────────►│
│ │ │
Reference: Upstream OpenCode Implementation
The upstream OpenCode Desktop app already has this feature! Key files:
packages/app/src/components/dialog-select-server.tsx - Server picker dialog
packages/app/src/context/server.tsx - Server state management
Key features we can adapt:
ServerConnection.Http type with URL + optional username/password
normalizeServerUrl() for URL validation
- Health check polling (every 10 seconds)
- Server list persistence in LocalStorage
- Default server selection
Requirements
Phase 1: Basic Implementation
Phase 2: Polish
Technical Implementation
Files to create/modify
New files:
app-prefixable/src/context/server.tsx - Server state management
app-prefixable/src/components/server-dialog.tsx - Server picker UI
Modify:
docker/serve-ui.ts - Add proxy endpoint for external servers
app-prefixable/src/utils/path.ts - Integrate with server context
Proxy endpoint
// serve-ui.ts
app.all("/api/proxy/*", async (req) => {
const targetServer = req.headers.get("X-Target-Server")
if (!targetServer) return new Response("Missing target server", { status: 400 })
// Proxy request to target server
const targetUrl = new URL(req.url.replace("/api/proxy", ""), targetServer)
return fetch(targetUrl, {
method: req.method,
headers: req.headers,
body: req.body,
})
})
Security Considerations
- Should we restrict allowed server URLs? (e.g., only
*.svc.cluster.local)
- Consider adding authentication between UI and sandbox server
- Rate limiting on proxy endpoint?
Status
⚠️ EXPERIMENTAL - This feature is in early development for the sandbox integration project. PRs should NOT be merged to main until the sandbox infrastructure is ready.
Related
Context
Currently, the OpenCode UI and server run together in the same Kubeflow Notebook pod. For the new Kubernetes sandbox feature, we need the ability to connect the UI to an external OpenCode server running in a separate sandbox pod.
Use Case
Architecture: Proxy Approach
The Problem
The browser can only communicate with the Notebook pod through Kubeflow's ingress. The Sandbox pod has no external route:
Solution: User-facing Server Picker + Backend Proxy
Frontend (User-facing):
Backend (Proxy):
Reference: Upstream OpenCode Implementation
The upstream OpenCode Desktop app already has this feature! Key files:
packages/app/src/components/dialog-select-server.tsx- Server picker dialogpackages/app/src/context/server.tsx- Server state managementKey features we can adapt:
ServerConnection.Httptype with URL + optional username/passwordnormalizeServerUrl()for URL validationRequirements
Phase 1: Basic Implementation
ServerContextfor managing server connections (adapt from upstream)DialogSelectServercomponent for adding/editing serversserve-ui.tsto proxy requests to user-selected serverPhase 2: Polish
Technical Implementation
Files to create/modify
New files:
app-prefixable/src/context/server.tsx- Server state managementapp-prefixable/src/components/server-dialog.tsx- Server picker UIModify:
docker/serve-ui.ts- Add proxy endpoint for external serversapp-prefixable/src/utils/path.ts- Integrate with server contextProxy endpoint
Security Considerations
*.svc.cluster.local)Status
Related