[macOS][regression] `codex_app` MCP override makes `CODEX_APP_SERVER_USE_LOCAL_DAEMON=1` unreachable
Summary
After updating ChatGPT Desktop, the existing managed local App Server path no longer works in a normal Desktop startup.
CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 is present in the Desktop process environment and the managed daemon is healthy, but Desktop starts a private stdio app-server instead of attaching to the daemon's Unix socket. If another local client is already using the same thread through the managed daemon, Desktop then shows:
This is open in another app Close it there to continue here.
This appears to be a startup-logic regression caused by the new app-managed codex_app MCP override.
Environment
- ChatGPT Desktop:
26.820.60940(build7119) - Bundled Codex:
codex-cli 0.150.0-alpha.8 - Standalone managed Codex/App Server:
0.149.1 - Bundled
codex-app-toolsplugin:0.1.3 - macOS:
26.5.2(25F84) - Architecture: Apple Silicon /
arm64
Managed daemon status before launching Desktop:
{
"status": "running",
"backend": "pid",
"managedCodexVersion": "0.149.1",
"socketPath": "$CODEX_HOME/app-server-control/app-server-control.sock",
"cliVersion": "0.150.0-alpha.8",
"appServerVersion": "0.149.1"
}
Previously working behavior
Before the Desktop update, this setup worked:
ChatGPT Desktop ────────┐
├─ managed app-server --listen unix://
local sidecar/client ───┘
Both clients connected to the same Unix socket and could observe/continue the same live thread.
This is the same shared-daemon topology documented in #31991.
Steps to reproduce
- Install the standalone Codex package.
- Start the managed App Server:
``bash``
codex app-server daemon bootstrap
- Ensure the Desktop process receives:
``bash``
launchctl setenv CODEX_APP_SERVER_USE_LOCAL_DAEMON 1
- Fully quit and restart ChatGPT Desktop.
- Connect a second local client to
$CODEX_HOME/app-server-control/app-server-control.sock. - Open or continue a thread through that client.
- Open the same thread in ChatGPT Desktop.
Actual behavior
Desktop does not attach to the managed daemon. It uses a private stdio app-server, so the system has two app-server processes with separate writer ownership:
ChatGPT Desktop ── private app-server --listen stdio://
local client ───── managed app-server --listen unix://
Opening the managed-daemon thread in Desktop produces the active-writer / “open in another app” conflict.
Fully quitting Desktop releases its private writer, but that defeats the shared-client workflow.
Diagnostic evidence
Inspection of the packaged Desktop startup logic shows that the managed-daemon branch is selected only when all of the following are true, including:
configOverrides.length === 0 &&
process.env.CODEX_APP_SERVER_USE_LOCAL_DAEMON === "1"
The same startup now creates the Codex app-tools native pipe, sets CODEX_APP_TOOLS_PIPE_PATH, reads the bundled codex-app-tools/desktop-mcp.json, and returns a request-level override for:
mcp_servers.codex_app
Therefore, on a healthy normal Desktop startup:
codex_app native pipe starts
→ mcp_servers.codex_app override is non-empty
→ configOverrides.length !== 0
→ managed-daemon branch is skipped
→ private stdio app-server is spawned
The daemon version gate is not the blocker: the packaged minimum is older than 0.149.1, so this execution path is rejected before daemon version selection matters.
The current Desktop process environment was also checked:
CODEX_APP_SERVER_USE_LOCAL_DAEMON=set
CODEX_APP_TOOLS_PIPE_PATH=set
CODEX_CLI_PATH=unset
CODEX_APP_SERVER_FORCE_CLI=unset
CODEX_APP_SERVER_WS_URL=unset
Expected behavior
If CODEX_APP_SERVER_USE_LOCAL_DAEMON=1 is set and a compatible daemon is healthy, Desktop should attach to it.
At minimum, one of these should be supported:
- Give the explicit local-daemon setting precedence and disable Desktop-only app tools with a clear warning.
- Provide a supported setting to disable the app-managed
codex_appMCP injection. - Make the
codex_apptools client/session-scoped so they do not require a process-wide app-server config override. - Support per-connection config overlays on the managed daemon.
Why this is distinct from a generic writer-lock issue
The writer conflict is the visible symptom. The earlier transport-selection decision is the regression: an automatically injected Desktop MCP override makes the existing local-daemon branch unreachable during normal startup.
Related reports cover the individual symptoms, but not this combined cause:
- #31991 — previously working Desktop + managed App Server topology
- #37403 — Desktop/CLI/Remote thread gets
already has an active writerafter update - #40157 — standalone app-server/Remote → Desktop produces “opened in another app”
- #40860 — Desktop injects
mcp_servers.codex_appeven when absent from user config - #40819 — request-level
codex_appconfig overrides file-level configuration
Additional note
I understand that CODEX_APP_SERVER_USE_LOCAL_DAEMON is undocumented. However, the current Desktop bundle still contains the environment-variable check, daemon discovery/version gate, and Unix-socket transport path. The automatic codex_app override now prevents that retained path from being selected.
No thread IDs, usernames, repository names, or private paths are included.
1 Comment
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action