Codex Control Plane MCP
The Codex Control Plane MCP server provides durable, asynchronous orchestration of Codex Desktop tasks without requiring a long-lived MCP connection. Key capabilities include:
Durable Task & Operation Management
Submit long-running tasks (
codex_submit_task) and poll their status (codex_get_operation_status)Retry-safe idempotency via
client_request_idto recover from timeouts without duplicate turns
Plan Mode Workflows
Start (
codex_start_plan_workflow), poll (codex_get_workflow_status), approve (codex_approve_plan), and execute plans — managing both planning and execution phases
Approvals & Interaction Handling
List and answer pending interactions (
codex_list_pending_interactions,codex_answer_pending_interaction) so active turns can continue
Turn Control
Steer active turns with additional context, interrupt running turns (
codex_interrupt_turn) by turn/thread/operation/workflow ID
Chat & Project Management
List projects and chats, search across history and transcripts, get chat status and full content (
codex_list_projects,codex_search_chats,codex_get_chat, etc.)
Compatibility Write Tools
codex_start_chat,codex_send_message,codex_execute_planfor legacy clients
App-Server Management
Check and restart the
codex-app-serversubprocess (codex_get_app_server_status,codex_restart_app_server)
Runtime Capabilities & Health
Inspect models, sandbox readiness, hooks, and skills (
codex_get_runtime_capabilities); get a quick health check (codex_health_summary)
Diagnostics & Repair
Collect full diagnostic snapshots (
codex_collect_diagnostics), read redacted logs (codex_get_diagnostic_logs), analyze root causes (codex_analyze_issue), and run safe allowlisted repairs (codex_repair_issue, dry-run by default)
Progress Journaling
Compact journal of progress events (assistant text, plan deltas, token usage, model reroutes) available via status tools for orchestrators and troubleshooting
Operation state is persisted in a local SQLite database, enabling recovery across client timeouts and MCP process restarts.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Codex Control Plane MCPstart a plan mode workflow to refactor the authentication module"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Codex Control Plane MCP
English | Русский
Reliable Codex Desktop automation for long tasks.
codex-control-plane-mcp turns Codex Desktop and codex-app-server into a
durable worker that an MCP client can drive safely. Send a task, get an
operationId or workflowId right away, poll until the work finishes, approve
Plan Mode when needed, then read the final report.
The server handles the awkward parts that thin wrappers usually leave to the caller: app-server startup, thread and turn creation, retry safety, duplicate prompt protection, Plan Mode, approvals, local history, diagnostics, and repair.
OpenClaw and Hermes are first-class clients, but the server is useful for any local orchestrator that needs Codex Desktop to do long-running work without holding one MCP call open for hours.
The short version
MCP client / orchestrator
-> submit a task or start a Plan Mode workflow
<- receive operationId or workflowId immediately
-> poll status
-> answer approvals or approve the plan
<- read final report, diagnostics, threadId, and turnIdThat gives you a simple contract:
no multi-hour MCP calls;
no duplicate Codex turns after a client retry;
no blind fire-and-forget task submission;
a local SQLite record of operations, workflows, turns, hooks, and diagnostics.
Related MCP server: RPA MCP Server
Why not just call Codex directly?
Capability | Thin Codex wrapper | Codex Control Plane MCP |
Multi-hour tasks | blocking / fragile | durable async operation |
Client timeout recovery | manual | retry-safe |
Duplicate turn protection | no | active prompt detection |
Plan Mode workflow | human / manual | pollable workflow state |
Approvals and questions | blocking / opaque | pending interactions API |
Restart recovery | ad hoc | persisted operation state |
Diagnostics | logs only | health, diagnostics, repair tools |
Current support
Full live target: Windows with Codex Desktop and
codex-app-server.Linux and macOS: protocol-only checks for now.
Local-first: not intended to be exposed as a public network service.
Security model
This is a local-first control plane for trusted Codex Desktop environments.
Do not expose it as a network service without authentication.
Recommended first-run posture:
use
read-onlyfor untrusted repositories;use
on-requestapproval when testing new workflows;keep
state/,logs/,.env, and.codex/private.
What it does
Durable async queue for Codex write operations.
Retry-safe
client_request_idhandling.Active duplicate prompt detection.
SQLite leases and heartbeats for competing MCP processes.
Recovery after MCP restart during
thread/startorturn/start.Durable
turn/steerfor adding context to an active turn without creating a second turn.Plan Mode workflows: start plan, poll, approve, execute, read final report.
Pending approvals and questions exposed as pollable MCP state.
Turn interrupts by
threadId/turnId,operationId, orworkflowId.Runtime inventory for models, permission profiles, sandbox readiness, hooks, skills, provider features, and supported app-server methods.
Health checks, diagnostics, issue analysis, and dry-run repairs.
MCP-owned hook history in SQLite for search, summaries, and fallback reads.
Redacted app-server progress journal for deltas, warnings, model reroutes, and token usage.
Structured MCP errors that automation code can branch on.
Write and control actions go through codex-app-server. The server does not
mutate Codex internal SQLite databases or transcript files.
Install
Recommended:
pipx install codex-control-plane-mcpOr run directly:
uvx codex-control-plane-mcpFrom GitHub:
python -m pip install "codex-control-plane-mcp @ git+https://github.com/aresyn/codex-control-plane-mcp.git"For local development:
git clone https://github.com/aresyn/codex-control-plane-mcp.git
cd codex-control-plane-mcp
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m pytest -qMCP client config
After installation, generate a config:
codex-control-plane-mcp-admin init --state-db .\state\codex-mcp-state.sqlite3 --projects-root C:\Users\you\ProjectsMinimal stdio entry:
{
"mcpServers": {
"codex-control-plane": {
"command": "codex-control-plane-mcp",
"args": []
}
}
}Run the MCP stdio server:
codex-control-plane-mcpOr run it as a module:
py -m codex_control_plane_mcp.serverThe old openclaw-codex-mcp and openclaw-codex-mcp-hooks commands remain as
compatibility aliases for one release line.
First setup
The admin helper can generate a fuller client config, install hooks, and run a protocol smoke:
codex-control-plane-mcp-admin init --state-db .\state\codex-mcp-state.sqlite3 --projects-root C:\Users\you\ProjectsThe command prints a JSON block you can copy into an MCP client config. It does not print secrets or private prompts.
You can also install only the Codex hooks:
codex-control-plane-mcp-hooks install --state-db .\state\codex-mcp-state.sqlite3
codex-control-plane-mcp-hooks status
codex-control-plane-mcp-hooks doctorThe installer backs up ~/.codex/hooks.json, merges its handlers with your
existing hooks, stores stateDb as an absolute path, and writes prompts, visible
agent progress text, final answers, and turn status into the MCP state DB. Tool
calls and command outputs are not recorded by default. Restart Codex after
installing or changing hooks.
For turns launched through codex-app-server, the server mirrors the accepted
prompt, visible assistant messages, and turn status into the same SQLite
history. That keeps search and status reads useful even when app-server does not
execute user hooks itself.
Main workflows
Submit a durable task:
codex_submit_task
-> operationId
codex_get_operation_status(operationId)
-> queued / running / waiting_for_approval / completed / failedUse the same client_request_id when a caller retries after a transport timeout.
The retry returns the existing operation instead of creating another turn.
Steer an active turn:
codex_submit_task(operation_type="steer_turn", thread_id=..., expected_turn_id=..., message=...)
-> operationId
codex_get_operation_status(operationId)
-> follows the target turn until completed / failed / interruptedUse steer_turn only while the target turn is active. For a completed thread,
use send_message instead.
Drive Plan Mode:
codex_start_plan_workflow
-> workflowId
codex_get_workflow_status(workflowId)
-> wait_plan / review_plan / execute_plan
codex_approve_plan(workflowId)
-> executionOperationId
codex_get_workflow_status(workflowId)
-> finalReportHandle approvals and questions:
codex_list_pending_interactions
codex_answer_pending_interactionStart diagnostics with:
codex_get_runtime_capabilities
codex_health_summary
codex_collect_diagnostics
codex_analyze_issue
codex_repair_issueRepair actions default to dry_run=true.
Runtime capabilities
Use codex_get_runtime_capabilities before orchestration or after reconnect. It
starts the MCP-owned app-server if needed, calls short best-effort inventory
methods, and returns a cached snapshot for five minutes.
The response includes:
model count, default model, hidden flags, input modalities, reasoning efforts, and service tier count;
permission profiles by
idanddescription;Windows sandbox readiness;
provider capabilities for web search, image generation, and namespace tools;
hook and skill counts without raw hook commands or absolute skill paths;
supported app-server schema methods with a compact source, version, and hash.
If one inventory method times out or fails, the tool still returns ok=true
with runtimeCapabilities.status="partial" and a machine-readable warning in
methodResults. Set refresh=true to bypass the cache. codex_health_summary
shows a small runtimeCapabilities subset from the last collected snapshot and
does not start app-server on its own.
Progress journal
codex_get_turn_status and codex_get_operation_status include a compact
progressEvents block by default. It captures app-server-visible progress such
as assistant text deltas, plan deltas, reasoning summary text, token usage,
model reroutes, and warnings.
The journal helps with orchestration and troubleshooting. It does not extract hidden chain-of-thought. It also does not store raw tool payloads, command output, or full unified diffs by default. Diff events are reduced to safe counts, such as changed line count and diff size.
Use progress_events=0 when a client wants the older, message-only status
shape. Use progress_max_chars to cap returned progress text.
Tool surface
Stable orchestration tools:
codex_submit_taskcodex_get_operation_statuscodex_start_plan_workflowcodex_get_workflow_statuscodex_approve_plancodex_list_pending_interactionscodex_answer_pending_interactioncodex_interrupt_turncodex_get_runtime_capabilitiescodex_health_summarycodex_collect_diagnosticscodex_repair_issue
Compatibility and read tools:
codex_start_chatcodex_send_messagecodex_execute_plancodex_list_projectscodex_list_project_chatscodex_list_active_chatscodex_search_chatscodex_get_chat_statuscodex_get_chatcodex_get_turn_statuscodex_restart_app_servercodex_get_app_server_statuscodex_get_diagnostic_logscodex_analyze_issue
New clients should use durable operations and workflows. Low-level write tools stay available for compatibility.
See docs/API_CONTRACT.md for schemas, error shape, stable tool groups, and versioning rules.
Result contract
Every tool declares an outputSchema and returns MCP structuredContent.
Success:
{"ok": true}Domain or tool error:
{
"ok": false,
"error": {
"code": "CODEX_ERROR_CODE",
"message": "Human readable message",
"details": {},
"retryable": false
}
}Call codex_health_summary on startup and reconnect. The version block
contains serverName, serverVersion, contractVersion, toolSurfaceHash,
and stable/compatibility tool lists.
Configuration
Configuration can come from environment variables or from a JSON file referenced
by CODEX_CONTROL_PLANE_MCP_CONFIG. The old OPENCLAW_CODEX_MCP_CONFIG name is
still accepted as a fallback.
Common variables:
CODEX_HOME: Codex home directory. Defaults to%USERPROFILE%\.codex.CODEX_PROJECTS_ROOT: project root scanned by catalog and read tools.CODEX_ALLOWED_ROOTS: semicolon-separated path allowlist.CODEX_PROJECTS_REGISTRY: optional JSON project registry.CODEX_MCP_STATE_DB: local MCP state DB.CODEX_CONTROL_PLANE_MCP_LOG: log file path.CODEX_MCP_HOOK_HISTORY_ENABLED: enables SQLite hook history. Defaults totrue.CODEX_MCP_HOOK_HISTORY_MAX_TEXT_CHARS: per-message hook capture limit.CODEX_KB_HISTORY_PROJECTS_ROOT: optional legacy normalized KB history root.CODEX_BINARY_PATH: optional explicit Codex binary path.CODEX_MCP_DEFAULT_SANDBOX: default write sandbox. Defaults toread-only.CODEX_MCP_DEFAULT_APPROVAL_POLICY: default write approval policy. Defaults toon-request.CODEX_MCP_DEFAULT_MODEL: default Codex model passed to app-server.CODEX_MCP_DEFAULT_EFFORT: default effort level.CODEX_MCP_APPROVAL_RESPONSE_TIMEOUT_SECONDS: pending interaction timeout.DEEPSEEK_ENV_PATH: optional.envfile for DeepSeek summary settings.DEEPSEEK_SUMMARY_ENABLED: enables or disables remote summary calls.
The write policy values are defaults, not hard limits. A client call can pass
sandbox or approval_policy explicitly when a trusted workflow needs a
different posture.
Example:
$env:CODEX_CONTROL_PLANE_MCP_CONFIG = Join-Path (Get-Location) "examples\codex-control-plane-mcp.config.json"
$env:CODEX_MCP_DEFAULT_SANDBOX = "read-only"
$env:CODEX_MCP_DEFAULT_APPROVAL_POLICY = "on-request"
py -m codex_control_plane_mcp.serverSee examples/codex-control-plane-mcp.config.json.
Reliability model
The server is built for common local orchestration failures:
MCP client timeout after task submission.
Repeated submit with the same
client_request_id.Repeated submit without an idempotency key but with the same active prompt.
MCP process restart between app-server
thread/startandturn/start.Two MCP processes sharing one SQLite state DB.
App-server exit while a turn is active.
Pending approval tied to an old app-server generation.
App-server or transcript gaps where hook history still captured the prompt, visible agent text, final answer, and completion status.
These cases are stored in durable operation, workflow, turn, hook, and pending
interaction state. Terminal statuses are explicit.
unknown_after_app_server_exit is not treated as success.
Safety
Live smoke prompts must include
MCP LIVE TEST / DO NOT MODIFY FILES.Repairs default to
dry_run=true.Forced app-server restart can mark active turns as unknown or orphaned. Prefer
restart_app_server_idle.
Checks
Fast local checks:
python -m pytest -q
python -m compileall -q openclaw_codex_mcp codex_control_plane_mcp tests scripts
git diff --checkProtocol-only MCP smoke:
python .\scripts\mcp_live_smoke.py --scenario protocolSafe live smoke with real Codex Desktop/app-server:
python .\scripts\mcp_live_smoke.py --scenario safe-operation --cwd <PROJECT_ROOT>Full live regression:
python .\scripts\mcp_live_smoke.py --scenario full --safe-restart --cwd <PROJECT_ROOT>See docs/RELEASE_CHECKLIST.md. For public launch positioning, see docs/PUBLICATION_GUIDE.md.
Packaging
Build locally:
python -m pip install build
python -m buildThe wheel includes the MCP server, the hook installer, the admin helper, and the bundled Codex hook module.
The normal install path is:
pipx install codex-control-plane-mcpor:
uvx codex-control-plane-mcpContributing
Read CONTRIBUTING.md and SECURITY.md before opening issues that include diagnostics.
Good GitHub topics for this repo:
python, mcp, mcp-server, model-context-protocol, openai-codex,
codex, codex-desktop, agent-tools, ai-agents, developer-tools,
automation, orchestration, agentic-workflows, long-running-tasks,
openclaw, hermes, hermes-agent.
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/aresyn/codex-control-plane-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server