Skip to main content
Glama

Codex SSH Task Bridge

Temporary task-management tools for Codex chats on an SSH host. The bridge exposes an existing same-user Codex app-server as a local stdio MCP server. It does not launch an app-server, open a network port, copy credentials, patch Codex, or change your provider, account or model.

This is an independent workaround, not an official OpenAI product. Check whether a fresh SSH chat already has working native create/message/fork tools before installing it. Retire this bridge when the native path works for your use case.

Tools

  • bridge_status: check the existing app-server connection.

  • create_thread: create a host-local chat and optionally start a prompt.

  • fork_thread: fork a host-local chat and optionally start a prompt.

  • send_message_to_thread: start a turn on an idle chat, or steer an exact active turn.

  • list_threads / read_thread: inspect host-local chats.

  • wait_thread: wait for a turn started by this bridge connection.

These are app-server thread operations. Cross-host handoff, Git-state transfer, Desktop project/worktree creation and native subagent management are not implemented. Chats created directly through app-server may need separate Desktop discovery.

Related MCP server: opencode-codex-mcp

Requirements

  • macOS or Linux, Python 3.11+, and websocket-client==1.9.2.

  • A working Codex CLI, an existing same-user app-server Unix WebSocket, and a regular same-user Codex config.toml file.

  • Working inference through your existing host configuration.

The app-server API is experimental; newer Codex versions can require changes. See OpenAI's app-server documentation. A Unix socket needs a WebSocket handshake: piping newline-delimited JSON through codex app-server proxy alone does not provide it.

Install on the SSH host

Run these commands on the machine where the SSH chat executes. Keep runtime files outside the source checkout. The following uses conventional Codex paths; adjust CODEX_CONFIG, CONTROL_SOCKET and HOST_CODEX for your installation.

git clone https://github.com/tacodong/codex-ssh-task-bridge.git
cd codex-ssh-task-bridge

BRIDGE_HOME="$HOME/.local/share/codex-ssh-task-bridge"
python3 -m venv "$BRIDGE_HOME/venv"
"$BRIDGE_HOME/venv/bin/python" -m pip install -r requirements.txt

CODEX_CONFIG="$HOME/.codex/config.toml"
CONTROL_SOCKET="$HOME/.codex/app-server-control/app-server-control.sock"
HOST_CODEX="$(command -v codex)"
BRIDGE_RECEIPT="$BRIDGE_HOME/receipts/$(date -u +%Y%m%dT%H%M%SZ)"

codex --version
codex app-server daemon version

"$BRIDGE_HOME/venv/bin/python" install_codex_ssh_task_bridge.py \
  --source "$PWD/codex_ssh_task_bridge.py" \
  --config "$CODEX_CONFIG" --socket "$CONTROL_SOCKET" \
  --python "$BRIDGE_HOME/venv/bin/python" --codex "$HOST_CODEX" \
  --install-root "$BRIDGE_HOME/releases" --receipt-directory "$BRIDGE_RECEIPT"

The last command prepares and validates without writing. Repeat it with --apply to install. It installs immutable hash-named source, saves a protected config before-image, preserves unrelated parsed configuration, and atomically replaces only the configuration needed for this bridge. It refuses an existing entry by default. Use --upgrade with a new receipt directory only for an unchanged installer-owned entry; manually modified entries fail closed.

Installing explicitly trusts this bridge through its MCP entry's default_tools_approval_mode = "approve". That grants same-user chat-control capability. Other servers, shell approval policy and sandbox settings remain unchanged. Child chats inherit the host's native settings unless you explicitly supply overrides. The bridge declines interactive app-server approval requests; it does not impersonate an approval UI.

The before-image can contain private configuration. Keep it owner-only, outside Git, and do not attach it to issues. No account login or credential transfer is part of this installation. If the socket is missing, restore the normal supported Codex connection first; this installer deliberately does not bootstrap a server. A not managed restart response is not permission to kill an unknown server.

Verify through Desktop SSH

Open a fresh chat through the Desktop SSH connection after installation. Existing chats may have an older tool catalog. Check for mcp__ssh_task_bridge tools, then use this bounded prompt:

Test the installed ssh_task_bridge. First call bridge_status. Create one chat titled SSH bridge test with a prompt to reply exactly BRIDGE-CREATE-OK. Wait for completion and read back its stored reply. Send only that idle test chat a follow-up asking it to reply exactly BRIDGE-MESSAGE-OK, then wait and read it. Fork only that test chat with a prompt to reply exactly BRIDGE-FORK-OK, then wait and read the fork. You may create and message only these test chats. Report the exact tool names, results, child IDs, and actual execution route. Also list any native task-management tools exposed across all namespaces. Do not change config, credentials, provider, model, files, or other chats.

Confirm all three replies, persistence, and whether Desktop can discover the created chats. A shell probe or socket health check alone does not verify this Desktop path. Keep test transcripts and host details local.

On an unknown-outcome write timeout, use list/read to reconcile the existing operation. Do not repeat the write: it may already have succeeded. Start mode refuses busy targets; steer mode requires the exact active turn ID. Message another chat only with its user's authorization. Never target the calling chat.

Tests

python3 -m unittest discover -p test_codex_ssh_task_bridge.py -v

The test suite uses local fakes and temporary files; no credentials or live inference are needed. Temporary files should be directed to your normal private task-data directory when your workspace requires it.

Compatibility and acceptance

The original September 30, 2026 pilot passed 20 automated tests and a model-visible create/message/fork sequence on macOS. Linux ARM64 passed the automated suite and socket probe; a separate provider-authentication error prevented its inference acceptance. The original Desktop SSH frontend/discovery test remained incomplete.

On October 15, the existing installation's read-only status probe also succeeded with CLI 0.163.0 on macOS. Full fresh Desktop acceptance is still pending. These dated results are not a guarantee for every Codex version or host.

Remove

codex mcp remove ssh_task_bridge

Open a fresh SSH chat and confirm the bridge namespace is absent. This removes the MCP entry; immutable releases, the venv and private before-images remain. Keep them until recovery is no longer needed, then remove only your bridge-owned files. Do not restore an entire old config over concurrent settings, delete sessions, stop the shared server or change remote-control ownership.

Development

Runtime code, installer and tests live in this repository. Changes should preserve native parameter support, configuration fidelity, busy-target checks, approval boundaries and unknown-outcome handling. Run the suite above before submitting a change. Never include credentials, config backups, real prompts, private paths, or session data in a commit or issue.

License

MIT. See LICENSE.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.
    4
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients and external AI supervisors to oversee and steer native Codex sessions through a thin local stdio bridge. It exposes eleven codex_* supervisory tools for tasks such as listing threads, starting turns, observing progress, steering, responding to approvals, interrupting, checkpointing, and rolling over work.
    MIT