Codex Desktop + WSL: `invalid transport in mcp_servers.codex_app` caused by injected `enabled_tools` without transport

Resolved 💬 1 comment Opened Aug 26, 2026 by ViperTecCorporation Closed Aug 26, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex Desktop fails to open/resume tasks when running the app-server in WSL with:

Error loading config.toml:
invalid transport
in `mcp_servers.codex_app`

Feedback ID: 01a0104e-ffed-74d1-9278-34af2907b2d2

Environment

  • Codex Desktop: 26.820.7780.0
  • Desktop bundled Codex runtime: codex-cli 0.150.0-alpha.8
  • WSL: Ubuntu 24.04
  • Standalone Codex CLI in WSL: initially 0.144.4; also tested with 0.150.0-alpha.8
  • Desktop configuration:
  • runCodexInWindowsSubsystemForLinux = true
  • integratedTerminalShell = "wsl"

What was ruled out

The problem does not originate from the user's config.toml.

Tested without resolving the issue:

  • Removed manually configured MCP servers.
  • Disabled bundled plugins.
  • Renamed/removed the WSL $HOME/.codex/config.toml.
  • Tested a minimal configuration.
  • Aligned the standalone WSL CLI with the Desktop bundled runtime (0.150.0-alpha.8).
  • Tested/replaced the bundled Codex executable.

Root cause identified

I intercepted the JSON-RPC traffic sent by Codex Desktop to the WSL app-server.

During thread/resume, Desktop sends a flat configuration override similar to:

{
  "config": {
    "mcp_servers.codex_app.enabled_tools": [
      "automation_update",
      "open_in_codex",
      "navigate_to_codex_page",
      "read_thread_terminal",
      "consume_usage_reset",
      "share_thread",
      "load_workspace_dependencies",
      "capture_screen_context",
      "end_realtime_voice_call",
      "fork_thread",
      "handoff_thread",
      "get_handoff_status",
      "list_projects",
      "create_thread",
      "list_threads",
      "list_archived_threads",
      "read_thread",
      "wait_threads",
      "send_message_to_thread",
      "set_thread_pinned",
      "set_thread_archived",
      "set_thread_title",
      "uninstall_plugin"
    ]
  }
}

No corresponding mcp_servers.codex_app.command or mcp_servers.codex_app.url is supplied.

The core therefore sees an MCP server named codex_app but cannot determine a transport, producing:

invalid transport in mcp_servers.codex_app

Workaround / confirmation

I built a small Linux binary wrapper between Codex Desktop and the bundled WSL app-server. It intercepts JSON-RPC stdin and removes flat overrides matching:

mcp_servers.codex_app.*

before forwarding the message to the real bundled codex 0.150.0-alpha.8 executable.

With that override filtered, the affected task opens successfully. This strongly indicates the failure is in the Desktop -> WSL app-server configuration injection path rather than the user's TOML configuration.

Additional WSL-specific finding

The Desktop app-server runs in a different mount namespace from the user's normal WSL shell. Example observed during debugging:

User WSL shell:             mnt:[4026532481]
Codex Desktop app-server:   mnt:[4026532221]

As a result, a normal bind mount from the interactive WSL shell does not affect the Desktop app-server. For the workaround, the wrapper had to be bind-mounted inside the app-server mount namespace using nsenter -t <PID> -m.

Desktop launches the bundled runtime as:

/mnt/c/Users/<user>/.codex/bin/wsl/<runtime-hash>/codex \
  -c features.code_mode_host=true \
  app-server \
  --analytics-default-enabled

The runtime reports codex-cli 0.150.0-alpha.8 and is recreated automatically by Desktop if its runtime directory is renamed/removed.

Secondary observation

When the real bundled Codex executable was relocated to /home/<user>/codex-desktop-real for the wrapper test, it attempted to resolve codex-code-mode-host relative to the executable location (/home/<user>/codex-code-mode-host). A symlink to the bundled codex-code-mode-host resolved that secondary issue.

Expected behavior

Codex Desktop should either:

  1. provide a complete valid transport definition for the internally injected codex_app MCP server; or
  2. treat codex_app as an internal Desktop MCP without passing an incomplete server definition through normal mcp_servers.* config parsing.

At minimum, injecting only mcp_servers.codex_app.enabled_tools should not cause config loading to fail when neither command nor url is present.

Reproduction signal

The critical reproducible signal is the thread/resume JSON-RPC request containing mcp_servers.codex_app.enabled_tools without a transport. Filtering that key before it reaches the real app-server makes the task load successfully.

View original on GitHub ↗

1 Comment

github-actions[bot] contributor · 1 day ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #40881
  • #40819
  • #40829
  • #40732
  • #40715

Powered by Codex Action