CodeDeck+ can run sessions against two different coding-agent backends: Claude
Code (the default, always available) and OpenCode — a
second SessionBackend a phone can pick per-session from the "New session"
sheet once the bridge advertises the opencode capability. This is optional:
a bridge with no OpenCode configuration behaves exactly as it always has.
The bridge never bundles or manages OpenCode's model access itself — it talks
to a running opencode serve HTTP server over @opencode-ai/sdk
(packages/core/src/sdk/opencodeFacade.ts). There are two ways to get it that
server:
Run opencode serve yourself (on the same machine, another machine, or
wherever), and tell the bridge its URL:
codedeck-bridge run --opencode-server-url http://127.0.0.1:4096
# or: CODEDECK_OPENCODE_SERVER_URL=http://127.0.0.1:4096 codedeck-bridge run
# or in config.json: { "openCodeServerUrl": "http://127.0.0.1:4096" }This is the right choice when you already run OpenCode for other purposes
(e.g. driving its own TUI), or when the bridge and the OpenCode server live on
different machines. Precedence is the same as every other bridge setting:
--opencode-server-url flag > CODEDECK_OPENCODE_SERVER_URL env >
openCodeServerUrl in config.json.
Have the bridge spawn opencode serve itself at boot, and shut it down
cleanly when the bridge stops:
codedeck-bridge run --opencode-auto-start
# or: CODEDECK_OPENCODE_AUTO_START=1 codedeck-bridge run
# or in config.json: { "openCodeAutoStart": true }This is the simplest option when the bridge runs in a container (the same container can run OpenCode too, with nothing else to deploy) or as a plain local process on a machine you control.
Additional settings for this mode:
--opencode-path <path>/CODEDECK_OPENCODE_PATH/"openCodePath"— explicit path to theopencodebinary. Otherwise the bridge resolves it fromwhich opencodeand a few well-known global-install locations (mirroring how it resolvesclaudeandnvpn).CODEDECK_OPENCODE_PORT/"openCodePort"(env/config-file only, no flag — a rarely hand-typed knob) — fixes the port instead of the default OS-assigned ephemeral one. Useful if you also want to point OpenCode's own TUI at the same running instance for debugging.
The embedded server always binds to 127.0.0.1 only — it is spawned
exclusively for the bridge's own use and is never configurable to listen on
any wider interface.
If opencode can't be resolved, or the spawned process fails to come up, the
bridge logs one actionable line and continues running Claude-Code-only — a
broken or missing OpenCode install never blocks the bridge from serving
Claude Code sessions.
If both openCodeServerUrl and openCodeAutoStart are set, the external URL
wins (logged as a warning — usually a leftover setting from switching modes).
OpenCode supports 75+ model providers with no single credential shape, so
CodeDeck+ does not manage them for you. Whatever environment reaches the
opencode process (the bridge's own environment, for auto-start; or however
you started the external server) is what OpenCode sees — including common
provider env vars like ANTHROPIC_API_KEY. See
OpenCode's own docs for the full list of supported
providers and how to configure each.
For auto-start under Docker, run the one-time interactive login once the
container is up, and it will survive container recreation (the image
redirects OpenCode's config/auth storage under /data, the same volume the
bridge's own identity lives in):
docker compose exec codedeck-bridge opencode auth login- No automated credential setup — that one
opencode auth loginstep (or equivalent env vars) is on you. - No support for multiple simultaneous OpenCode servers.
- No change to session/model routing on the wire — this only controls how the
bridge obtains the
baseUrlit handsOpenCodeFacade.