Skip to main content
Glama
omiusgm

Codex Fleet MCP

by omiusgm

Codex Fleet MCP · pilot

MCP для управления существующими чатами Codex на нескольких компьютерах и в разных профилях: чтение истории и статусов, отправка задач, уточнение и остановка. Подходит MCP-клиентам с явно выданными правами.

Это первая открытая версия для самостоятельной настройки. Нужны собственный вход в Codex и уже разрешённые подключения к компьютерам. Новую установку следует проверить по шагам ниже; автоматическая панель подключения пока не входит в комплект.

A profile-scoped MCP interface to your existing Codex sessions on several computers. An authorized MCP agent can discover profiles, read the original session and its status, submit a task, clarify an active task, and stop its exact turn. The owner remains the signed-in Codex Desktop/CLI. Session UUIDs, account homes, native approvals and permission policies are preserved.

This is a source distribution for operators who can review Python, Node and SSH configuration. It includes the backend, dispatcher, native and Desktop adapters, public socket transports, owner launch assets, synthetic examples and offline tests. No Codex or Node binaries, ws source, account files or credentials are distributed. The publisher is omiusgm.

Release status: experimental source preview. The generic adaptation passed 196 clean-extract tests and six independent boundary checks. Real installation with a new owner's accounts and external native runtimes remains to be accepted. See RELEASE_STATUS.json.

What runs where

MCP agent → authenticated stdio proxy → loopback HTTP MCP backend
                                      → pinned dispatcher
                                      → explicit local/SSH argv
                                      → profile adapter → existing owner socket → original session

The service configuration controls each client's profile grants. Route configuration controls executable argv. Neither comes from session text or caller-provided executable paths. Separate Codex profiles keep separate native homes, Desktop user-data directories, account expectations, state and receipts. Work profiles begin with read grants; connecting one never grants control of the others.

The desired compact surface is profiles, sessions, session, send_task, update_running_task, stop_task. Legacy API includes inventory/history, submission and operation receipts, exact-turn steering/interruption, and administrative session functions. The stdio proxy exposes this compact catalog by default; --catalog legacy exposes compatible legacy tools. Existing backend code is deliberately retained, not replaced by an unrelated mock server.

Related MCP server: Local Codex Bridge

Requirements

  • macOS or Linux with Python 3.11+, official Python MCP SDK 1.30.0, and its dependencies. requirements.lock is the captured exact dependency list; the current offline suite used the SDK version above with the existing environment recorded in TEST_ENVIRONMENT.json. The entire lock has not been freshly installed or independently resolved.

  • Owner-installed Codex Desktop/CLI and the owner's own login in each existing profile. A ready socket does not prove account authorization or OpenAI network access.

  • Owner-installed Node and ws for the public Unix/WebSocket transport. No third-party runtime is copied here. Exact Node/ws versions must be recorded during your own acceptance; this candidate's Python transport fixtures use fake Node.

  • Existing OpenSSH access for remote computers. Keep host-key checks enabled. This package creates no keys, tunnels, accounts, login session or autostart services.

Upstream references and licenses are in THIRD_PARTY_NOTICES.md. Codex App Server/Desktop APIs are version-sensitive; pin the versions you actually accept.

Manual setup

