Codex Gateway
Experimental: this is an early local compatibility gateway for Codex app-server. Treat the HTTP contract and safety model as unstable, review changes carefully before relying on it, and do not expose it outside loopback.
Local FastAPI adapter that lets the official OpenAI Python SDK talk to codex app-server over stdio:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:8000/v1",
api_key="<local-gateway-token>",
)
print(client.models.list())
print(client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "Say pong"}],
))
Run
Initialize once, then start the gateway:
uvx codex-gateway init
uvx codex-gateway
codex-gateway init writes ~/.config/codex-gateway/config.json with a generated local bearer token and 0600 permissions, then prints the matching OpenAI SDK setup. The server reads that config automatically on future runs.
To reprint the SDK setup later:
uvx codex-gateway show
The OpenAI SDK setup is three lines:
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="<local-gateway-token>")
For scripts that only need a token value, use codex-gateway token. codex-gateway env still prints shell exports for scripted use, but interactive setup should prefer init and show.
For local development:
uv sync --group dev
uv run codex-gateway --port 8000
The api_key is a local gateway bearer token. It is not an OpenAI API key and is never proxied to Codex.
If neither config nor CODEX_GATEWAY_TOKEN is set, the gateway prints a generated local token at startup.
Implemented
GET /v1/modelsPOST /v1/chat/completionsstream=TrueSSE chunks compatible withopenai.OpenAI(...).chat.completions.create(..., stream=True)- Multi-turn text chat history via Codex
thread/inject_items - OpenAI
image_urlcontent parts in user messages, mapped to Codex image inputs/history. Image data URLs are materialized as temporary local files for the live Codex turn and cleaned up afterward. - Local bearer-token authentication
- Codex app-server stdio transport
Safety Defaults
- Binds to
127.0.0.1by default. - Starts ephemeral Codex threads with
sandbox="read-only",approvalPolicy="never", no environments, and no dynamic tools. - Unsubscribes from each per-request thread after the API response finishes.
- Accepts only
http://,https://, anddata:image/...image URLs; local file URLs are rejected. - Denies app-server requests for command execution, patch approval, file-change approval, MCP elicitations, and dynamic tool calls.
- Does not expose app-server filesystem, shell, config, auth, or account endpoints through the OpenAI-compatible HTTP API.
- Does not print, persist, proxy, or expose Codex auth credentials.
Architecture
chat_contract.pyowns the OpenAI-facing chat subset: validation, text/image message conversion, history item construction, completion payloads, streaming chunks, SSE framing, and OpenAI-style errors._app_server_stdio_session.pyowns the Codex app-server stdio transport: JSON-RPC request correlation, notification fan-out, stderr redaction, shutdown, and denial responses for privileged app-server requests._codex_turn_lifecycle.pyowns Codex turn behavior: starting turns, collecting final assistant output, streaming assistant deltas, draining idle notifications, and mapping token usage.codex_client.pyis the high-level client used by FastAPI. It initializes the app-server session, lists models, starts ephemeral read-only Codex threads, injects prior text/image history, materializes image data URLs for live turns, delegates turn execution, and unsubscribes when finished.
Unsupported OpenAI Features
This MVP returns a 400 instead of pretending to support features it cannot honor, including tools/functions, tool choice, response formats, JSON/schema-constrained output, audio, n > 1, logprobs, sampling controls, stop sequences, token limits, metadata storage, and non-chat APIs such as /v1/responses, /v1/embeddings, and legacy completions.
Tests
uv sync --group dev
uv run --group dev pytest -m "not integration" tests
Live contract tests are opt-in because they start the FastAPI gateway, launch codex app-server over stdio, and require working Codex auth:
CODEX_GATEWAY_RUN_CONTRACT_TESTS=1 uv run --group dev pytest -m integration tests/test_contract.py
The contract tests instantiate the official OpenAI SDK with base_url=.../v1, call /v1/models, call non-streaming chat completions including a multi-turn message chain and image content part, call streaming SSE chat completions, and verify missing/invalid local bearer tokens are rejected.
The coverage gate is configured at 95% in pyproject.toml.
Linting
uv run --group dev ruff check src tests
uv run --group dev ruff format --check src tests
uv run --group dev pre-commit install
uv run --group dev pre-commit run --all-files
The generated Codex app-server JSON Schema and TypeScript protocol references used for this implementation are in generated/.
Metadata
Release files for codex-gateway 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| codex_gateway-0.1.2.tar.gz | 28.4 kB | Without provenance | Details for codex_gateway-0.1.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| codex_gateway-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for codex_gateway-0.1.2-py3-none-any.whl |
Total release size: 47.3 kB
Release files / codex_gateway-0.1.2.tar.gz
| Download URL | codex_gateway-0.1.2.tar.gz |
|---|---|
| Size | 28.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f04b3e6aceab26601b2cc3402cec0b23f7b9e1aa8239243ad1b8ee1bc62bb87b
|
|
BLAKE2b-256 checksum How to use checksums |
06dc2048f21fb453216b096d8db6a998aa3f79ea3f560ef186ab902b0cb47598
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / codex_gateway-0.1.2-py3-none-any.whl
| Download URL | codex_gateway-0.1.2-py3-none-any.whl |
|---|---|
| Size | 18.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
59559b0c4c73cb922e831d4097b5e238dff7d1d5bafa5a9af9826638e130d9c4
|
|
BLAKE2b-256 checksum How to use checksums |
5599ad483eaf120162e8cb082b54dde060939a985782a7b3ea6c2462518f2a65
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for codex-gateway 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.