Skip to content

How It Works

hypnguyen1209 edited this page Aug 25, 2026 · 1 revision

How It Works

This page traces Codex Free end-to-end: how a request from ChatGPT reaches a tool on your machine, and everything the server does around each call. If you only read one "under the hood" page, read this one.


The picture

flowchart LR
    ChatGPT["ChatGPT Web Pro"]
    Tunnel["OpenAI Secure MCP Tunnel"]
    Client["Official OpenAI\ntunnel-client-runtime\n(supervised)"]
    Server["Codex Free\nMCP Bridge\n127.0.0.1:3000"]
    Tools["Tool Registry"]
    WorkDir[("Active project root")]
    State[("~/.codex-free\nplan + notes")]
    Upstream[("Bridged MCP servers")]

    ChatGPT <-->|"connector calls"| Tunnel
    Client <-->|"outbound HTTPS"| Tunnel
    Client <-->|"loopback HTTP /mcp\n+ per-process bearer"| Server
    Server --> Tools
    Tools --> WorkDir
    Tools --> State
    Tools -.->|"if configured"| Upstream
Loading

The key property: traffic is outbound-only. Codex Free listens on 127.0.0.1. The tunnel client dials out to OpenAI over HTTPS and forwards tunnel traffic back to the authenticated loopback endpoint. No inbound port is opened, and there's no public URL.


1. Startup

When you run codex-free --work-dir …, before it accepts any traffic the server:

  1. Reads config. Loads codex.config.json (or the built-in defaults if missing) and applies CLI-flag overrides. The startup banner reports the effective settings.
  2. Resolves the mode. Single-project (default), multi-project (--multi-project), and native-tunnel vs legacy/external — see below.
  3. Discovers MCP upstreams. Reads $CODEX_HOME/config.toml (read-only) for [mcp_servers.*], optionally enriches via codex mcp list/get --json, then applies your mcpServers overlays. Each upstream is connected and its tools listed. The banner names every one — including failures. See Bridging MCP Servers.
  4. Installs/verifies the tunnel runtime (native mode only). Downloads the pinned official client if absent, checks it against an embedded SHA-256, and starts it. The server reports ready only after /readyz passes and a control-plane poll succeeds.
  5. Sweeps stale worktrees (multi-project). Removes old, clean, unreferenced managed worktrees beyond keepCount. See Worktree Isolation.

2. A conversation connects (the initialize handshake)

When ChatGPT (or any MCP client) opens a session, the server returns an initialize response. Its instructions field is where Codex Free layers Codex's operating brief, in Codex's own order, each part outranking the one above it:

  1. The agent brief — how to behave (edit carefully, apply_patch over rewrites, respect the dirty-worktree rules, keep a plan, report concisely). Ported from Codex's own prompt.
  2. The environment — OS, shell, work directory, command policy.
  3. Saved state — the plan and notes from earlier work, if any. See Context and Memory.
  4. The skill catalogue — what this project and user know how to do, if any skills are installed. See AGENTS and Skills.
  5. AGENTS.md — the project speaking for itself, behind a --- project-doc --- marker.

Because instructions is rebuilt per session, editing AGENTS.md or adding a skill takes effect on the next connection — no restart needed.

Important: no client is obliged to show instructions to its model, and ChatGPT Web isn't reliable about it. That's why get_agent_brief returns the identical string on demand. Opening a chat with "Call get_agent_brief and follow it for the rest of this chat" is the reliable way to onboard. See Connecting to ChatGPT.

3. A tool call arrives

For each tool call, the server:

  1. Identifies the owner. For ChatGPT calls carrying _meta["openai/session"], work is scoped to that hashed conversation identity — so bindings, memory, review checkpoints, and exec_command sessions survive the connector swapping transports mid-chat. Clients without that metadata fall back to a per-transport-session scope.
  2. Resolves the active project root. --work-dir in single-project mode; the conversation's selected root in multi-project mode. Until a root is bound in multi-project mode, project-scoped tools are unavailable and say why.
  3. Guards the path. Every filesystem tool resolves paths through a guard that rejects anything outside the active project root — after canonicalization, so .. and symlinks can't escape.
  4. Enforces policy. run_command checks allowedCommands; exec_command checks that plus exec.extraAllowedCommands, at every command position in the string. Output is bounded per the output block.
  5. Snapshots for review (first project-scoped call). Captures the checkout as the agent first sees it, before any write — the project-open baseline. See Review Checkpoints.
  6. Runs the tool, bounds the result, and appends a truncation notice when it hit a cap.
  7. Records an audit event if --audit is set — hashes, timings, sizes, redacted argument shape. See Audit Logging.

4. Bounded output

Any tool that could return unbounded text stops at a budget and says so on its last line, naming the argument that continues:

(showing lines 1-1000 of 4820 — call again with offset=1000 for the rest)

That last line matters as much as the cap — silent truncation reads as "that was the whole file", which is worse than no cap. read_file has a byte ceiling as well as a line one (a minified bundle is one line, megabytes long). exec_command and grep are bounded too, ported that way from Codex.

5. State that outlives the chat

ChatGPT's window is smaller than most real tasks, and a new chat starts blank. Codex Free keeps what's expensive to rediscover:

  • remember writes one keyed note; recall returns the notes plus the current plan; update_plan persists the plan itself.
  • State lives in ~/.codex-free/projects/<name>-<hash>/memory.json, keyed by the absolute project root — never inside your repo.
  • In single-project mode, the saved plan and notes are already in front of a new conversation via instructions. In multi-project mode they arrive from get_agent_brief after the project is selected.

Full detail in Context and Memory.


The three connection modes

Mode Binds Endpoint Auth When
Native OpenAI tunnel 127.0.0.1 only routed via tunnel random per-process bearer (loopback hop); /readyz gate Recommended. No public URL, no inbound port.
Legacy / external 0.0.0.0:3000 /mcp, /health you provide it (proxy, --api-key) Local clients, or an explicitly authenticated reverse proxy/tunnel.
Multi-project (either of the above) same per-conversation project binding One server, many repos beneath an access root.

Native and multi-project compose — you can run --multi-project behind the native tunnel. What multi-project changes is project selection, not the transport. See Multi-Project Mode and Connecting to ChatGPT.


A full example, start to finish

  1. You run codex-free --work-dir ~/code/myapp with an openaiTunnel block configured.
  2. Codex Free verifies/starts the tunnel client, connects any bridged MCP servers, and reports ready.
  3. In ChatGPT (Developer mode), you enable the connector for that tunnel and open a chat: "Call get_agent_brief and follow it for the rest of this chat. Task: fix the failing test in auth.rs."
  4. ChatGPT calls get_agent_brief, receives the environment + AGENTS.md + any saved plan, and starts working the way Codex would.
  5. It calls grep, read_file, apply_patch, exec_command — all pinned to ~/code/myapp, all bounded, all optionally audited.
  6. It calls show_changes to show you exactly what it touched, and git_commit / git_push when you approve.
  7. You close the chat. The plan and notes persist. A new chat tomorrow picks them up with one recall.

See also

Clone this wiki locally