Skip to content

Build1 publisher3 min readPublished

A local proxy convinces the ChatGPT desktop app it is still talking to OpenAI

One MIT-licensed proxy on localhost is enough to serve OpenAI's own desktop client from self-hosted models. The models that fail there fail on Codex's tool-call format. One of three tested got lost.

The Engineer · Build desk

Photograph accompanying A local proxy convinces the ChatGPT desktop app it is still talking to OpenAI
Photo: xda-developers.com

What happened

  • opencodex injects openai_base_url and experimental_realtime_ws_base_url pointing at http://127.0.0.1:10100/v1 into ~/.codex/config.toml, so the client's model lists and its messages reach the proxy first.
  • An XDA writer reported his ChatGPT Desktop app believed it was talking to OpenAI servers while it was served by MiniMax M3, OpenCode subscription models, and locally run Qwen 3.8 27B and GLM-5.3-Flash.
  • OpenAI folded the Codex Desktop app into the ChatGPT app in early 2026, leaving one switch between chat and coding mode and a model picker confined to OpenAI's own models.
  • The tool is MIT-licensed and runs as a local proxy impersonating the OpenAI API, so neither the desktop app nor the Codex binary is forked or patched.
  • Defaults reach Ollama, vLLM and LM Studio on standard local ports, and the README lists more than 40 built-in providers plus any OpenAI-compatible or Anthropic Messages endpoint.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint Model choice for this client is bounded by Codex's tool-calling surface, so a shortlist has to be tested against freeform apply_patch and shell calls before throughput or price is worth discussing.
  • exposure Steering new sessions to whichever pooled ChatGPT or Codex account still has quota leaves the account holder answering for how the subscription was used.
  • precedent Any desktop client that reads its base URL from an environment variable is reroutable the same way. Whoever ships the next first-party app has to decide whether that knob stays.
  • cost Adoption means running a long-lived local service on Node 18 or later with a Bun runtime the installer drags in, and keeping that service current becomes the operator's job.

Ask the desktop app for its model list and the proxy fans out. It queries every provider in its config, merges the replies, and returns a single list. In the XDA writer's setup the locally served GLM-5.3-Flash turned up in the Codex picker as `vllm/glm-5.3-flash`, sitting next to models from his OpenCode subscription [8]. Routing happens after selection: once a message is sent, the proxy decides where it goes [9].

Redirecting Codex is cheap because Codex speaks the OpenAI Responses API and takes its base URL from an environment variable [5]. Translating between that wire format and whatever the target model expects is harder. Codex also has its own tool-calling surface: freeform `apply_patch`, shell access, MCP namespaces, and `tool_search` [25]. A model trained against a different convention emits the wrong shape. According to the dev.to writeup relaying the XDA test, MiniMax M3 got lost, while GLM-5.3-Flash and Qwen 3.8 27B worked normally [26]. Two of the three models named as serving the app worked [29]. For the ratio to mean anything in your setup you would need his runtimes, his prompts, and the Codex build he was on.

The diagnostic he offers is worth copying: if a model works in Claude Code or OpenCode but fails in Codex, check whether it is calling tools correctly before looking anywhere else [27].

The stated reason for a proxy instead of a fork is maintenance. Format translation sits outside the client, so it survives Codex updates [10]. A fork has to be re-patched on every release, and one proxy covers the CLI and the desktop app at the same time [11]. The XDA author says he has taken several Codex updates since and it still works [12].

Setup is `npm install -g @bitkyc08/opencodex` on Node 18 or later, then `ocx start`, which brings up the proxy and a dashboard on port 10100 [13]. `ocx init` asks which provider you want and offers to write `config.toml` for you, `ocx service` runs it in the background, and the command set is documented at opencodex.me [15][16]. The same author ran models on several machines across a private network behind one instance [20]. The dashboard reports per-call token counts and an estimated cost per model [22].

All of the hands-on detail traces to that one tester. The dev.to post carrying it is dated 19 September 2026, credited to Nokka, and says the draft came from the deepseek-v4.1-flash model on ollama-cloud through Nous Research's Hermes Agent before Nokka checked and edited it [28]. It counts four pitfalls drawn from the XDA article and the official README [24], and the second of them, on web search, breaks off mid-sentence in the text as published [30].

What to watch

  • Whether the proxy still attaches after a Codex release that changes the Responses API surface or the config key names.
  • Whether OpenAI's client starts validating the endpoint it was pointed at, or its terms address pooling several ChatGPT accounts behind one proxy.
  • An independent test reporting tool-call pass rates across more than three models under Codex.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories