Purpose
codex-control-plane-mcp is a persistent MCP control plane that provides reliable automation for long-running Codex Desktop tasks. It turns Codex Desktop and codex-app-server into a persistent worker that can be safely driven by MCP clients.
Its core contract is: after submitting a task, immediately return an operationId or workflowId, then poll until the work is complete, approve Plan Mode when necessary, and finally read the final report. This avoids hours-long MCP calls, duplicate Codex turns after client retries, and blind fire-and-forget task submissions, and provides a local SQLite record of operations, workflows, turns, hooks, and diagnostics.
Main capabilities
- Persistent asynchronous queue for Codex write operations.
- Retry-safe client_request_id handling.
- Active duplicate prompt detection.
- SQLite leases and heartbeats to coordinate competing MCP processes.
- Recovery after MCP restart during thread/start or turn/start.
- Persistent turn/steer to add context to an active turn without creating a second turn.
- Persistent thread/fork for branching an existing thread, with or without an initial message.
- Plan Mode workflow: start a plan, poll, approve, execute, read the final report. The Plan Mode runtime lower bound is workspace-write, and when MCP promotes a read-only request, runtimePolicyAdjusted is returned in the status.
- Code review workflow via app-server review/start, with polling and final report capture.
- Structured final reports using output_schema.
- Thread lifecycle tools: archive, unarchive, and pollable compaction.
- Workflow goals synchronized with Codex Desktop thread goals.
- Turns started via turn/start support image and local image input.
- Expose pending approvals and questions as pollable MCP status.
- Interrupt turns by threadId / turnId, operationId, or workflowId.
- RunHour list: models, permission configuration, sandbox readiness state, hooks, skills, provider capabilities, account status, usage range, rate limit status, and supported app-server methods.
- Health checks, diagnostics, problem analysis, and dry-run repairs.
- MCP-owned hook history stored in SQLite, used for search, summaries, and fallback reads.
- Redacted app-server progress logs, including increments, warnings, model rerouting, and token usage.
- Structured MCP errors, for automated code branching.
Write operations and control operations are executed through codex-app-server. The server does not modify Codex's internal SQLite database or transcript files.
Usage
Currently the full live target is Codex Desktop and codex-app-server on Windows; Linux and macOS currently only support protocol checks. This is a local-first control plane and should not be exposed as a network service without authentication.
Recommended first-run posture: use read-only for untrusted repositories; use on-demand approval when testing new workflows; Plan Mode never runs under a read-only sandbox, and if the caller requests read-only, MCP will elevate that turn to workspace-write and report the adjustment in the status output; keep state/, logs/, .env, and .codex/ private.
After installation, generate configuration and run the MCP server in stdio mode. The legacy openclaw-codex-mcp and openclaw-codex-mcp-hooks commands are still retained as compatibility aliases in the next release line.
In the default inline mode, a single MCP process can submit and execute operations. For OpenClaw, Hermes, or any setup with multiple MCP clients, a central worker is recommended: all MCP clients use the same CODEX_HOME and CODEX_MCP_STATE_DB; the OpenClaw gateway entry runs with CODEX_MCP_EXECUTION_MODE=client; a long-running codex-control-plane-mcp-worker process owns codex-app-server, leases, queue slots, and resource locks; clients call codex_submit_task,Then poll the status and do not perform queueing operations yourself.
The management assistant can generate a more complete client configuration, install hooks, and run protocol smoke tests. The installer backs up ~/.codex/hooks.json, merges its handlers with existing hooks, stores stateDb as an absolute path, and writes prompts, visible proxy progress text, final answers, and turn status to the MCP state database. By default, tool calls and command output are not logged. Restart Codex after installing or changing hooks.
For turns started via codex-app-server, the server mirrors accepted prompts, visible assistant messages, and turn status into the same SQLite history.
Applicable scenarios
Suitable for local orchestrators that need to have Codex Desktop execute long-running tasks, such as OpenClaw, Hermes, or any multi-MCP client setup. Supports submitting persistent tasks, attaching screenshots or other image evidence, steering active turns, starting work immediately in a thread branch, managing thread lifecycle, requesting structured final reports, driving Plan Mode, mirroring workflow goals to Codex Desktop, running Codex code reviews, handling approvals and questions, and starting diagnostics and repairs.
Before orchestration or after reconnecting, use codex_get_runtime_capabilities to get runtime capabilities. It starts the MCP-owned app-server when needed, calls short best-effort manifest methods, and returns a snapshot cached for five minutes. In client mode, the client process does not start its own app-server for live manifests; when a snapshot managed by a passive worker exists, that snapshot is returned. Use refresh=true to bypass the cache.
Limitations
- Full live support is currently limited to Windows with Codex Desktop and codex-app-server; Linux and macOS are protocol checks.
- Local-first, not intended to be exposed as a public network service, and must not be exposed as a network service without authentication.
- Write and control operations are performed through codex-app-server and do not modify Codex's internal SQLite database or transcript files.
- Public status payloads are proxy-safe and do not contain full prompts, full instructions, raw titles, raw image URLs/paths, exact token counts, raw command output, or private paths.
- MCP does not extract hidden chain of thought, and does not store raw tool payloads or command output in final reports.
- Public thread/delete is intentionally not exposed.
- Image input is accepted only for operation types that start a new turn.
- output_schema object schemas must use the strict form required by Codex, with additionalProperties set to false.
- Plan Mode never runs under a read-only sandbox.
- If agentGuidance.loopGuard.allowed=false, automatic recovery should stop, diagnostics should be collected, and a human should be asked; do not create a new client_request_id after a timeout unless the guidance explicitly requires starting a replacement workflow.
- codex_health_summary by default concerns current readiness state; stale or orphaned rows are reported in historicalDebt but do not affect the current health judgment.
- Specific charges, prices, and platform support details are not provided for now.