CodexBridge
中文版本
CodexBridge wraps the official Codex CLI/SDK and exposes it as an OpenAI-compatible /v1/chat/completions endpoint. It also ships with a tiny CLI so you can talk to Codex locally. Any OpenAI-style client (OpenWebUI, Cherry Studio, curl, etc.) can treat CodexBridge as a drop-in model.
Highlights
- OpenAI-compatible API –
/v1/chat/completions (sync + SSE) plus /v1/models.
- Persistent sessions – Use
session_id / conversation_id / thread_id / user to keep Codex context; omit them for ephemeral runs.
- Multimodal input – Accepts
image_url and local_image blocks (HTTP(S), file://, data: URIs, local paths) and automatically converts them to Codex local_image.
- Structured output – Maps OpenAI
response_format / output_schema to Codex outputSchema so the agent must return JSON that matches your schema.
- Configurable sandbox – Environment variables control filesystem access, working directory, networking, web search, and approval policy.
- Self-hosted storage – Codex sessions live in
~/.codex/sessions; bridge mappings stay in .codex_threads.json.
Requirements
- Node.js 18+
- Codex CLI installed and authenticated on the same machine
- npm (or adapt scripts for pnpm / yarn)
Installation
git clone https://github.com/begonia599/CodexBridge
cd codexbridge
npm install
cp .env.example .env
cp .env .env.local # optional custom config
Edit .env / .env.local before exposing the service (API key, sandbox mode, working directory, etc.).
CLI chat
npm run codex:chat
- Type natural language commands; Codex replies inline.
/reset starts a new Codex thread.
/exit leaves the REPL.
Thread IDs are cached in .codex_threads.json, so you can close the CLI and continue later.
HTTP bridge
npm run codex:server
- Default port:
8080 (PORT overrides)
- Health check:
GET /health
- Session map:
.codex_threads.json (delete to reset bridge-managed sessions)
Basic request
curl http://localhost:8080/v1/chat/completions \
-H "content-type: application/json" \
-H "authorization: Bearer 123321" \
-d '{"model":"gpt-5.5:medium","session_id":"demo","messages":[{"role":"user","content":"ls"}]}'
Session IDs & persistence
- In production/front-end setups enable
CODEX_REQUIRE_SESSION_ID=true so every request must include a session identifier.
- IDs can be supplied in the JSON body (
session_id / conversation_id / thread_id / user) or via headers (x-session-id, session-id, x-conversation-id, x-thread-id, x-user-id).
- IDs must be non-empty strings (UUID, user ID, chat ID, etc.). Avoid numeric-only or nested objects.
- If all identifiers are omitted and
CODEX_REQUIRE_SESSION_ID is false, CodexBridge flattens the entire messages history into [ROLE] blocks and sends it as a one-off prompt.
Streaming
curl -N http://localhost:8080/v1/chat/completions \
-H "content-type: application/json" \
-H "authorization: Bearer 123321" \
-d '{"model":"gpt-5.5:high","session_id":"stream","stream":true,"messages":[{"role":"user","content":"Explain how to run npm init step by step."}]}'
Response is SSE (data: {...}) ending with data: [DONE].
The bridge understands OpenAI-style content arrays. Examples:
{"type":"image_url","image_url":{"url":"https://example.com/demo.png"}}
{"type":"local_image","path":"./images/demo.png"}
Remote URLs and data URIs are downloaded to a temp folder, converted to Codex local_image, then cleaned up after the turn.
Structured JSON output
CodexBridge forwards OpenAI response_format to Codex outputSchema:
{
"model": "gpt-5.5",
"session_id": "lint",
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "lint_report",
"schema": {
"type": "object",
"properties": {
"summary": { "type": "string" },
"status": { "type": "string", "enum": ["ok", "action_required"] }
},
"required": ["summary", "status"],
"additionalProperties": false
}
}
},
"messages": [
{ "role": "user", "content": "Check src/ for lint problems and return JSON following the schema." }
]
}
type: "json_schema" must include a schema. Missing or invalid schemas trigger HTTP 400.
Networking & search
CODEX_NETWORK_ACCESS=true allows Codex to run networked commands (curl, git clone, API calls).
CODEX_WEB_SEARCH=true lets Codex use its built-in web search tool.
Both default to false.
Source deployment
cp .env.example .env
npm run codex:server
Keep the process running via pm2, systemd, forever, or any other supervisor. If you need HTTPS, front the service with Nginx/Caddy pointing to localhost:8080. You can run npm run codex:chat alongside the server for CLI interaction.
Dashboard prototype
Visit http://<host>:8080/dashboard to see the placeholder dashboard (served from public/dashboard.html). The page currently loads mock content; once token parsing is wired up you can populate it with real account metadata and session stats.
One-command setup for Linux
curl -fsSL https://raw.githubusercontent.com/begonia599/CodexBridge/master/scripts/install.sh | bash
The script:
- Installs git, Node.js, Docker, and Docker Compose if missing.
- Clones/pulls the repo to
~/codexbridge (override via CODEXBRIDGE_DIR env var).
- Copies
.env.example → .env (edit afterward).
- Runs
docker compose up -d --build.
Requires sudo privileges to install system packages and Docker.
Docker
Docker Compose
docker compose up -d
docker compose logs -f codexbridge
Compose mounts Codex data under ./codex-data (auto-created). Delete that directory to reset Codex threads. Use docker-compose instead if you rely on the legacy command.
Docker CLI
docker build -t codexbridge .
docker run --rm -p 8080:8080 \
--env-file .env \
-v "%cd%":/workspace \
-v "%LOCALAPPDATA%\Codex":/root/.codex \
-w /workspace \
codexbridge
Environment variables
| Variable |
Default |
Description |
PORT |
8080 |
HTTP port |
CODEX_MODEL |
gpt-5.5 |
Default model |
CODEX_REASONING |
medium |
Default reasoning effort (minimal / low / medium / high / xhigh) |
CODEX_BRIDGE_API_KEY |
123321 |
API key for Authorization: Bearer / x-api-key |
CODEX_SKIP_GIT_CHECK |
true |
Skip Codex “trusted Git repo” requirement |
CODEX_SANDBOX_MODE |
read-only |
read-only / workspace-write / danger-full-access |
CODEX_WORKDIR |
empty |
Force Codex threads to run inside this directory |
CODEX_NETWORK_ACCESS |
false |
Allow networked commands |
CODEX_WEB_SEARCH |
false |
Allow built-in web search |
CODEX_APPROVAL_POLICY |
never |
never / on-request / on-failure / untrusted |
CODEX_LOG_REQUESTS |
false |
Log incoming payloads |
CODEX_REQUIRE_SESSION_ID |
false |
Require session identifiers (true recommended for production) |
CODEX_JSON_LIMIT |
10mb |
express.json() body limit |
CODEX_DYNAMIC_MODELS |
true |
Fetch the live model list from the Codex backend for /v1/models; falls back to a static list if unreachable |
CODEX_MODELS_TTL_MS |
300000 |
Cache TTL (ms) for the dynamic model list |
CODEX_MODELS_ENDPOINT |
Codex backend |
Override the model-listing endpoint URL |
CODEX_CLIENT_VERSION |
SDK version |
client_version sent to the model-listing endpoint |
Troubleshooting
- 413 PayloadTooLargeError – Increase
CODEX_JSON_LIMIT when sending base64 images or large bodies.
- “Invalid or missing API key” – Provide the correct
Authorization: Bearer <CODEX_BRIDGE_API_KEY> or x-api-key.
- Codex refuses to run (Git check) – Disable
CODEX_SKIP_GIT_CHECK only if the working directory is a trusted repo.
- Need a clean slate – Stop the server and delete
.codex_threads.json and/or ~/.codex/sessions.
License
Non-commercial use only. See LICENSE for the full terms. Commercial usage requires prior written permission from begonia.
Feel free to reach out if you run into problems, want new features, or plan to fork and rework CodexBridge. Contributions and derivative projects are welcome.
评论