codex-asm connects a local Codex TUI to a remote codex app-server over SSH in one command.
The workflow is intentionally client-first, like opening a VS Code Remote SSH window:
codex-asm connect devbox ~/work/projectThat single command:
- SSHes from the client to
devbox. - Starts or reuses a remote
codex app-serverin~/work/project. - Opens a local SSH port forward to the remote app-server.
- Starts local
codex --remote ws://127.0.0.1:<local-port>. - Cleans up the SSH tunnel when the local Codex client exits.
On the client machine:
bashsshcodexcurlawk
On the remote machine:
bashcodexcurlssawk- SSH access from the client
The remote machine does not need codex-asm installed. The local script streams itself over SSH and runs an internal remote-start command with bash -s.
codex-asm connect <ssh-target> <remote-workdir> [options] [-- <codex-args>...]
Examples:
codex-asm connect devbox ~/work/project
codex-asm connect user@10.0.0.12 /repo/app --name app
codex-asm connect devbox ~/work/project --ssh-port 2222
codex-asm connect devbox ~/work/project -- --model gpt-5.2Use an SSH config entry for the best experience:
Host devbox
HostName <remote-ip-or-hostname>
User <remote-user>
IdentityFile ~/.ssh/id_ed25519Then connect with:
codex-asm connect devbox ~/work/project| Option | Description |
|---|---|
--name NAME |
Stable remote app-server name. Defaults to a name derived from SSH target and workdir. |
--workdir DIR |
Remote workdir. Use this instead of the second positional argument if preferred. |
--remote-port PORT |
Fixed remote app-server port. Default: random free remote port. |
--local-port PORT |
Fixed local forwarded port. Default: random free local port. |
--ssh-port PORT |
SSH port for the remote host. |
--identity-file FILE |
SSH identity file. |
--ssh-option OPTION, -o OPTION |
Extra ssh -o option. May be repeated. |
Arguments after -- are appended to the local codex --remote ... command.
| Variable | Side | Default | Description |
|---|---|---|---|
CODEX_ASM_SSH_BIN |
client | ssh |
SSH binary used by connect. |
CODEX_ASM_CODEX_BIN |
client | codex |
Local Codex binary used for the TUI client. |
CODEX_ASM_SERVER_DIR |
remote | ~/.codex/asm |
Remote state directory. If set locally, connect forwards it into the remote startup command. |
CODEX_ASM_LOCAL_PORT_RANGE |
client | 20000-49151 |
Random local port range. |
CODEX_ASM_REMOTE_PORT_RANGE |
remote | 20000-49151 |
Random remote port range. If set locally, connect forwards it into the remote startup command. |
Each named remote app-server stores state under:
~/.codex/asm/<name>/
pid
port
workdir
server.log
connect reuses an existing app-server when the same --name points to the same remote workdir and remote port. If the name is already running for a different workdir or fixed port, connect fails instead of attaching to the wrong project.
sequenceDiagram
autonumber
participant Client as Client shell
participant SSH as SSH
participant Remote as Remote bash
participant Server as Remote codex app-server
participant Codex as Local codex TUI
Client->>SSH: codex-asm connect devbox ~/work/project
SSH->>Remote: stream codex-asm and run __remote-start
Remote->>Server: codex app-server --listen ws://127.0.0.1:PORT
Remote-->>Client: return remote PORT
Client->>SSH: ssh -N -L 127.0.0.1:LOCAL:127.0.0.1:PORT devbox
Client->>Codex: codex --remote ws://127.0.0.1:LOCAL
Codex->>Server: WebSocket over SSH tunnel
The app-server only listens on remote 127.0.0.1. The client reaches it through SSH port forwarding.
When the local Codex client exits, codex-asm closes the SSH tunnel. The remote app-server keeps running and can be reused by the next connect call.
If the network drops while a turn is active, reconnect with the same command:
codex-asm connect devbox ~/work/projectThen use Codex resume commands inside the TUI if needed.
codex-asm intentionally binds the app-server to remote loopback:
codex --dangerously-bypass-approvals-and-sandbox app-server --listen ws://127.0.0.1:PORTDo not expose the app-server directly on 0.0.0.0. Use SSH for access control and encryption.
The remote app-server has strong execution power in the selected remote workdir. Use it only on trusted machines, trusted accounts, and trusted repositories.
This version is not a lifecycle manager with start, status, client, list, or stop commands. The supported public workflow is connect.