Codex CLI — консольный агент OpenAI для работы с кодом — в версии 0.154 требует явной настройки провайдера модели через файл ~/.codex/config.toml. Переменная OPENAI_BASE_URL, к которой привыкли пользователи OpenAI SDK, полностью игнорируется: Codex всё равно стучится на api.openai.com и возвращает 401 Unauthorized. Единственный способ перенаправить запросы на сторонний сервер — описать секцию model_providers.
Минимальный рабочий конфиг выглядит так: в секции [model_providers.myproxy] указываются name, base_url с суффиксом /v1, env_key с именем переменной окружения (не сам ключ) и wire_api = "responses". В основной части файла задаются model — идентификатор модели ровно так, как его понимает endpoint, model_provider — имя секции, и model_reasoning_effort — сколько модель думает перед ответом. Без строки model_provider Codex пойдёт в api.openai.com, даже если секция описана. Проверка подключения: codex exec "Ответь одним словом: работает" — в ответе должно быть одно слово и строка tokens used.
| Поле конфига | Назначение | Типичная ошибка |
|---|---|---|
| model | ID модели, как его понимает endpoint | Неизвестный ID — Codex подставляет fallback-метадату |
| model_provider | Имя секции провайдера | Без строки Codex идёт в api.openai.com |
| base_url | Адрес endpoint с /v1 на конце | Без /v1 Codex стучится в /responses и получает HTML |
| env_key | Имя переменной окружения с ключом | Переменная не экспортирована — ошибка Missing environment variable |
| wire_api | Протокол обмена | wire_api = "chat" больше не поддерживается |
Девять способов сломать конфиг. Первый: попытка использовать OPENAI_BASE_URL — переменная проигнорирована, в ошибке виден url api.openai.com. Второй: wire_api = "chat" — Codex не запустится вообще, endpoint обязан реализовывать /responses, что отсекает старые прокси и самописные шлюзы. Третий: опечатка в wire_api — сообщение об ошибке будет невнятным, как и за любую опечатку в enum-поле. Четвёртый: base_url без /v1 — Codex дописывает /responses и получает HTML главной страницы, пять попыток переподключения и мусор в терминале. Пятый: переменная с ключом не экспортирована — env_key читает окружение процесса, а не файлы.env. Шестой: модель, о которой Codex не знает — срабатывает fallback-метадата, запрос всё равно уйдёт на endpoint, но с запасными параметрами. Седьмой: supports_websockets = true на прокси без WebSocket — каждый ход начинается с неудачного рукопожатия 426 Upgrade Required, после чего Codex молча падает на HTTPS. Восьмой: requires_openai_auth = true — в 0.154 с заданным env_key строка ничего не меняет, но вводит в заблуждение. Девятый: experimental_bearer_token — ключ лежит открытым текстом в конфиге, который легко скопировать на новую машину или случайно закоммитить вместе с dotfiles.
Для подключения к стороннему endpoint нужна секция [model_providers.<имя>] с полями base_url, env_key и wire_api.
Практический вывод: перед правкой конфига проверьте, что ваш прокси отдаёт /v1/responses, а не только /chat/completions. Ключ передавайте через env_key — тот же результат, что и experimental_bearer_token, но без риска утечки. Если endpoint не заявляет WebSocket явно, не включайте supports_websockets. Диагностика большинства ошибок сводится к одному: смотреть на url в конце сообщения об ошибке — он показывает, куда именно ушёл запрос.
Контекст: Codex CLI — не единственный агент с собственным форматом конфига. Claude Code, например, использует переменные окружения для указания endpoint, а Codex выбрал TOML-файл с десятком полей. Такой подход даёт больше контроля, но и больше способов ошибиться: половина полей ломает подключение молча, без внятного сообщения. Для команд, которые разворачивают Codex за корпоративным прокси или в изолированной среде, это означает необходимость проверять конфиг на каждом обновлении версии — формат и допустимые значения полей меняются.

