AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified Apache-2.0 Self-run

Codex Control Plane Mcp

mcp-aresyn-codex-control-plane-mcp · by aresyn

Durable MCP control plane for long-running Codex Desktop tasks

No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add mcp-aresyn-codex-control-plane-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-aresyn-codex-control-plane-mcp)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Codex Control Plane Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

[](https://mseep.ai/app/aresyn-codex-control-plane-mcp)

Codex Control Plane MCP

English | [Русский](README.ru.md)

[](https://github.com/aresyn/codex-control-plane-mcp/actions/workflows/ci.yml) [](https://pypi.org/project/codex-control-plane-mcp/) [](https://www.python.org/) [](LICENSE) [](docs/API_CONTRACT.md)

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
   poll status
  -> answer approvals or approve the plan
   operationId
codex_get_operation_status(operationId)
  -> queued / running / waiting_for_approval / completed / failed

Use the same client_request_id when a caller retries after a transport timeout. The retry returns the existing operation instead of creating another turn.

Attach screenshots or other image evidence:

codex_submit_task(
  operation_type="start_chat",
  message="Analyze this screen.",
  input_items=[
    {"type": "localImage", "path": ".\\screens\\error.png", "detail": "low"},
    {"type": "image", "url": "https://example.com/screenshot.png", "detail": "high"}
  ]
)

Image inputs are accepted only for operation types that start a new turn: start_chat, send_message, execute_plan, and fork_thread with an initial message. MCP sends the path or URL to codex-app-server, but operation status and diagnostics return only safe metadata such as type, detail, size, extension, and hashes. Binary image content, raw URLs, and full local image paths are not stored in public status payloads.

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 / interrupted

Use steer_turn only while the target turn is active. For a completed thread, use send_message instead.

Fork a thread:

codex_submit_task(operation_type="fork_thread", source_thread_id=...)
  -> operationId
codex_get_operation_status(operationId)
  -> completed, threadId=

Start work in the fork right away:

codex_submit_task(operation_type="fork_thread", source_thread_id=..., message=...)
  -> operationId
codex_get_operation_status(operationId)
  -> follows the first turn in the forked thread

Use client_request_id for retry-safe fork requests. Without it, each call is treated as a new fork request. threadId in operation status is the forked thread; the source thread is reported in forkState.sourceThreadId.

Manage thread lifecycle:

codex_archive_thread(thread_id)
  -> completed
codex_unarchive_thread(thread_id)
  -> completed
codex_start_thread_compaction(thread_id)
  -> actionId
codex_get_thread_compaction_status(actionId)
  -> running / completed / unknown_after_app_server_exit

Archive and unarchive are audit actions around app-server thread/archive and thread/unarchive. They refuse to run while the thread has an active turn or a pending interaction. Compaction uses its own lightweight actionId because thread/compact/start is asynchronous. Public thread/delete is intentionally not exposed.

Ask for a structured final report:

codex_submit_task(operation_type="start_chat", message=..., output_schema={...})
codex_approve_plan(workflowId, output_schema={...})
  -> operationId / executionOperationId
codex_get_operation_status(operationId)
codex_get_workflow_status(workflowId)
  -> finalReport.text + finalReport.structured

output_schema is passed to app-server turn/start and is tracked by a schema hash in status output. Object schemas must use the strict form required by Codex: set additionalProperties to false. MCP stores the final assistant message as readable text, then parses JSON object output into finalReport.structured when Codex returns valid JSON. Plain text still works and stays available in finalReport.text.

MCP does not extract hidden chain-of-thought and does not store raw tool payloads or command output in final reports.

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)
  -> finalReport

Plan Mode has a runtime floor. The public default write policy is still read-only and on-request, but Plan Mode needs a writable workspace on Windows. If the caller or server default resolves to read-only, MCP sends workspace-write to codex-app-server and returns requestedSandbox, effectiveSandbox, and runtimePolicyAdjusted in workflow and operation status.

Mirror a workflow goal into Codex Desktop when the client has one:

codex_start_plan_workflow(goal="Review the migration plan", goal_completion_action="clear")
codex_get_workflow_status(workflowId, refresh_live_goal=true)
  -> threadGoal.syncState + threadGoal.currentGoal

MCP writes a thread goal only when the client passes goal. Managed goals use clear after completion by default. Use set_complete or leave when the goal should remain visible after the workflow ends. Normal workflow polling is passive; use refresh_live_goal=true only when you want MCP to call live app-server goal methods.

Run a Codex code review:

codex_start_review_workflow(thread_id=..., target_type="base_branch", base_branch="main")
  -> workflowId
codex_get_workflow_status(workflowId)
  -> wait_review / read_review_report

Or let MCP create a service thread for a local checkout:

codex_start_review_workflow(cwd=..., target_type="uncommitted_changes")
  -> workflowId
codex_get_workflow_status(workflowId)
  -> reviewThreadId + reviewTurnId + finalReport

Review workflows do not write files by themselves. They run inside the selected Codex sandbox and approval policy. Use client_request_id when a caller may retry the start request after a transport timeout.

Handle approvals and questions:

codex_list_pending_interactions
codex_answer_pending_interaction

Start diagnostics with:

codex_get_runtime_capabilities
codex_health_summary
codex_collect_diagnostics
codex_analyze_issue
codex_repair_issue

Repair actions default to dry_run=true.

Status and diagnostic tools also return agentGuidance and agentGuidanceText when MCP sees a blocker, failed state, stale run, pending interaction, duplicate prompt, auth problem, rate limit, or unsafe recovery loop. Agents should follow agentGuidance.instructions before deciding to retry or stop. If agentGuidance.loopGuard.allowed=false, stop automatic recovery, collect diagnostics, and ask a human. Do not create a new client_request_id after a timeout unless the guidance explicitly says to start a replacement workflow.

For a broken Plan Mode workflow, use retry_workflow_with_runtime_policy. It creates a new workflow with the selected sandbox and approval policy, links it to the old workflow through workflowRetryState, and does not revive the old terminal turn.

codex_health_summary is about current readiness by default. Old stale or orphaned rows are reported in historicalDebt, but they do not make fresh orchestration look broken when the worker, queue, and app-server are currently healthy. Use targeted cleanup for that debt instead of blocking new work.

Status payloads now separate freshness signals:

  • operationRowAgeSeconds: age of the durable operation row;
  • turnFreshness.lastProgressAgeSeconds: age of the last turn progress event;
  • workerFreshness.heartbeatAgeSeconds: age of the worker heartbeat;
  • stalenessMeaning="operation_row_age" for the compatibility

stalenessSeconds field.

Public status payloads are agent-safe. Operation and workflow status return requestSummary instead of raw request; it contains ids, runtime policy, scheduling intent, input item state, output schema hash, resource keys, and text hashes. It does not include the full prompt, full instructions, raw title, raw image URL/path, exact token counts, raw command output, or private paths. Use your own stored task text plus requestSummary.*.sha256 for correlation.

codex_get_queue_status only recommends wait_for_worker_slot when there is actual queued work blocked by slots. If there are running turns but queueSummary.queued == 0, the queue action is none.

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.

In client mode, the client process does not start its own app-server for live inventory. It returns a passive worker-managed snapshot when one exists. With refresh=true, it queues a worker command and returns refreshCommandId; poll codex_get_worker_command_status to read the refreshed inventory.

The response includes:

  • model count, default model, hidden flags, input modalities, reasoning efforts, and service tier count;
  • permission profiles by id and description;
  • 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;
  • redacted account status, coarse usage bands, and operational rate-limit state;
  • supported app-server schema methods with a compact source, version, and hash.

Account inventory is safe to show to an orchestrator. It reports whether Codex is authenticated, the account and plan type, whether an email exists, whether usage data is available, and whether a rate limit or credits issue is visible. It does not return raw email, account identifiers, credit balances, spend limits, exact spend used, daily usage buckets, or exact token counts.

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. Pass include_account=false when a client does not need account, usage, or rate-limit status.

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.

Public status returns token usage as coarse bands, not exact token counts. Raw audit surfaces may keep redacted event payloads for debugging, but orchestrators should treat tokenUsage.totalTokensBand and related band fields as the public contract.

Tool surface

Stable orchestration tools:

  • codex_submit_task
  • codex_get_operation_status
  • codex_start_plan_workflow
  • codex_start_review_workflow
  • codex_get_workflow_status
  • codex_approve_plan
  • codex_list_pending_interactions
  • codex_answer_pending_interaction
  • codex_interrupt_turn
  • codex_archive_thread
  • codex_unarchive_thread
  • codex_start_thread_compaction
  • codex_get_thread_compaction_status
  • codex_get_runtime_capabilities
  • codex_health_summary
  • codex_collect_diagnostics
  • codex_repair_issue

Compatibility and read tools:

  • codex_start_chat
  • codex_send_message
  • codex_execute_plan
  • codex_list_projects
  • codex_list_project_chats
  • codex_list_active_chats
  • codex_search_chats
  • codex_get_chat_status
  • codex_get_chat
  • codex_get_turn_status
  • codex_restart_app_server
  • codex_get_app_server_status
  • codex_get_diagnostic_logs
  • codex_analyze_issue

New clients should use durable operations and workflows. Low-level write tools stay available for compatibility.

Read and diagnostic calls are bounded for agent loops. codex_list_projects defaults to compact cached output, codex_search_chats can return timeBudgetExhausted=true instead of blocking on a full refresh, and chat reads prefer tracked turn plus hook history before legacy KB fallback. Diagnostics are scoped-first: scopedFindings drive the next action, while backgroundFindings are historical context.

See [docs/APICONTRACT.md](docs/APICONTRACT.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, guideHash, guideVersion, recommended startup/write tools, and stable/compatibility tool lists.

Agents can discover the operating contract without reading this README. tools/list includes:

  • codexMcpGuide: compact machine-readable guide with capabilities, flows,

global rules, and runtime limits;

  • toolGroups: ordered groups of preferred tools;
  • recommendedStartupTool="codex_health_summary";
  • recommendedPrimaryWriteTool="codex_submit_task".

Every tool also has annotations.codexMcp with its role, follow-up tools, idempotency rule, passive-read flag, and mayStartTurn flag. If a client library hides top-level tools/list fields, call codex_get_agent_contract(detail="compact") or codex_get_agent_contract(detail="full", include_examples=true).

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 to true.
  • 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 to read-only.
  • CODEX_MCP_DEFAULT_APPROVAL_POLICY: default write approval policy. Defaults to on-request.
  • CODEX_MCP_DEFAULT_MODEL: default Codex model passed to app-server.
  • `CODEXMCPDEFAULT

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.