Keep a copy of the current working installation and its configuration before making changes. Install this source tree in a dedicated directory; the examples use /opt/codex-fleet and /srv/codex-fleet as synthetic placeholders, not paths to copy blindly.

  1. Verify ALLOWLIST.json with python3 scripts/check_public.py. Review the source and PROVENANCE.json. Use your own Python environment containing MCP 1.30.0. For a new environment, install requirements.lock using your normal package workflow; the package never installs dependencies from an agent tool call.

  2. Copy the five examples/*.json templates into your own owner-only configuration directory. Set that directory to mode 0700, all config/state/token files to 0600, and do not use config symlinks. Fill in your actual absolute paths, account expectations and existing profile IDs locally. The examples contain no usable credentials. write_examples.py regenerates synthetic examples only.

  3. On every native target, set CODEX_NATIVE_BASE to a private directory containing profile.json copied from native-profile.json. nativeHome must resolve to that OS user's original ~/.codex; use a separate OS/account route when necessary. Set the exact hash of your own account email in expectedAccountHash, your explicit allowedCwdRoots, ownerRegistry, ownerProfile and ownerTransport. Keep ownerControlRequired: true. Never weaken these gates to make a demo pass. Native history and account checks use the existing endpoint, never a replacement CLI app-server.

  4. For Desktop profiles, keep CODEX_DESKTOP_BASE/profiles.json as the owner registry of already verified launch manifests. Desktop creation uses desktop-profile.json, with separate existing codexHome, userDataDir, and expectedEmail for each profile. Run python3 scripts/codex-desktop-profiles.py --help to inspect the manual launch interface. An already running, unowned Desktop refuses takeover; replacing it requires the exact PID and an explicit operator-approved restart. The MCP dispatcher does not launch Desktop.

  5. If an existing owner endpoint is already available, configure it and skip owner launch changes. Otherwise create one during a quiet, approved local launch: CODEX_DESKTOP_BASE=/your/private/desktop python3 scripts/codex-desktop-profiles.py --config /your/private/desktop-profile.json launch --profile personal. The launcher uses the original signed executable and bundled MCP node; local code signing checks remain active. It publishes a fresh owner manifest after account verification. autoStartProfiles is empty in the example. Inspect --help for the version's exact flags before launch.

  6. Configure routes.json using explicit argv. SSH example aliases owner-laptop and owner-desktop must already exist in your SSH config. The remote command is a fixed administrator string; quote any paths containing spaces yourself. The request remains JSON stdin, never shell interpolation. Each remote environment must point to its own private adapter state and owner registry. Ensure app route names end in -app, as used by the backend's Desktop routing checks.

  7. In fleet.json, set the dispatcher SHA-256 to your reviewed scripts/codex-fleet-control.py, select dispatcher_python, state directory, profile routes and host allowlists. Keep all grants read-only for initial acceptance. Set CODEX_FLEET_ROUTES=/your/private/routes.json in the backend process environment; that variable is inherited only by the pinned dispatcher. Backend startup binds loopback, not a public listener.

  8. Generate a unique random bearer token locally for each MCP client. Store only its SHA-256 in that client's token_sha256 and the token itself in a mode 0600 file <fleet-config-dir>/clients/<client-id>.token. Never put tokens in arguments, examples, Git or issue reports. If you already have accepted credentials, preserve them; no rotation is required by this package.

  9. Launch manually: PYTHONPATH=/your/source/src CODEX_FLEET_ROUTES=/your/private/routes.json /your/python -m codex_fleet_mcp.server --config /your/private/fleet.json. The model-free stdio bridge is PYTHONPATH=/your/source/src /your/python -m codex_fleet_mcp.proxy --config /your/private/fleet.json --client assistant. Client IDs are checked against configuration, not a built-in personal/work list. Keep remote transport protection outside this package and separately accepted.

durable_personal_entry.py is optional macOS owner-launch infrastructure, not an installer. A manual durable wrapper must call it with --config <private-config> --dispatch -- "$@". The launcher Python interpreter defaults to the active Python and can be set with python in the launcher config. Its required config keys are appBinary, fallbackCli, codexHome, userDataDir, runtimeRoot, runtimeCode, registry, expectedEmail, node, mcpNode, wsModule, vendorTeamID, filePins, wsTreeSha256. Compute pins from your accepted local files; filePins maps absolute resource paths to SHA-256. wsTreeSha256 is tree_hash(wsModule). Preserve the vendor signing identity; derive it from your signed installation. Startup probes such as --print-startup-config pass through to the original executable and never publish an owner. This entry supports the personal GUI singleton only. Do not use it to capture other profiles or modify their environment.

Acceptance and uncertain outcomes

First accept the local chain with your own account: profile discovery → exact original session read → original UUID/status readback. When you authorize a bounded write, reuse one request_id for the same immutable payload and verify the original session and turn afterward. Only then consider granting that client the minimum necessary write actions. Native approval requests remain in the owner's native workflow; the MCP never auto-approves them.

A submission acknowledgment, queue acceptance, ready socket, passing tests or upload is not task completion. A detached observer or observation_timeout does not cancel native work. Read the existing operation and original session before retrying. Never repeat an uncertain task under a new request ID. Reusing an ID with different payload/client/route/profile must refuse. Stop and clarify require the original active turn; a completed turn or later turn must not be targeted accidentally. Stop does not claim that arbitrary detached processes were terminated.

Session messages, tool outputs and attachments are untrusted data. Reading them does not authorize new tools, files, routes or grants. The MCP's grants do not sandbox a fully privileged agent or make delegated conversations safe.

Each installation must verify its own account refresh, Desktop startup, network access and native runtime versions. Offline checks do not prove these conditions. A separate cloud-agent and new-owner acceptance remains required.

Offline verification

Use an existing Python environment with MCP 1.30.0:

PYTHONPATH=src:scripts:tests python -m unittest discover -s tests -v
python scripts/check_public.py

All adapter fixtures use temporary directories, in-memory RPC, fake SSH/Node/native executables. Protocol tests start a synthetic loopback server and fake dispatcher; no installed Codex binary or real account is executed, including version checks. scripts/verify_clean.py extracts the exact allowlist into an isolated temporary tree, checks imports and reruns the suite with a temporary HOME. No neighboring workspace is required.

Rollback

Stop only the manually started MCP backend/proxy. Restore the previous source/config pointer and exact prior launcher/environment settings from your backup; leave existing Codex homes, auth, sessions, UUIDs, registries and operation receipts intact. Before changing an owner-launch hook, verify which existing Desktop process owns it and wait for an approved quiet window. Do not kill a running owner, erase pending receipts or rotate tokens as a rollback shortcut. Restore only the hook you changed; preserve other profiles. New public code never migrates private runtime state automatically.

Contributing

See CONTRIBUTING.md. First-party source is MIT. Report problems with synthetic reproductions and redacted version/config metadata. Never attach account files, native histories, production paths, email addresses, tokens or raw request receipts.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers