CCM
Click on "Deploy 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., "@CCMlist the connected execution environments and run 'npm test' on the local worker"
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.
CCM — Codex-Compatible MCP
CCM is a Codex-inspired execution harness for MCP clients. It focuses on a small, stable coding/execution surface, persistent process sessions, Remote Workers, native sandboxing, bounded tool output, patching, and image reads.
CCM does not attempt to reproduce Codex's model loop or own the host application's conversation history. The MCP client remains the orchestrator; CCM owns the execution world.
Status
CCM is currently targeting v0.1 as its first public release.
Milestone 1 — Execution Core: implemented and regression-tested.
Milestone 2 — Environment + Remote Worker: implemented and regression-tested.
Milestone 3 — Editing (
apply_patch,view_image): implemented and regression-tested.Milestone 4 — Tool Architecture / Code Mode: implemented and regression-tested.
The v0.1 release gate is defined in PROJECT.md. v0.1 is intended to be directly publishable rather than a private prototype.
Related MCP server: cmd-exec-mcp
Architecture
MCP client
|
v
CCM Controller
|- MCP HTTP server
|- ToolRegistry
|- Environment Registry
|- Workspace Context Manager
|- RemoteProcessManager / RemoteFileService
'- WorkerHub
|
v
Remote Worker
|- native shell / filesystem semantics
|- Worker-local Workspace Registry
|- ProcessManager
|- PTY
|- native sandbox
|- apply_patch
'- view_imageEvery execution environment uses the same Remote Worker protocol. The machine hosting the Controller is not a special execution backend: by default, npm start launches a normal Remote Worker locally and connects it through loopback.
Registered workspaces are owned by each Worker, not by the Controller. Entering or hot-registering a real project requires one-shot user approval and returns an opaque workspace_context. ccm.register_workspace already combines registration and entry; with create_if_missing=true, the same one-shot approval may also create the exact missing project directory before registration, so a new project does not need a separate shell mkdir approval followed by workspace approval. Normal development tools carry only the resulting context. Workspace contexts are persisted by the Controller and remain valid across Controller or Worker restarts. Worker-local projectless mappings are persisted as well, so a surviving projectless directory can be resumed after a Worker restart.
An environment does not expose a default workspace or default working directory to the MCP client. Worker bootstrap cwd is an internal/legacy runtime seed only; it is not a project-location hint, a default project, or the parent directory for newly created projects. CCM deliberately has no "Projects Root" policy: project placement comes from the user or the upper-layer orchestrator.
When no real project is selected, create an explicit projectless context with the deferred ccm.create_projectless_context capability through tool_search + exec. Pass environment_id to create it on a specific Worker, or omit environment_id to use the primary environment. Projectless workspaces are created under CCM_PROJECTLESS_ROOT (default: the user's Documents\\CCM directory) and do not require workspace approval. Do not register temporary directories, Documents, drive roots, or other arbitrary paths merely to obtain an execution context.
Identity and lifecycle terminology
CCM deliberately keeps transport identity, execution identity, process identity, and higher-level task state separate. Do not use the word "session" interchangeably for these concepts.
Host conversation / ChatGPT conversation: conversation state owned by the MCP client. CCM does not own it and must not assume a one-to-one mapping between a host conversation and an MCP session.
MCP session: the current CCM HTTP implementation's stateful Streamable HTTP protocol/transport session. It is created during MCP initialization, identified by the
Mcp-Session-Idheader, and used by the Controller to find the corresponding transport and protocol server. It may span multiple user turns, and a single host conversation may create more than one MCP session because of reconnects, fresh initialization, Controller restart, or other client lifecycle events. An MCP session is not a durable task, plan, workspace, or conversation identifier.Process session (
session_id): a live command/process continuation handle returned byexec_commandand consumed bywrite_stdin. It identifies one running process session and is unrelated toMcp-Session-Id.Workspace context (
workspace_context): an opaque logical execution-context identifier that binds a Worker and workspace/projectless root. Workspace contexts are persisted independently of MCP transport sessions and may remain valid across Controller or Worker restarts.Approval (
approval_id): a one-shot authorization record for one exact escalated operation or workspace entry attempt. It is neither an MCP session nor a workspace context.Plan: a logical planning cycle, if/when Plan Mode is used. One MCP session may contain zero, one, or multiple plans. A persisted plan may outlive the MCP session that created it. A session-scoped "active plan" pointer is only a convenience for multi-turn continuity and must never redefine the MCP session itself as the plan identity.
Useful cardinality rules:
host conversation -> 0..N MCP sessions
MCP session -> 0..N process sessions
MCP session -> 0..N logical plans
workspace_context -> independent of MCP session lifetime
persisted plan -> may outlive MCP session lifetimeWhen adding stateful features, choose an identity according to the feature's real lifecycle. Do not key durable intent solely by Mcp-Session-Id merely because it is convenient at the transport layer.
Direct MCP tools
Tool | Purpose |
| Show connected execution environments, capabilities, and coarse effective filesystem read/write scope. |
| Run a native shell command inside an existing |
| Record an explicit user decision for a pending one-shot CCM approval. |
| Write to or poll a live process session returned by |
| Apply a Codex-style patch inside an existing |
| Read and validate a bounded image inside an existing |
| Transfer a file from the Worker selected by |
| Discover deferred ToolRegistry capabilities without expanding the top-level MCP schema. |
| Dispatch one or more nested registered capabilities, sequentially or safely in parallel. |
| Resume a nested |
Normal repository inspection, search, Git, builds, tests, and diagnostics should usually go through exec_command.
Core deferred capabilities
These are core CCM operations but intentionally stay off the top-level MCP schema. Discover them with tool_search and invoke them through exec.
Capability | Purpose |
| Create a temporary projectless context on a chosen Worker, or on the primary Worker when no environment is specified. |
| Discover registered projects on one Worker without entering them. |
| Enter an explicitly selected registered project after user approval. |
| Register and enter an explicitly selected project directory after user approval; optionally create that exact missing directory with |
| Create or update one durable Plan using Codex-style patch syntax and an explicit opaque |
| Read, range-read, or search only the Plan identified by |
Durable Plans
CCM provides durable Plan storage without implementing a Controller-side "Plan Mode" state machine. When a user explicitly asks to plan/discuss before implementation and persistence is useful, discover ccm.plan_patch / ccm.plan_read through tool_search and invoke them through exec.
ccm.plan_patch omits plan_id only for the first write. That call creates a Plan and returns an opaque UUID; later reads/patches carry that id explicitly, so Plan identity is independent of MCP transport sessions. Managed Plans are stored centrally under ignored Controller state at .state/plans/<plan_id>.md; no public list/delete/search-other-Plans capability is exposed and v0.1 does not automatically expire or garbage-collect Plan files.
Plan patches reuse the normal Codex-style patch grammar but target one virtual file only: creation uses *** Add File: plan.md, and updates use *** Update File: plan.md. The real .state path is never accepted as a tool argument. Keep the logical Plan current rather than append-only: rewrite or remove completed, invalidated, obsolete, or superseded items while preserving active constraints and unresolved decisions. Unless the user explicitly instructs execution/implementation, Plan work remains planning; imperative wording, completed inspection, workspace approval, registration approval, or sandbox escalation approval does not itself authorize implementation. ccm.plan_read is intentionally lifecycle-neutral so implementation can consult a Plan repeatedly without re-entering planning behavior.
ToolRegistry and Code Mode
CCM stores capability exposure as three independent surfaces:
Direct — included in MCP
tools/list.Deferred — omitted from the initial schema and discoverable through
tool_search.Code Mode — callable as a nested capability through
exec.
Convenience states such as Direct, Deferred, CodeModeOnly, DirectModelOnly, DeferredModelOnly, and Hidden are derived from those surfaces rather than stored as one rigid enum.
The direct MCP surface is intentionally kept small and stable. New ordinary capabilities should default to the Deferred + Code Mode surfaces and be invoked through tool_search + exec. Add a new top-level Direct tool only when the capability is a common operational primitive or is fundamental to environment discovery, explicit approval, process continuation, or nested-tool discovery/dispatch. Workspace/context lifecycle tools intentionally remain Deferred.
Keeping ordinary additions off the Direct surface prevents routine feature work from changing the client's top-level MCP schema. In particular, adding a deferred capability should not require deleting and recreating the CCM integration in ChatGPT or another MCP client. Updating CCM server code may still require restarting the Controller and/or Worker processes so the new implementation is loaded; that is separate from recreating the client integration.
Do not promote a capability to Direct merely for convenience. Keep workspace/context lifecycle operations deferred, and prefer deferred ccm-extra.* or other namespaced capabilities for specialized workflows. The common operational file tools apply_patch, view_image, and send_file are intentionally Direct.
CCM deliberately does not embed a second JavaScript interpreter for Code Mode. The host application remains responsible for loops, branching, and data processing. CCM's exec/wait pair is a bounded structured dispatcher over ToolRegistry capabilities. state=completed is terminal. If nested dispatch has finished but an exec_command leaves a live process session, CCM returns state=awaiting_io with next_operation=write_stdin until those process sessions are continued separately.
ChatGPT Share conversation export
ccm-extra.chatgpt_share_export exports public ChatGPT Share conversations without BMG or browser automation.
Supported features:
mode=text: readable user/assistant conversation export.mode=full: preserves all message records exposed by the Share payload, including system/tool records and message metadata.ranch=active: follows the current Share branch when available.
ranch=all: exports all mapping nodes for debugging or archival.
Markdown and JSON output formats.
output_pathis optional. Omitted or relative paths are written under the Git-ignored.cache/chatgpt-share-export/directory; absolute paths are honored directly.Non-text messages such as image-only messages are retained rather than silently dropped.
The exporter only recovers information present in the public Share payload. Information removed upstream by ChatGPT is not recoverable.
Bundled specialized capabilities
CCM ships optional Windows workflows ported from WCM. Specialized workflows remain deferred; ccm-extra.send_file is the direct file-transfer exception:
ccm-extra.send_filetransfers an exact file from a selected CCM environment to the GPT client only when a user-facing handoff is actually needed (preview/download/upload to another tool). It returns an MCPresource_link;resources/readserves the exact file bytes from a bounded Controller-side bridge cache that is persisted under ignored.state/file-transfersand survives Controller restarts. By default the bridge has no time-based expiry and is bounded byCCM_FILE_TRANSFER_CACHE_BYTES; an optional positiveCCM_FILE_TRANSFER_TTL_MScan impose a TTL. In ChatGPT, the associated MCP App materializes that resource once into a conversation-scoped ChatGPT file withlibrary:false, persists its stablefileIdin widget state, and requests a fresh temporary download URL on each click. This keeps the attachment usable after the tool turn finishes without saving it to the ChatGPT Library. Do not usesend_filemerely for model-side inspection when the file can be read or viewed locally in CCM; prefer local reading,view_image, command-line inspection, or temporary local previews to avoid unnecessary materialization/approval prompts. The transfer does not use BMG.ccm-extra.quark_uploadsubmits one or more files through that local Quark desktop session and can wait for verified completion.ccm-extra.bilibili_download_dashdownloads signed DASH video/audio URLs obtained from an authenticated browser session and remuxes them withffmpeg -c copy.
Discover deferred specialized workflows with tool_search (for example, quark upload or bilibili) and invoke them through exec. send_file is available directly and is also callable through exec. Long uploads/downloads may return a live process session; continue that session with the top-level write_stdin tool.
The Quark helper reuses only the login state of the local Quark desktop client and does not export account credentials. The Bilibili helper intentionally leaves authenticated playurl discovery to the browser/BMG layer and accepts only the resulting short-lived signed media URLs; it does not export cookies or attempt to bypass account/quality restrictions.
Requirements
CCM requires Node.js 20 or newer and a Rust toolchain with Cargo.
On Windows, building the native execution helpers also requires Visual Studio 2022 Build Tools with the C++ toolchain and the Windows .NET Framework C# compiler. scripts/build-native.mjs locates these automatically when they are installed in standard locations.
Quick start
git clone <your-ccm-repository-url>
cd codex-compatible-mcp
npm ci
npm test
npm startBy default:
MCP endpoint: http://127.0.0.1:18209/ccm/mcp
Health: http://127.0.0.1:18209/ccm/health
WorkerHub: 127.0.0.1:18301npm start builds the native helpers first, starts the Controller, then launches one local Remote Worker unless CCM_SPAWN_LOCAL_WORKER=0.
A standalone Worker can be started with:
npm run workerThe preworker script builds the native helper for the current platform first.
Windows scheduled-task operation
CCM includes public Task Scheduler helpers for both Controller hosts and standalone Remote Workers. They run hidden under the current Windows user, start at logon, use IgnoreNew to avoid duplicate instances, and configure Task Scheduler restart-on-failure behavior. Each supervisor also restarts its own child process if that child exits unexpectedly.
For a Controller machine that should run the Controller, its local Worker, and the OAuth sidecar as one service group:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\install-ccm-autostart.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\ccm-status.ps1Remove it with:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\uninstall-ccm-autostart.ps1For a standalone Windows Remote Worker, first create its ignored runtime config:
Copy-Item .\config\worker.env.example .\config\worker.env
notepad .\config\worker.envSet at least CCM_WORKER_HUB_CONNECT_HOST; normally also give the Worker a stable CCM_ENVIRONMENT_ID. CCM_WORKSPACE is optional legacy/bootstrap configuration and is not a GPT-visible default project. Then install and inspect the Worker task:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\install-ccm-worker-autostart.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\ccm-worker-status.ps1Remove it with:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\uninstall-ccm-worker-autostart.ps1The Remote Worker supervisor reads config/worker.env itself, builds the native helpers on startup, and launches src/worker/agent.mjs. The Worker agent owns connection retry/reconnect behavior, so temporary Controller/network loss does not cause a process restart. config/worker.env, PID files, and supervisor logs are local runtime state and are not committed.
The Worker task installer resolves the current fully qualified Windows identity for both the logon trigger and task principal. This also supports machines whose hostname and local username are identical.
OAuth-protected public endpoint
For ChatGPT/plugin use, expose the OAuth sidecar rather than the raw Controller.
CCM's OAuth gateway follows the same deployment pattern proven in WCM:
OAuth 2.0 authorization code flow with PKCE S256
dynamic public-client registration
Protected Resource Metadata and Authorization Server Metadata
bearer access tokens, refresh-token rotation, and revocation
a local approval secret required at consent time
only the OAuth sidecar is exposed through HTTPS ingress; the Controller and WorkerHub stay private
Prepare a local deployment:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\ccm-enable-oauth.ps1 `
-PublicBaseUrl https://your-machine.your-tailnet.ts.net
npm run publicThe default local ports are:
OAuth sidecar: 127.0.0.1:18208
MCP Controller: 127.0.0.1:18209
WorkerHub: 127.0.0.1:18301For Tailscale Funnel, apply the path routes after the sidecar is healthy:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\configure-ccm-funnel.ps1 -ApplyThe public MCP resource is https://<host>/ccm/mcp. Runtime OAuth configuration is stored in ignored config/ccm.env; OAuth tokens/state and the local approval secret remain under ignored .state/.
Remote Worker example
The WorkerHub has no authentication or transport encryption in v0.1. Keep it on loopback or a trusted/private network.
On the Controller:
$env:CCM_SPAWN_LOCAL_WORKER = "0"
$env:CCM_WORKER_HUB_BIND_HOST = "0.0.0.0"
npm startOn a trusted remote Windows Worker:
$env:CCM_WORKER_HUB_CONNECT_HOST = "<controller-private-ip>"
$env:CCM_WORKER_HUB_PORT = "18301"
$env:CCM_ENVIRONMENT_ID = "build-windows"
$env:CCM_PERMISSION_PROFILE = "workspace-write"
npm run workerThe legacy CCM_WORKER_HUB_HOST variable is accepted as a fallback for both bind and connect configuration, but new deployments should use the explicit bind/connect variables.
Configuration
Variable | Default | Meaning |
|
| MCP HTTP bind host. |
|
| MCP HTTP port. |
|
| MCP endpoint path. |
|
| Controller-side WorkerHub bind host. |
|
| Worker-side Controller address. |
|
| WorkerHub TCP port. |
| enabled | Set to |
| OS hostname | Environment id advertised by a Worker. |
| environment id | Worker connection id. |
| current directory | Legacy/internal Worker bootstrap seed. It may seed Worker-local registry state for compatibility, but it is not a GPT-visible default workspace/project or a new-project parent. |
|
| Root used for automatically created projectless workspaces. |
|
| Worker-local registered and projectless workspace registry. |
|
| Persistent Controller workspace-context registry. |
|
|
|
| 2 MiB | Serialized MCP tool-result limit for ordinary results. |
| 24 MiB | Serialized MCP result limit when returning an embedded file resource. |
| 1 MiB | Maximum raw image size returned by |
| 12 MiB | Maximum raw file size returned by |
| 0 (disabled) | Optional positive TTL for persisted |
| 64 MiB | Maximum total raw bytes retained in the persisted file-transfer bridge cache; oldest entries are evicted first. |
| 1000 ms | Worker reconnect delay. |
Sandbox and platform support
Windows is the current fully supported restricted-execution platform.
read-only and workspace-write command execution use the CCM Windows native sandbox helper. The public environment-discovery surface intentionally does not expose internal bootstrap directories, raw permission profiles, or filesystem permission topology, but list_environments does expose a coarse filesystem_access summary derived from the current effective profile. In the current Windows restricted sandbox, read-only reports host read / no write, workspace-write reports host read / workspace write, and full-access reports host read / host write. Callers should therefore treat workspace boundaries and read boundaries separately: a read outside the selected workspace should be attempted normally when read_scope=host, without requesting escalation merely because the path is outside the workspace. PTY sessions use a Rust ConPTY backend aligned with the useful parts of Codex's current Windows PTY implementation. full-access runs with the Worker's normal host permissions.
Restricted command execution on Linux/macOS is not implemented yet and fails closed rather than silently running unsandboxed. A Linux/macOS Worker therefore currently needs CCM_PERMISSION_PROFILE=full-access for shell execution.
apply_patch enforces its own workspace-write boundary on the Worker, including real-path checks that reject symlink/junction escapes. exec_command can cross the command sandbox only through the one-shot approval flow below.
One-shot sandbox escalation
Restricted Workers support an explicit one-shot escalation flow for exec_command.
When sandbox_permissions=require_escalated is requested on a read-only or workspace-write environment, CCM does not execute the command immediately. It returns an approval_required result containing the selected environment, exact command, execution context, justification, a short-lived approval id, and a SHA-256 hash of the frozen execution intent.
The host should show that request to the user and wait. After the user explicitly approves it, the host calls respond_to_escalation with decision=approve, then retries the exact same exec_command with the returned approval_id. The grant:
is valid for five minutes,
can be consumed only once,
is bound to the environment, command, working directory, shell, and TTY mode,
runs that one command with
full-access,cannot be reused after execution,
does not create a persistent allow rule.
Changing the command or execution context requires a new approval. Denied and expired requests cannot execute.
This approval mechanism controls CCM's sandbox boundary; it does not grant Windows Administrator/UAC privileges. Also, MCP currently provides no cryptographic proof that an approval tool call originated from a human message. CCM enforces the frozen one-shot grant, while the ChatGPT/host interaction layer is responsible for calling respond_to_escalation only after an explicit user decision. A separately authenticated consent UI would be required for CCM itself to independently verify human presence.
Output and transport protection
CCM treats oversized output as a reliability and context-safety problem.
Command capture is bounded, model-facing command output has a token budget, live process reads are incremental, Worker protocol messages have a hard serialized-size ceiling, final MCP tool results have an absolute byte limit, and view_image checks file size before reading/encoding it.
If a hard transport limit would be exceeded, CCM returns or triggers a compact failure instead of attempting to send an oversized response.
MCP result compatibility
CCM returns standard MCP tool results directly. It does not add a custom result envelope such as resultType.
Text tools return normal content: [{ type: "text", ... }] results. view_image
returns normal MCP image content and keeps its file metadata in result _meta,
so multimodal clients can preserve the image block instead of reducing the
result to structured-only output. Other tools may use structuredContent as
the standard optional structured companion to content.
view_image is a common Direct operational tool and is also available through
Code Mode for nested/batched dispatch. exec passes nested MCP image content
through directly while compacting the duplicate structured result, so the
model can receive the image without attaching an MCP Apps output template or
creating a widget card for every image.
Security notes
Both the MCP HTTP server and WorkerHub bind to loopback by default. v0.1 does not provide authentication or TLS for the WorkerHub. Do not expose it directly to an untrusted network.
The Controller routes execution but does not execute repository commands itself. Shell, PTY, sandbox, patch, and image filesystem operations happen inside the selected Remote Worker.
Generated native binaries, Cargo build output, dependency directories, runtime state, logs, and local environment files are excluded from Git.
Development
npm ci
npm run build:native
npm testThe regression suite covers process exit semantics, PTY interaction, sandbox behavior, long-running sessions, oversized MCP results, multi-Worker routing, disconnect cleanup, patch preflight verification, workspace and symlink/junction boundaries, image validation, and MCP end-to-end calls.
See PROJECT.md for architecture decisions, Codex source-alignment notes, and the performance-first roadmap.
License
Original CCM code is licensed under the MIT License. See LICENSE.
Some native PTY source files are copied or derived from OpenAI Codex (Apache-2.0) and WezTerm (MIT). Their notices and applicable license text are preserved in THIRD_PARTY_NOTICES.md and LICENSES.
This server cannot be deployed
Maintenance
Related MCP Connectors
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
Hosted MCP server for task-first delegation to remote workstations and workers.
MCP access to ELSHWORK agents, repositories, isolated runs, discovery and tasks.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.4MIT
- AlicenseNot gradedqualityBmaintenanceA command execution MCP server supporting local execution, sandbox isolation via Docker/OpenSandbox, and SSH remote execution.MIT
- AlicenseNot gradedqualityAmaintenanceA local MCP server that enables Codex and other MCP clients to orchestrate native external coding-agent harnesses through a normalized lifecycle, with guarded execution and deterministic testing.373 PyPIMIT
- AlicenseNot gradedqualityAmaintenanceEnables repository-aware lifecycle management and controlled delegation of coding tasks to trusted worker harnesses via MCP, with execution isolation, recovery, and verified handoff.10 npm8Apache 2.0