This commit is contained in:
viyatb-oai
2025-12-18 00:53:18 -08:00
1483 changed files with 138470 additions and 44142 deletions
+6 -6
View File
@@ -2,11 +2,11 @@
If you already lean on Codex every day and just need a little more control, this page collects the knobs you are most likely to reach for: tweak defaults in [Config](./config.md), add extra tools through [Model Context Protocol support](#model-context-protocol), and script full runs with [`codex exec`](./exec.md). Jump to the section you need and keep building.
## Config quickstart {#config-quickstart}
## Config quickstart
Most day-to-day tuning lives in `config.toml`: set approval + sandbox presets, pin model defaults, and add MCP server launchers. The [Config guide](./config.md) walks through every option and provides copy-paste examples for common setups.
## Tracing / verbose logging {#tracing-verbose-logging}
## Tracing / verbose logging
Because Codex is written in Rust, it honors the `RUST_LOG` environment variable to configure its logging behavior.
@@ -20,15 +20,15 @@ By comparison, the non-interactive mode (`codex exec`) defaults to `RUST_LOG=err
See the Rust documentation on [`RUST_LOG`](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) for more information on the configuration options.
## Model Context Protocol (MCP) {#model-context-protocol}
## Model Context Protocol (MCP)
The Codex CLI and IDE extension is a MCP client which means that it can be configured to connect to MCP servers. For more information, refer to the [`config docs`](./config.md#mcp-integration).
## Using Codex as an MCP Server {#mcp-server}
## Using Codex as an MCP Server
The Codex CLI can also be run as an MCP _server_ via `codex mcp-server`. For example, you can use `codex mcp-server` to make Codex available as a tool inside of a multi-agent framework like the OpenAI [Agents SDK](https://platform.openai.com/docs/guides/agents). Use `codex mcp` separately to add/list/get/remove MCP server launchers in your configuration.
### Codex MCP Server Quickstart {#mcp-server-quickstart}
### Codex MCP Server Quickstart
You can launch a Codex MCP server with the [Model Context Protocol Inspector](https://modelcontextprotocol.io/legacy/tools/inspector):
@@ -58,7 +58,7 @@ Send a `tools/list` request and you will see that there are two tools available:
| **`prompt`** (required) | string | The next user prompt to continue the Codex conversation. |
| **`conversationId`** (required) | string | The id of the conversation to continue. |
### Trying it Out {#mcp-server-trying-it-out}
### Trying it Out
> [!TIP]
> Codex often takes a few minutes to run. To accommodate this, adjust the MCP inspector's Request and Total timeouts to 600000ms (10 minutes) under ⛭ Configuration.
+150 -117
View File
@@ -33,24 +33,23 @@ Optional and experimental capabilities are toggled via the `[features]` table in
```toml
[features]
streamable_shell = true # enable the streamable exec tool
web_search_request = true # allow the model to request web searches
# view_image_tool defaults to true; omit to keep defaults
```
Supported features:
| Key | Default | Stage | Description |
| ----------------------------------------- | :-----: | ------------ | ---------------------------------------------------- |
| `unified_exec` | false | Experimental | Use the unified PTY-backed exec tool |
| `streamable_shell` | false | Experimental | Use the streamable exec-command/write-stdin pair |
| `rmcp_client` | false | Experimental | Enable oauth support for streamable HTTP MCP servers |
| `apply_patch_freeform` | false | Beta | Include the freeform `apply_patch` tool |
| `view_image_tool` | true | Stable | Include the `view_image` tool |
| `web_search_request` | false | Stable | Allow the model to issue web searches |
| `experimental_sandbox_command_assessment` | false | Experimental | Enable model-based sandbox risk assessment |
| `ghost_commit` | false | Experimental | Create a ghost commit each turn |
| `enable_experimental_windows_sandbox` | false | Experimental | Use the Windows restricted-token sandbox |
| Key | Default | Stage | Description |
| ------------------------------------- | :-----: | ------------ | ----------------------------------------------------- |
| `unified_exec` | false | Experimental | Use the unified PTY-backed exec tool |
| `rmcp_client` | false | Experimental | Enable oauth support for streamable HTTP MCP servers |
| `apply_patch_freeform` | false | Beta | Include the freeform `apply_patch` tool |
| `view_image_tool` | true | Stable | Include the `view_image` tool |
| `web_search_request` | false | Stable | Allow the model to issue web searches |
| `ghost_commit` | false | Experimental | Create a ghost commit each turn |
| `enable_experimental_windows_sandbox` | false | Experimental | Use the Windows restricted-token sandbox |
| `tui2` | false | Experimental | Use the experimental TUI v2 (viewport) implementation |
| `skills` | false | Experimental | Enable discovery and injection of skills |
Notes:
@@ -64,7 +63,7 @@ Notes:
The model that Codex should use.
```toml
model = "gpt-5" # overrides the default ("gpt-5-codex" on macOS/Linux, "gpt-5" on Windows)
model = "gpt-5.1" # overrides the default ("gpt-5.1-codex-max" across platforms)
```
### model_providers
@@ -191,12 +190,13 @@ model = "mistral"
### model_reasoning_effort
If the selected model is known to support reasoning (for example: `o3`, `o4-mini`, `codex-*`, `gpt-5`, `gpt-5-codex`), reasoning is enabled by default when using the Responses API. As explained in the [OpenAI Platform documentation](https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning), this can be set to:
If the selected model is known to support reasoning (for example: `o3`, `o4-mini`, `codex-*`, `gpt-5.1-codex-max`, `gpt-5.1`, `gpt-5.1-codex`, `gpt-5.2`), reasoning is enabled by default when using the Responses API. As explained in the [OpenAI Platform documentation](https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning), this can be set to:
- `"minimal"`
- `"low"`
- `"medium"` (default)
- `"high"`
- `"xhigh"` (available on `gpt-5.1-codex-max` and `gpt-5.2`)
Note: to minimize reasoning, choose `"minimal"`.
@@ -227,7 +227,7 @@ When set, Codex includes a `text` object in the request payload with the configu
Example:
```toml
model = "gpt-5"
model = "gpt-5.1"
model_verbosity = "low"
```
@@ -247,11 +247,19 @@ The size of the context window for the model, in tokens.
In general, Codex knows the context window for the most common OpenAI models, but if you are using a new model with an old version of the Codex CLI, then you can use `model_context_window` to tell Codex what value to use to determine how much context is left during a conversation.
### model_max_output_tokens
### oss_provider
This is analogous to `model_context_window`, but for the maximum number of output tokens for the model.
Specifies the default OSS provider to use when running Codex. This is used when the `--oss` flag is provided without a specific provider.
> See also [`codex exec`](./exec.md) to see how these model settings influence non-interactive runs.
Valid values are:
- `"lmstudio"` - Use LM Studio as the local model provider
- `"ollama"` - Use Ollama as the local model provider
```toml
# Example: Set default OSS provider to LM Studio
oss_provider = "lmstudio"
```
## Execution environment
@@ -308,7 +316,7 @@ disk, but attempts to write a file or access the network will be blocked.
A more relaxed policy is `workspace-write`. When specified, the current working directory for the Codex task will be writable (as well as `$TMPDIR` on macOS). Note that the CLI defaults to using the directory where it was spawned as `cwd`, though this can be overridden using `--cwd/-C`.
On macOS (and soon Linux), all writable roots (including `cwd`) that contain a `.git/` folder _as an immediate child_ will configure the `.git/` folder to be read-only while the rest of the Git repository will be writable. This means that commands like `git commit` will fail, by default (as it entails writing to `.git/`), and will require Codex to ask for permission.
On macOS (and soon Linux), all writable roots (including `cwd`) that contain a `.git/` or `.codex/` folder _as an immediate child_ will configure those folders to be read-only while the rest of the root stays writable. This means that commands like `git commit` will fail, by default (as it entails writing to `.git/`), and will require Codex to ask for permission.
```toml
# same as `--sandbox workspace-write`
@@ -350,7 +358,6 @@ Codex can route subprocess network traffic through an external proxy (for exampl
enabled = true
proxy_url = "http://127.0.0.1:3128"
admin_url = "http://127.0.0.1:8080"
config_path = "~/.codex/network_proxy/config.toml"
mode = "limited" # limited | full (default)
no_proxy = ["localhost", "127.0.0.1"]
prompt_on_block = true
@@ -362,10 +369,12 @@ Notes:
- Proxy settings are injected only when sandbox network access is enabled (or full access mode). If the sandbox blocks network access, requests are blocked at the OS layer.
- `proxy_url` is used for `HTTP_PROXY`, `HTTPS_PROXY`, and `ALL_PROXY` env vars.
- `no_proxy` entries bypass the proxy; use sparingly because bypassed traffic is not filtered by the proxy policy.
- When `prompt_on_block = true`, Codex polls the proxy admin API (`/blocked`) and surfaces a prompt to allow once, allow always (add to allowlist), or deny (add to denylist). Codex writes changes to `config_path` and calls `/reload`.
- When `prompt_on_block = true`, Codex polls the proxy admin API (`/blocked`) and surfaces a prompt to allow for the session, allow always (add to allowlist), or deny (add to denylist). Allow/deny decisions update `~/.codex/config.toml` under `[network_proxy.policy]`, then Codex calls `/reload`.
### tools.\*
These `[tools]` configuration options are deprecated. Use `[features]` instead (see [Feature flags](#feature-flags)).
Use the optional `[tools]` table to toggle built-in tools that the agent may call. `web_search` stays off unless you opt in, while `view_image` is now enabled by default:
```toml
@@ -374,8 +383,6 @@ web_search = true # allow Codex to issue first-party web searches without prom
view_image = false # disable image uploads (they're enabled by default)
```
`web_search` is deprecated; use the `web_search_request` feature flag instead.
The `view_image` toggle is useful when you want to include screenshots or diagrams from your repo without pasting them manually. Codex still respects sandboxing: it can only attach files inside the workspace roots you allow.
### approval_presets
@@ -451,7 +458,7 @@ You can configure Codex to use [MCP servers](https://modelcontextprotocol.io/abo
command = "npx"
# Optional
args = ["-y", "mcp-server"]
# Optional: propagate additional env vars to the MVP server.
# Optional: propagate additional env vars to the MCP server.
# A default whitelist of env vars will be propagated to the MCP server.
# https://github.com/openai/codex/blob/main/codex-rs/rmcp-client/src/utils.rs#L82
env = { "API_KEY" = "value" }
@@ -480,10 +487,11 @@ http_headers = { "HEADER_NAME" = "HEADER_VALUE" }
env_http_headers = { "HEADER_NAME" = "ENV_VAR" }
```
Streamable HTTP connections always use the experimental Rust MCP client under the hood, so expect occasional rough edges. OAuth login flows are gated on the `experimental_use_rmcp_client = true` flag:
Streamable HTTP connections always use the experimental Rust MCP client under the hood, so expect occasional rough edges. OAuth login flows are gated on the `rmcp_client = true` flag:
```toml
experimental_use_rmcp_client = true
[features]
rmcp_client = true
```
After enabling it, run `codex mcp login <server-name>` when the server supports OAuth.
@@ -505,17 +513,6 @@ disabled_tools = ["search"]
When both `enabled_tools` and `disabled_tools` are specified, Codex first restricts the server to the allow-list and then removes any tools that appear in the deny-list.
#### Experimental RMCP client
This flag enables OAuth support for streamable HTTP servers.
```toml
experimental_use_rmcp_client = true
[mcp_servers.server_name]
…
```
#### MCP CLI commands
```shell
@@ -619,7 +616,7 @@ metadata above):
- `codex.tool_decision`
- `tool_name`
- `call_id`
- `decision` (`approved`, `approved_for_session`, `denied`, or `abort`)
- `decision` (`approved`, `approved_execpolicy_amendment`, `approved_for_session`, `denied`, or `abort`)
- `source` (`config` or `user`)
- `codex.tool_result`
- `tool_name`
@@ -641,12 +638,12 @@ Set `otel.exporter` to control where events go:
endpoint, protocol, and headers your collector expects:
```toml
[otel]
exporter = { otlp-http = {
endpoint = "https://otel.example.com/v1/logs",
protocol = "binary",
headers = { "x-otlp-api-key" = "${OTLP_TOKEN}" }
}}
[otel.exporter."otlp-http"]
endpoint = "https://otel.example.com/v1/logs"
protocol = "binary"
[otel.exporter."otlp-http".headers]
"x-otlp-api-key" = "${OTLP_TOKEN}"
```
- `otlp-grpc` – streams OTLP log records over gRPC. Provide the endpoint and any
@@ -654,12 +651,26 @@ Set `otel.exporter` to control where events go:
```toml
[otel]
exporter = { otlp-grpc = {
endpoint = "https://otel.example.com:4317",
headers = { "x-otlp-meta" = "abc123" }
}}
exporter = { otlp-grpc = {endpoint = "https://otel.example.com:4317",headers = { "x-otlp-meta" = "abc123" }}}
```
Both OTLP exporters accept an optional `tls` block so you can trust a custom CA
or enable mutual TLS. Relative paths are resolved against `~/.codex/`:
```toml
[otel.exporter."otlp-http"]
endpoint = "https://otel.example.com/v1/logs"
protocol = "binary"
[otel.exporter."otlp-http".headers]
"x-otlp-api-key" = "${OTLP_TOKEN}"
[otel.exporter."otlp-http".tls]
ca-certificate = "certs/otel-ca.pem"
client-certificate = "/etc/codex/certs/client.pem"
client-private-key = "/etc/codex/certs/client-key.pem"
```
If the exporter is `none` nothing is written anywhere; otherwise you must run or point to your
own collector. All exporters run on a background batch worker that is flushed on
shutdown.
@@ -757,6 +768,8 @@ notify = ["python3", "/Users/mbolin/.codex/notify.py"]
> [!NOTE]
> Use `notify` for automation and integrations: Codex invokes your external program with a single JSON argument for each event, independent of the TUI. If you only want lightweight desktop notifications while using the TUI, prefer `tui.notifications`, which uses terminal escape codes and requires no external program. You can enable both; `tui.notifications` covers in‑TUI alerts (e.g., approval prompts), while `notify` is best for system‑level hooks or custom notifiers. Currently, `notify` emits only `agent-turn-complete`, whereas `tui.notifications` supports `agent-turn-complete` and `approval-requested` with optional filtering.
When Codex detects WSL 2 inside Windows Terminal (the session exports `WT_SESSION`), `tui.notifications` automatically switches to a Windows toast backend by spawning `powershell.exe`. This ensures both approval prompts and completed turns trigger native toasts even though Windows Terminal ignores OSC 9 escape sequences. Terminals that advertise OSC 9 support (iTerm2, WezTerm, kitty, etc.) continue to use the existing escape-sequence backend, and the `notify` hook remains unchanged.
### hide_agent_reasoning
Codex intermittently emits "reasoning" events that show the model's internal "thinking" before it produces a final answer. Some users may find these events distracting, especially in CI logs or minimal terminal output.
@@ -827,7 +840,7 @@ Users can specify config values at multiple levels. Order of precedence is as fo
1. custom command-line argument, e.g., `--model o3`
2. as part of a profile, where the `--profile` is specified via a CLI (or in the config file itself)
3. as an entry in `config.toml`, e.g., `model = "o3"`
4. the default value that comes with Codex CLI (i.e., Codex CLI defaults to `gpt-5-codex`)
4. the default value that comes with Codex CLI (i.e., Codex CLI defaults to `gpt-5.1-codex-max`)
### history
@@ -840,6 +853,11 @@ To disable this behavior, configure `[history]` as follows:
persistence = "none" # "save-all" is the default value
```
To cap the size of `history.jsonl`, set `history.max_bytes` to a positive byte
count. When the file grows beyond the limit, Codex removes the oldest entries,
compacting the file down to roughly 80% of the hard cap while keeping the newest
record intact. Omitting the option—or setting it to `0`—disables pruning.
### file_opener
Identifies the editor/URI scheme to use for hyperlinking citations in model output. If set, citations to files in the model output will be hyperlinked using the specified URI scheme so they can be ctrl/cmd-clicked from the terminal to open them.
@@ -879,12 +897,16 @@ Options that are specific to the TUI.
```toml
[tui]
# Send desktop notifications when approvals are required or a turn completes.
# Defaults to false.
# Defaults to true.
notifications = true
# You can optionally filter to specific notification types.
# Available types are "agent-turn-complete" and "approval-requested".
notifications = [ "agent-turn-complete", "approval-requested" ]
# Disable terminal animations (welcome screen, status shimmer, spinner).
# Defaults to true.
animations = false
```
> [!NOTE]
@@ -928,70 +950,81 @@ Valid values:
## Config reference
| Key | Type / Values | Notes |
| ------------------------------------------------ | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `model` | string | Model to use (e.g., `gpt-5-codex`). |
| `model_provider` | string | Provider id from `model_providers` (default: `openai`). |
| `model_context_window` | number | Context window tokens. |
| `model_max_output_tokens` | number | Max output tokens. |
| `approval_policy` | `untrusted` \| `on-failure` \| `on-request` \| `never` | When to prompt for approval. |
| `sandbox_mode` | `read-only` \| `workspace-write` \| `danger-full-access` | OS sandbox policy. |
| `sandbox_workspace_write.writable_roots` | array<string> | Extra writable roots in workspace‑write. |
| `sandbox_workspace_write.network_access` | boolean | Allow network in workspace‑write (default: false). |
| `sandbox_workspace_write.exclude_tmpdir_env_var` | boolean | Exclude `$TMPDIR` from writable roots (default: false). |
| `sandbox_workspace_write.exclude_slash_tmp` | boolean | Exclude `/tmp` from writable roots (default: false). |
| `network_proxy.enabled` | boolean | Enable proxy environment injection + admin polling (default: false). |
| `network_proxy.proxy_url` | string | Proxy URL used for `HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY` (default: `http://127.0.0.1:3128`). |
| `network_proxy.admin_url` | string | Proxy admin API base URL (default: `http://127.0.0.1:8080`). |
| `network_proxy.config_path` | string (path) | Proxy config path to edit on approvals (default: `$CODEX_HOME/network_proxy/config.toml`). |
| `network_proxy.mode` | `limited` \| `full` | Default proxy mode for policy hints (default: `full`). |
| `network_proxy.no_proxy` | array<string> | Hosts/IPs that bypass the proxy (default includes `localhost`, `127.0.0.1`, `::1`). |
| `network_proxy.prompt_on_block` | boolean | Poll `/blocked` and prompt on denied requests (default: true). |
| `network_proxy.poll_interval_ms` | number | Admin poll interval in ms (default: 1000). |
| `notify` | array<string> | External program for notifications. |
| `instructions` | string | Currently ignored; use `experimental_instructions_file` or `AGENTS.md`. |
| `features.<feature-flag>` | boolean | See [feature flags](#feature-flags) for details |
| `mcp_servers.<id>.command` | string | MCP server launcher command (stdio servers only). |
| `mcp_servers.<id>.args` | array<string> | MCP server args (stdio servers only). |
| `mcp_servers.<id>.env` | map<string,string> | MCP server env vars (stdio servers only). |
| `mcp_servers.<id>.url` | string | MCP server url (streamable http servers only). |
| `mcp_servers.<id>.bearer_token_env_var` | string | environment variable containing a bearer token to use for auth (streamable http servers only). |
| `mcp_servers.<id>.enabled` | boolean | When false, Codex skips starting the server (default: true). |
| `mcp_servers.<id>.startup_timeout_sec` | number | Startup timeout in seconds (default: 10). Timeout is applied both for initializing MCP server and initially listing tools. |
| `mcp_servers.<id>.tool_timeout_sec` | number | Per-tool timeout in seconds (default: 60). Accepts fractional values; omit to use the default. |
| `mcp_servers.<id>.enabled_tools` | array<string> | Restrict the server to the listed tool names. |
| `mcp_servers.<id>.disabled_tools` | array<string> | Remove the listed tool names after applying `enabled_tools`, if any. |
| `model_providers.<id>.name` | string | Display name. |
| `model_providers.<id>.base_url` | string | API base URL. |
| `model_providers.<id>.env_key` | string | Env var for API key. |
| `model_providers.<id>.wire_api` | `chat` \| `responses` | Protocol used (default: `chat`). |
| `model_providers.<id>.query_params` | map<string,string> | Extra query params (e.g., Azure `api-version`). |
| `model_providers.<id>.http_headers` | map<string,string> | Additional static headers. |
| `model_providers.<id>.env_http_headers` | map<string,string> | Headers sourced from env vars. |
| `model_providers.<id>.request_max_retries` | number | Per‑provider HTTP retry count (default: 4). |
| `model_providers.<id>.stream_max_retries` | number | SSE stream retry count (default: 5). |
| `model_providers.<id>.stream_idle_timeout_ms` | number | SSE idle timeout (ms) (default: 300000). |
| `project_doc_max_bytes` | number | Max bytes to read from `AGENTS.md`. |
| `profile` | string | Active profile name. |
| `profiles.<name>.*` | various | Profile‑scoped overrides of the same keys. |
| `history.persistence` | `save-all` \| `none` | History file persistence (default: `save-all`). |
| `history.max_bytes` | number | Currently ignored (not enforced). |
| `file_opener` | `vscode` \| `vscode-insiders` \| `windsurf` \| `cursor` \| `none` | URI scheme for clickable citations (default: `vscode`). |
| `tui` | table | TUI‑specific options. |
| `tui.notifications` | boolean \| array<string> | Enable desktop notifications in the tui (default: false). |
| `hide_agent_reasoning` | boolean | Hide model reasoning events. |
| `show_raw_agent_reasoning` | boolean | Show raw reasoning (when available). |
| `model_reasoning_effort` | `minimal` \| `low` \| `medium` \| `high` | Responses API reasoning effort. |
| `model_reasoning_summary` | `auto` \| `concise` \| `detailed` \| `none` | Reasoning summaries. |
| `model_verbosity` | `low` \| `medium` \| `high` | GPT‑5 text verbosity (Responses API). |
| `model_supports_reasoning_summaries` | boolean | Force‑enable reasoning summaries. |
| `model_reasoning_summary_format` | `none` \| `experimental` | Force reasoning summary format. |
| `chatgpt_base_url` | string | Base URL for ChatGPT auth flow. |
| `experimental_instructions_file` | string (path) | Replace built‑in instructions (experimental). |
| `experimental_use_exec_command_tool` | boolean | Use experimental exec command tool. |
| `projects.<path>.trust_level` | string | Mark project/worktree as trusted (only `"trusted"` is recognized). |
| `tools.web_search` | boolean | Enable web search tool (deprecated) (default: false). |
| `tools.view_image` | boolean | Enable or disable the `view_image` tool so Codex can attach local image files from the workspace (default: true). |
| `forced_login_method` | `chatgpt` \| `api` | Only allow Codex to be used with ChatGPT or API keys. |
| `forced_chatgpt_workspace_id` | string (uuid) | Only allow Codex to be used with the specified ChatGPT workspace. |
| `cli_auth_credentials_store` | `file` \| `keyring` \| `auto` | Where to store CLI login credentials (default: `file`). |
| Key | Type / Values | Notes |
| -------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `model` | string | Model to use (e.g., `gpt-5.1-codex-max`). |
| `model_provider` | string | Provider id from `model_providers` (default: `openai`). |
| `model_context_window` | number | Context window tokens. |
| `tool_output_token_limit` | number | Token budget for stored function/tool outputs in history (default: 2,560 tokens). |
| `approval_policy` | `untrusted` \| `on-failure` \| `on-request` \| `never` | When to prompt for approval. |
| `sandbox_mode` | `read-only` \| `workspace-write` \| `danger-full-access` | OS sandbox policy. |
| `sandbox_workspace_write.writable_roots` | array<string> | Extra writable roots in workspace‑write. |
| `sandbox_workspace_write.network_access` | boolean | Allow network in workspace‑write (default: false). |
| `sandbox_workspace_write.exclude_tmpdir_env_var` | boolean | Exclude `$TMPDIR` from writable roots (default: false). |
| `sandbox_workspace_write.exclude_slash_tmp` | boolean | Exclude `/tmp` from writable roots (default: false). |
| `network_proxy.enabled` | boolean | Enable proxy environment injection + admin polling (default: false). |
| `network_proxy.proxy_url` | string | Proxy URL used for `HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY` (default: `http://127.0.0.1:3128`). |
| `network_proxy.admin_url` | string | Proxy admin API base URL (default: `http://127.0.0.1:8080`). |
| `network_proxy.mode` | `limited` \| `full` | Default proxy mode for policy hints (default: `full`). |
| `network_proxy.no_proxy` | array<string> | Hosts/IPs that bypass the proxy (default includes `localhost`, `127.0.0.1`, `::1`). |
| `network_proxy.prompt_on_block` | boolean | Poll `/blocked` and prompt on denied requests (default: true). |
| `network_proxy.poll_interval_ms` | number | Admin poll interval in ms (default: 1000). |
| `network_proxy.policy.allowedDomains` | array<string> | Allowlist of domain patterns (denylist takes precedence). |
| `network_proxy.policy.deniedDomains` | array<string> | Denylist of domain patterns (takes precedence over allowlist). |
| `network_proxy.mitm.enabled` | boolean | Enable HTTPS MITM for read-only enforcement in limited mode (default: false). |
| `network_proxy.mitm.inspect` | boolean | Enable body inspection in MITM mode (default: false). |
| `network_proxy.mitm.max_body_bytes` | number | Max body bytes to buffer when inspection is enabled (default: 4096). |
| `network_proxy.mitm.ca_cert_path` | string (path) | CA cert path (default: `network_proxy/mitm/ca.pem` under `$CODEX_HOME`). |
| `network_proxy.mitm.ca_key_path` | string (path) | CA key path (default: `network_proxy/mitm/ca.key` under `$CODEX_HOME`). |
| `notify` | array<string> | External program for notifications. |
| `tui.animations` | boolean | Enable terminal animations (welcome screen, shimmer, spinner). Defaults to true; set to `false` to disable visual motion. |
| `instructions` | string | Currently ignored; use `experimental_instructions_file` or `AGENTS.md`. |
| `features.<feature-flag>` | boolean | See [feature flags](#feature-flags) for details |
| `ghost_snapshot.disable_warnings` | boolean | Disable every warnings around ghost snapshot (large files, directory, ...) |
| `ghost_snapshot.ignore_large_untracked_files` | number | Exclude untracked files larger than this many bytes from ghost snapshots (default: 10 MiB). Set to `0` to disable. |
| `ghost_snapshot.ignore_large_untracked_dirs` | number | Ignore untracked directories with at least this many files (default: 200). Set to `0` to disable. |
| `mcp_servers.<id>.command` | string | MCP server launcher command (stdio servers only). |
| `mcp_servers.<id>.args` | array<string> | MCP server args (stdio servers only). |
| `mcp_servers.<id>.env` | map<string,string> | MCP server env vars (stdio servers only). |
| `mcp_servers.<id>.url` | string | MCP server url (streamable http servers only). |
| `mcp_servers.<id>.bearer_token_env_var` | string | environment variable containing a bearer token to use for auth (streamable http servers only). |
| `mcp_servers.<id>.enabled` | boolean | When false, Codex skips starting the server (default: true). |
| `mcp_servers.<id>.startup_timeout_sec` | number | Startup timeout in seconds (default: 10). Timeout is applied both for initializing MCP server and initially listing tools. |
| `mcp_servers.<id>.tool_timeout_sec` | number | Per-tool timeout in seconds (default: 60). Accepts fractional values; omit to use the default. |
| `mcp_servers.<id>.enabled_tools` | array<string> | Restrict the server to the listed tool names. |
| `mcp_servers.<id>.disabled_tools` | array<string> | Remove the listed tool names after applying `enabled_tools`, if any. |
| `model_providers.<id>.name` | string | Display name. |
| `model_providers.<id>.base_url` | string | API base URL. |
| `model_providers.<id>.env_key` | string | Env var for API key. |
| `model_providers.<id>.wire_api` | `chat` \| `responses` | Protocol used (default: `chat`). |
| `model_providers.<id>.query_params` | map<string,string> | Extra query params (e.g., Azure `api-version`). |
| `model_providers.<id>.http_headers` | map<string,string> | Additional static headers. |
| `model_providers.<id>.env_http_headers` | map<string,string> | Headers sourced from env vars. |
| `model_providers.<id>.request_max_retries` | number | Per‑provider HTTP retry count (default: 4). |
| `model_providers.<id>.stream_max_retries` | number | SSE stream retry count (default: 5). |
| `model_providers.<id>.stream_idle_timeout_ms` | number | SSE idle timeout (ms) (default: 300000). |
| `project_doc_max_bytes` | number | Max bytes to read from `AGENTS.md`. |
| `profile` | string | Active profile name. |
| `profiles.<name>.*` | various | Profile‑scoped overrides of the same keys. |
| `history.persistence` | `save-all` \| `none` | History file persistence (default: `save-all`). |
| `history.max_bytes` | number | Maximum size of `history.jsonl` in bytes; when exceeded, history is compacted to ~80% of this limit by dropping oldest entries. |
| `file_opener` | `vscode` \| `vscode-insiders` \| `windsurf` \| `cursor` \| `none` | URI scheme for clickable citations (default: `vscode`). |
| `tui` | table | TUI‑specific options. |
| `tui.notifications` | boolean \| array<string> | Enable desktop notifications in the tui (default: true). |
| `hide_agent_reasoning` | boolean | Hide model reasoning events. |
| `check_for_update_on_startup` | boolean | Check for Codex updates on startup (default: true). Set to `false` only if updates are centrally managed. |
| `show_raw_agent_reasoning` | boolean | Show raw reasoning (when available). |
| `model_reasoning_effort` | `minimal` \| `low` \| `medium` \| `high`\|`xhigh` | Responses API reasoning effort. |
| `model_reasoning_summary` | `auto` \| `concise` \| `detailed` \| `none` | Reasoning summaries. |
| `model_verbosity` | `low` \| `medium` \| `high` | GPT‑5 text verbosity (Responses API). |
| `model_supports_reasoning_summaries` | boolean | Force‑enable reasoning summaries. |
| `model_reasoning_summary_format` | `none` \| `experimental` | Force reasoning summary format. |
| `chatgpt_base_url` | string | Base URL for ChatGPT auth flow. |
| `experimental_instructions_file` | string (path) | Replace built‑in instructions (experimental). |
| `experimental_use_exec_command_tool` | boolean | Use experimental exec command tool. |
| `projects.<path>.trust_level` | string | Mark project/worktree as trusted (only `"trusted"` is recognized). |
| `tools.web_search` | boolean | Enable web search tool (deprecated) (default: false). |
| `tools.view_image` | boolean | Enable or disable the `view_image` tool so Codex can attach local image files from the workspace (default: true). |
| `forced_login_method` | `chatgpt` \| `api` | Only allow Codex to be used with ChatGPT or API keys. |
| `forced_chatgpt_workspace_id` | string (uuid) | Only allow Codex to be used with the specified ChatGPT workspace. |
| `cli_auth_credentials_store` | `file` \| `keyring` \| `auto` | Where to store CLI login credentials (default: `file`). |
+1 -20
View File
@@ -25,7 +25,7 @@ If you want to add a new feature or change the behavior of an existing one, plea
- Fill in the PR template (or include similar information) - **What? Why? How?**
- Include a link to a bug report or enhancement request in the issue tracker
- Run **all** checks locally (`cargo test && cargo clippy --tests && cargo fmt -- --config imports_granularity=Item`). CI failures that could have been caught locally slow down the process.
- Run **all** checks locally. Use the root `just` helpers so you stay consistent with the rest of the workspace: `just fmt`, `just fix -p <crate>` for the crate you touched, and the relevant tests (e.g., `cargo test -p codex-tui` or `just test` if you need a full sweep). CI failures that could have been caught locally slow down the process.
- Make sure your branch is up-to-date with `main` and that you have resolved merge conflicts.
- Mark the PR as **Ready for review** only when you believe it is in a merge-able state.
@@ -71,25 +71,6 @@ No special Git commands, email attachments, or commit footers required.
The **DCO check** blocks merges until every commit in the PR carries the footer (with squash this is just the one).
### Releasing `codex`
_For admins only._
Make sure you are on `main` and have no local changes. Then run:
```shell
VERSION=0.2.0 # Can also be 0.2.0-alpha.1 or any valid Rust version.
./codex-rs/scripts/create_github_release.sh "$VERSION"
```
This will make a local commit on top of `main` with `version` set to `$VERSION` in `codex-rs/Cargo.toml` (note that on `main`, we leave the version as `version = "0.0.0"`).
This will push the commit using the tag `rust-v${VERSION}`, which in turn kicks off [the release workflow](../.github/workflows/rust-release.yml). This will create a new GitHub Release named `$VERSION`.
If everything looks good in the generated GitHub Release, uncheck the **pre-release** box so it is the latest release.
Create a PR to update [`Cask/c/codex.rb`](https://github.com/Homebrew/homebrew-cask/blob/main/Formula/c/codex.rb) on Homebrew.
### Security & responsible AI
Have you discovered a vulnerability or have concerns about model output? Please e-mail **security@openai.com** and we will respond promptly.
+44 -50
View File
@@ -18,12 +18,11 @@ Use this example configuration as a starting point. For an explanation of each f
# Core Model Selection
################################################################################
# Primary model used by Codex. Default differs by OS; non-Windows defaults here.
# Linux/macOS default: "gpt-5-codex"; Windows default: "gpt-5".
model = "gpt-5-codex"
# Primary model used by Codex. Default: "gpt-5.1-codex-max" on all platforms.
model = "gpt-5.1-codex-max"
# Model used by the /review feature (code reviews). Default: "gpt-5-codex".
review_model = "gpt-5-codex"
# Model used by the /review feature (code reviews). Default: "gpt-5.1-codex-max".
review_model = "gpt-5.1-codex-max"
# Provider id selected from [model_providers]. Default: "openai".
model_provider = "openai"
@@ -31,14 +30,14 @@ model_provider = "openai"
# Optional manual model metadata. When unset, Codex auto-detects from model.
# Uncomment to force values.
# model_context_window = 128000 # tokens; default: auto for model
# model_max_output_tokens = 8192 # tokens; default: auto for model
# model_auto_compact_token_limit = 0 # disable/override auto; default: model family specific
# tool_output_token_limit = 10000 # tokens stored per tool output; default: 10000 for gpt-5.1-codex-max
################################################################################
# Reasoning & Verbosity (Responses API capable models)
################################################################################
# Reasoning effort: minimal | low | medium | high (default: medium)
# Reasoning effort: minimal | low | medium | high | xhigh (default: medium; xhigh on gpt-5.1-codex-max and gpt-5.2)
model_reasoning_effort = "medium"
# Reasoning summary: auto | concise | detailed | none (default: auto)
@@ -109,10 +108,8 @@ exclude_slash_tmp = false
enabled = false
# HTTP/HTTPS/ALL proxy URL. Default: "http://127.0.0.1:3128"
proxy_url = "http://127.0.0.1:3128"
# Admin API for the proxy (for /blocked, /allow_once, /reload). Default: "http://127.0.0.1:8080"
# Admin API for the proxy (for /blocked, /reload, /mode). Default: "http://127.0.0.1:8080"
admin_url = "http://127.0.0.1:8080"
# Proxy config file to edit when approvals are granted/denied.
config_path = "~/.codex/network_proxy/config.toml"
# limited | full (default: full)
mode = "full"
# Hosts/IPs that bypass the proxy. Default includes localhost + loopback.
@@ -147,7 +144,7 @@ experimental_use_profile = false
[history]
# save-all (default) | none
persistence = "save-all"
# Maximum bytes for history file (currently not enforced). Example: 5242880
# Maximum bytes for history file; oldest entries are trimmed when exceeded. Example: 5242880
# max_bytes = 0
# URI scheme for clickable citations: vscode (default) | vscode-insiders | windsurf | cursor | none
@@ -158,17 +155,20 @@ file_opener = "vscode"
################################################################################
[tui]
# Desktop notifications from the TUI: boolean or filtered list. Default: false
# Examples: true | ["agent-turn-complete", "approval-requested"]
# Desktop notifications from the TUI: boolean or filtered list. Default: true
# Examples: false | ["agent-turn-complete", "approval-requested"]
notifications = false
# Suppress internal reasoning events from output (default: false)
# Enables welcome/status/spinner animations. Default: true
animations = true
# Suppress internal reasoning events from output. Default: false
hide_agent_reasoning = false
# Show raw reasoning content when available (default: false)
# Show raw reasoning content when available. Default: false
show_raw_agent_reasoning = false
# Disable burst-paste detection in the TUI (default: false)
# Disable burst-paste detection in the TUI. Default: false
disable_paste_burst = false
# Track Windows onboarding acknowledgement (Windows only). Default: false
@@ -200,6 +200,9 @@ chatgpt_base_url = "https://chatgpt.com/backend-api/"
# Allowed values: chatgpt | api
# forced_login_method = "chatgpt"
# Preferred store for MCP OAuth credentials: auto (default) | file | keyring
mcp_oauth_credentials_store = "auto"
################################################################################
# Project Documentation Controls
################################################################################
@@ -231,38 +234,21 @@ view_image = true
[features]
# Leave this table empty to accept defaults. Set explicit booleans to opt in/out.
unified_exec = false
streamable_shell = false
rmcp_client = false
apply_patch_freeform = false
view_image_tool = true
web_search_request = false
experimental_sandbox_command_assessment = false
ghost_commit = false
enable_experimental_windows_sandbox = false
skills = false
################################################################################
# Experimental toggles (legacy; prefer [features])
################################################################################
# Use experimental unified exec tool. Default: false
experimental_use_unified_exec_tool = false
# Use experimental Rust MCP client (enables OAuth for HTTP MCP). Default: false
experimental_use_rmcp_client = false
# Include apply_patch via freeform editing path (affects default tool set). Default: false
experimental_use_freeform_apply_patch = false
# Enable model-based sandbox command assessment. Default: false
experimental_sandbox_command_assessment = false
################################################################################
# MCP (Model Context Protocol) servers
################################################################################
# Preferred store for MCP OAuth credentials: auto (default) | file | keyring
mcp_oauth_credentials_store = "auto"
# Define MCP servers under this table. Leave empty to disable.
[mcp_servers]
@@ -337,7 +323,7 @@ mcp_oauth_credentials_store = "auto"
[profiles]
# [profiles.default]
# model = "gpt-5-codex"
# model = "gpt-5.1-codex-max"
# model_provider = "openai"
# approval_policy = "on-request"
# sandbox_mode = "read-only"
@@ -345,12 +331,9 @@ mcp_oauth_credentials_store = "auto"
# model_reasoning_summary = "auto"
# model_verbosity = "medium"
# chatgpt_base_url = "https://chatgpt.com/backend-api/"
# experimental_compact_prompt_file = "compact_prompt.txt"
# experimental_compact_prompt_file = "./compact_prompt.txt"
# include_apply_patch_tool = false
# experimental_use_unified_exec_tool = false
# experimental_use_rmcp_client = false
# experimental_use_freeform_apply_patch = false
# experimental_sandbox_command_assessment = false
# tools_web_search = false
# tools_view_image = true
# features = { unified_exec = false }
@@ -377,17 +360,28 @@ environment = "dev"
exporter = "none"
# Example OTLP/HTTP exporter configuration
# [otel]
# exporter = { otlp-http = {
# endpoint = "https://otel.example.com/v1/logs",
# protocol = "binary", # "binary" | "json"
# headers = { "x-otlp-api-key" = "${OTLP_TOKEN}" }
# }}
# [otel.exporter."otlp-http"]
# endpoint = "https://otel.example.com/v1/logs"
# protocol = "binary" # "binary" | "json"
# [otel.exporter."otlp-http".headers]
# "x-otlp-api-key" = "${OTLP_TOKEN}"
# Example OTLP/gRPC exporter configuration
# [otel]
# exporter = { otlp-grpc = {
# endpoint = "https://otel.example.com:4317",
# headers = { "x-otlp-meta" = "abc123" }
# }}
# [otel.exporter."otlp-grpc"]
# endpoint = "https://otel.example.com:4317",
# headers = { "x-otlp-meta" = "abc123" }
# Example OTLP exporter with mutual TLS
# [otel.exporter."otlp-http"]
# endpoint = "https://otel.example.com/v1/logs"
# protocol = "binary"
# [otel.exporter."otlp-http".headers]
# "x-otlp-api-key" = "${OTLP_TOKEN}"
# [otel.exporter."otlp-http".tls]
# ca-certificate = "certs/otel-ca.pem"
# client-certificate = "/etc/codex/certs/client.pem"
# client-private-key = "/etc/codex/certs/client-key.pem"
```
+2 -2
View File
@@ -99,8 +99,8 @@ codex exec resume --last "Fix use-after-free issues"
Only the conversation context is preserved; you must still provide flags to customize Codex behavior.
```shell
codex exec --model gpt-5-codex --json "Review the change, look for use-after-free issues"
codex exec --model gpt-5 --json resume --last "Fix use-after-free issues"
codex exec --model gpt-5.1-codex-max --json "Review the change, look for use-after-free issues"
codex exec --model gpt-5.1 --json resume --last "Fix use-after-free issues"
```
## Authentication
+74
View File
@@ -0,0 +1,74 @@
# Execpolicy quickstart
Codex can enforce your own rules-based execution policy before it runs shell commands. Policies live in `.rules` files under `~/.codex/rules`.
## How to create and edit rules
### TUI interactions
Codex CLI will present the option to whitelist commands when a command causes a prompt.
<img width="513" height="168" alt="Screenshot 2025-12-04 at 9 23 54 AM" src="https://github.com/user-attachments/assets/4c8ee8ea-3101-4a81-bb13-3f4a9aa02502" />
Whitelisted commands will no longer require your permission to run in current and subsequent sessions.
Under the hood, when you approve and whitelist a command, codex will edit `~/.codex/rules/default.rules`.
### Editing `.rules` files
1. Create a policy directory: `mkdir -p ~/.codex/rules`.
2. Add one or more `.rules` files in that folder. Codex automatically loads every `.rules` file in there on startup.
3. Write `prefix_rule` entries to describe the commands you want to allow, prompt, or block:
```starlark
prefix_rule(
pattern = ["git", ["push", "fetch"]],
decision = "prompt", # allow | prompt | forbidden
match = [["git", "push", "origin", "main"]], # examples that must match
not_match = [["git", "status"]], # examples that must not match
)
```
- `pattern` is a list of shell tokens, evaluated from left to right; wrap tokens in a nested list to express alternatives (for example, match both `push` and `fetch`).
- `decision` sets the severity; Codex picks the strictest decision when multiple rules match (forbidden > prompt > allow).
- `match` and `not_match` act as optional unit tests. Codex validates them when it loads your policy, so you get feedback if an example has unexpected behavior.
In this example rule, if Codex wants to run commands with the prefix `git push` or `git fetch`, it will first ask for user approval.
## Preview decisions
Use the `codex execpolicy check` subcommand to preview decisions before you save a rule (see the [`codex-execpolicy` README](../codex-rs/execpolicy/README.md) for syntax details):
```shell
codex execpolicy check --rules ~/.codex/rules/default.rules git push origin main
```
Pass multiple `--rules` flags to test how several files combine, and use `--pretty` for formatted JSON output. See the [`codex-rs/execpolicy` README](../codex-rs/execpolicy/README.md) for a more detailed walkthrough of the available syntax.
Example output when a rule matches:
```json
{
"matchedRules": [
{
"prefixRuleMatch": {
"matchedPrefix": ["git", "push"],
"decision": "prompt"
}
}
],
"decision": "prompt"
}
```
When no rules match, `matchedRules` is an empty array and `decision` is omitted.
```json
{
"matchedRules": []
}
```
## Status
`execpolicy` commands are still in preview. The API may have breaking changes in the future.
+1 -1
View File
@@ -8,7 +8,7 @@ In 2021, OpenAI released Codex, an AI system designed to generate code from natu
### Which models are supported?
We recommend using Codex with GPT-5 Codex, our best coding model. The default reasoning level is medium, and you can upgrade to high for complex tasks with the `/model` command.
We recommend using Codex with GPT-5.1 Codex Max, our best coding model. The default reasoning level is medium, and you can upgrade to high or xhigh (where supported, e.g. `gpt-5.1-codex-max` and `gpt-5.2`) for complex tasks with the `/model` command.
You can also use older models by using API-based auth and launching codex with the `--model` flag.
+5
View File
@@ -21,6 +21,7 @@ Key flags: `--model/-m`, `--ask-for-approval/-a`.
- Run `codex resume` to display the session picker UI
- Resume most recent: `codex resume --last`
- Resume by id: `codex resume <SESSION_ID>` (You can get session ids from /status or `~/.codex/sessions/`)
- The picker shows the session's original working directory and, when available, the Git branch it was recorded on
Examples:
@@ -112,3 +113,7 @@ Paste images directly into the composer (Ctrl+V / Cmd+V) to attach them to your
codex -i screenshot.png "Explain this error"
codex --image img1.png,img2.jpg "Summarize these diagrams"
```
#### Environment variables and executables
Make sure your environment is already set up before launching Codex so it does not spend tokens probing what to activate. For example, source your Python virtualenv (or other language runtimes), start any required daemons, and export the env vars you expect to use ahead of time.
+13 -5
View File
@@ -24,6 +24,10 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup component add rustfmt
rustup component add clippy
# Install helper tools used by the workspace justfile:
cargo install just
# Optional: install nextest for the `just test` helper (or use `cargo test --all-features` as a fallback)
cargo install cargo-nextest
# Build Codex.
cargo build
@@ -31,10 +35,14 @@ cargo build
# Launch the TUI with a sample prompt.
cargo run --bin codex -- "explain this codebase to me"
# After making changes, ensure the code is clean.
cargo fmt -- --config imports_granularity=Item
cargo clippy --tests
# After making changes, use the root justfile helpers (they default to codex-rs):
just fmt
just fix -p <crate-you-touched>
# Run the tests.
cargo test
# Run the relevant tests (project-specific is fastest), for example:
cargo test -p codex-tui
# If you have cargo-nextest installed, `just test` runs the full suite:
just test
# Otherwise, fall back to:
cargo test --all-features
```
+1 -1
View File
@@ -1,3 +1,3 @@
## Platform sandboxing
This content now lives alongside the rest of the sandbox guidance. See [Sandbox mechanics by platform](./sandbox.md#platform-sandboxing-details) for up-to-date details.
This content now lives alongside the rest of the sandbox guidance. See [Sandbox mechanics by platform](./sandbox.md#sandbox-mechanics-by-platform) for up-to-date details.
+44 -5
View File
@@ -42,16 +42,55 @@ Custom prompts turn your repeatable instructions into reusable slash commands, s
### Examples
**Draft PR helper**
### Example 1: Basic named arguments
`~/.codex/prompts/draftpr.md`
**File**: `~/.codex/prompts/ticket.md`
```markdown
---
description: Create feature branch, commit and open draft PR.
description: Generate a commit message for a ticket
argument-hint: TICKET_ID=<id> TICKET_TITLE=<title>
---
Create a branch named `tibo/<feature_name>`, commit the changes, and open a draft PR.
Please write a concise commit message for ticket $TICKET_ID: $TICKET_TITLE
```
Usage: type `/prompts:draftpr` to have codex perform the work.
**Usage**:
```
/prompts:ticket TICKET_ID=JIRA-1234 TICKET_TITLE="Fix login bug"
```
**Expanded prompt sent to Codex**:
```
Please write a concise commit message for ticket JIRA-1234: Fix login bug
```
**Note**: Both `TICKET_ID` and `TICKET_TITLE` are required. If either is missing, Codex will show a validation error. Values with spaces must be double-quoted.
### Example 2: Mixed positional and named arguments
**File**: `~/.codex/prompts/review.md`
```markdown
---
description: Review code in a specific file with focus area
argument-hint: FILE=<path> [FOCUS=<section>]
---
Review the code in $FILE. Pay special attention to $FOCUS.
```
**Usage**:
```
/prompts:review FILE=src/auth.js FOCUS="error handling"
```
**Expanded prompt**:
```
Review the code in src/auth.js. Pay special attention to error handling.
```
-45
View File
@@ -1,45 +0,0 @@
# Release Management
Currently, we made Codex binaries available in three places:
- GitHub Releases https://github.com/openai/codex/releases/
- `@openai/codex` on npm: https://www.npmjs.com/package/@openai/codex
- `codex` on Homebrew: https://formulae.brew.sh/cask/codex
# Cutting a Release
Run the `codex-rs/scripts/create_github_release` script in the repository to publish a new release. The script will choose the appropriate version number depending on the type of release you are creating.
To cut a new alpha release from `main` (feel free to cut alphas liberally):
```
./codex-rs/scripts/create_github_release --publish-alpha
```
To cut a new _public_ release from `main` (which requires more caution), run:
```
./codex-rs/scripts/create_github_release --publish-release
```
TIP: Add the `--dry-run` flag to report the next version number for the respective release and exit.
Running the publishing script will kick off a GitHub Action to build the release, so go to https://github.com/openai/codex/actions/workflows/rust-release.yml to find the corresponding workflow. (Note: we should automate finding the workflow URL with `gh`.)
When the workflow finishes, the GitHub Release is "done," but you still have to consider npm and Homebrew.
## Publishing to npm
The GitHub Action is responsible for publishing to npm.
## Publishing to Homebrew
For Homebrew, we ship Codex as a cask. Homebrew's automation system checks our GitHub repo every few hours for a new release and will open a PR to update the cask with the latest binary.
Inevitably, you just have to refresh this page periodically to see if the release has been picked up by their automation system:
https://github.com/Homebrew/homebrew-cask/pulls?q=%3Apr+codex
For reference, our Homebrew cask lives at:
https://github.com/Homebrew/homebrew-cask/blob/main/Casks/c/codex.rb
+27 -25
View File
@@ -4,21 +4,12 @@ What Codex is allowed to do is governed by a combination of **sandbox modes** (w
### Approval policies
Codex starts conservatively. Until you explicitly tell it a workspace is trusted, the CLI defaults to **read-only sandboxing** with the `read-only` approval preset. Codex can inspect files and answer questions, but every edit or command requires approval.
Codex starts conservatively. Until you explicitly tell it a working directory is trusted, the CLI defaults to **read-only**. Codex can inspect files and answer questions, but every edit or command requires approval.
When you mark a workspace as trusted (for example via the onboarding prompt or `/approvals` → “Trust this directory”), Codex upgrades the default preset to **Auto**: sandboxed writes inside the workspace with `AskForApproval::OnRequest`. Codex only interrupts you when it needs to leave the workspace or rerun something outside the sandbox.
When you mark a working directory as trusted (for example via the onboarding prompt or `/approvals` → “Trust this directory”), Codex upgrades the default preset to **Agent**, which allows writes inside the workspace. Codex only interrupts you when it needs to leave the workspace or rerun something outside the sandbox. Note that the workspace includes the working directory plus temporary directories like `/tmp`. Use `/status` to confirm the exact writable roots.
If you want maximum guardrails for a trusted repo, switch back to Read Only from the `/approvals` picker. If you truly need hands-off automation, use `Full Access`—but be deliberate, because that skips both the sandbox and approvals.
#### Defaults and recommendations
- Every session starts in a sandbox. Until a repo is trusted, Codex enforces read-only access and will prompt before any write or command.
- Marking a repo as trusted switches the default preset to Auto (`workspace-write` + `ask-for-approval on-request`) so Codex can keep iterating locally without nagging you.
- The workspace always includes the current directory plus temporary directories like `/tmp`. Use `/status` to confirm the exact writable roots.
- You can override the defaults from the command line at any time:
- `codex --sandbox read-only --ask-for-approval on-request`
- `codex --sandbox workspace-write --ask-for-approval on-request`
### Can I run without ANY approvals?
Yes, you can disable all approval prompts with `--ask-for-approval never`. This option works with all `--sandbox` modes, so you still have full control over Codex's level of autonomy. It will make its best attempt with whatever constraints you provide.
@@ -65,17 +56,18 @@ sandbox_mode = "read-only"
### Network proxy approvals
Codex can optionally route outbound network traffic through a proxy (for example the `network_proxy` sandbox proxy) and prompt you when new domains are blocked by policy.
Codex can optionally route outbound network traffic through a proxy and prompt you when new domains are blocked by policy.
Key behaviors:
- The OS sandbox is still the first line of defense. If network access is disabled, outbound requests are blocked at the OS level.
- When network is enabled and `network_proxy.prompt_on_block = true`, Codex polls the proxy admin API (`/blocked`) and immediately notifies you about blocked domains.
- For exec commands that include HTTP/HTTPS URLs, Codex preflights the host against the proxy config and prompts before running the command.
- Approvals update `~/.codex/config.toml` under `[network_proxy.policy]` and trigger a proxy reload.
- You can choose to:
- **Deny** the request (adds the domain to the proxy denylist).
- **Allow once** (temporary exception via the proxy admin API).
- **Allow permanently** (adds the domain to the proxy allowlist and reloads policy).
- **Deny** the request (adds the domain to the denylist).
- **Allow for session** (temporary allow that is reverted on exit).
- **Allow always** (adds the domain to the allowlist).
Network access is controlled through a proxy server running outside the sandbox:
@@ -86,24 +78,34 @@ Network access is controlled through a proxy server running outside the sandbox:
`NO_PROXY` is supported via `[network_proxy].no_proxy` and is passed to subprocesses as `NO_PROXY/no_proxy`. Any domains or IPs in that list bypass the proxy and are not filtered by proxy policy.
When MITM is enabled in the proxy config, Codex injects common CA environment variables (for example `SSL_CERT_FILE`, `CURL_CA_BUNDLE`, `GIT_SSL_CAINFO`, `REQUESTS_CA_BUNDLE`, `NODE_EXTRA_CA_CERTS`, `PIP_CERT`, and `NPM_CONFIG_CAFILE`) pointing at the proxy CA cert to reduce per‑tool configuration. It also sets common tool‑specific proxy variables (Yarn/npm/Electron) and, when possible, appends Gradle proxy flags via `GRADLE_OPTS`.
When MITM is enabled in the proxy config, Codex injects common CA environment variables (for example `SSL_CERT_FILE`, `CURL_CA_BUNDLE`, `GIT_SSL_CAINFO`, `REQUESTS_CA_BUNDLE`, `NODE_EXTRA_CA_CERTS`, `PIP_CERT`, and `NPM_CONFIG_CAFILE`) pointing at the proxy CA cert to reduce per‑tool configuration.
### Sandbox mechanics by platform {#platform-sandboxing-details}
### Sandbox mechanics by platform
The mechanism Codex uses to enforce the sandbox policy depends on your OS:
- **macOS 12+** uses **Apple Seatbelt**. Codex invokes `sandbox-exec` with a profile that corresponds to the selected `--sandbox` mode, constraining filesystem and network access at the OS level.
- **Linux** combines **Landlock** and **seccomp** APIs to approximate the same guarantees. Kernel support is required; older kernels may not expose the necessary features.
- **Windows (experimental)**:
- Launches commands inside a restricted token derived from an AppContainer profile.
- Grants only specifically requested filesystem capabilities by attaching capability SIDs to that profile.
- Disables outbound network access by overriding proxy-related environment variables and inserting stub executables for common network tools.
#### macOS 12+
Windows sandbox support remains highly experimental. It cannot prevent file writes, deletions, or creations in any directory where the Everyone SID already has write permissions (for example, world-writable folders).
Uses **Apple Seatbelt**. Codex invokes `sandbox-exec` with a profile that corresponds to the selected `--sandbox` mode, constraining filesystem and network access at the OS level.
#### Linux
Combines **Landlock** and **seccomp** APIs to approximate the same guarantees. Kernel support is required; older kernels may not expose the necessary features.
In containerized Linux environments (for example Docker), sandboxing may not work when the host or container configuration does not expose Landlock/seccomp. In those cases, configure the container to provide the isolation you need and run Codex with `--sandbox danger-full-access` (or the shorthand `--dangerously-bypass-approvals-and-sandbox`) inside that container.
### Experimenting with the Codex Sandbox
#### Windows
Windows sandbox support remains experimental. How it works:
- Launches commands inside a restricted token derived from an AppContainer profile.
- Grants only specifically requested filesystem capabilities by attaching capability SIDs to that profile.
- Disables outbound network access by overriding proxy-related environment variables and inserting stub executables for common network tools.
Its primary limitation is that it cannot prevent file writes, deletions, or creations in any directory where the Everyone SID already has write permissions (for example, world-writable folders).
See more discussion and limitations at [Windows Sandbox Security Details](./windows_sandbox_security.md).
## Experimenting with the Codex Sandbox
To test how commands behave under Codex's sandbox, use the CLI helpers:
+80
View File
@@ -0,0 +1,80 @@
# Skills (experimental)
> **Warning:** This is an experimental and non-stable feature. If you depend on it, please expect breaking changes over the coming weeks and understand that there is currently no guarantee that this works well. Use at your own risk!
Codex can automatically discover reusable "skills" you keep on disk. A skill is a small bundle with a name, a short description (what it does and when to use it), and an optional body of instructions you can open when needed. Codex injects only the name, description, and file path into the runtime context; the body stays on disk.
## Enable skills
Skills are behind the experimental `skills` feature flag and are disabled by default.
- Enable in config (preferred): add the following to `$CODEX_HOME/config.toml` (usually `~/.codex/config.toml`) and restart Codex:
```toml
[features]
skills = true
```
- Enable for a single run: launch Codex with `codex --enable skills`
## Where skills live
- Location (v1): `~/.codex/skills/**/SKILL.md` (recursive). Hidden entries and symlinks are skipped. Only files named exactly `SKILL.md` count.
- Sorting: rendered by name, then path for stability.
## File format
- YAML frontmatter + body.
- Required:
- `name` (non-empty, ≤100 chars, sanitized to one line)
- `description` (non-empty, ≤500 chars, sanitized to one line)
- Extra keys are ignored. The body can contain any Markdown; it is not injected into context.
## Loading and rendering
- Loaded once at startup.
- If valid skills exist, Codex appends a runtime-only `## Skills` section after `AGENTS.md`, one bullet per skill: `- <name>: <description> (file: /absolute/path/to/SKILL.md)`.
- If no valid skills exist, the section is omitted. On-disk files are never modified.
## Using skills
- Mention a skill by name in a message using `$<skill-name>`.
- In the TUI, you can also use `/skills` to browse and insert skills.
## Validation and errors
- Invalid skills (missing/invalid YAML, empty/over-length fields) trigger a blocking, dismissible startup modal in the TUI that lists each path and error. Errors are also logged. You can dismiss to continue (invalid skills are ignored) or exit. Fix SKILL.md files and restart to clear the modal.
## Create a skill
1. Create `~/.codex/skills/<skill-name>/`.
2. Add `SKILL.md`:
```
---
name: your-skill-name
description: what it does and when to use it (<=500 chars)
---
# Optional body
Add instructions, references, examples, or scripts (kept on disk).
```
3. Keep `name`/`description` within the limits; avoid newlines in those fields.
4. Restart Codex to load the new skill.
## Example
```
mkdir -p ~/.codex/skills/pdf-processing
cat <<'SKILL_EXAMPLE' > ~/.codex/skills/pdf-processing/SKILL.md
---
name: pdf-processing
description: Extract text and tables from PDFs; use when PDFs, forms, or document extraction are mentioned.
---
# PDF Processing
- Use pdfplumber to extract text.
- For form filling, see FORMS.md.
SKILL_EXAMPLE
```
+20 -17
View File
@@ -10,22 +10,25 @@ Slash commands are special commands you can type that start with `/`.
Control Codex’s behavior during an interactive session with slash commands.
| Command | Purpose |
| ------------ | ----------------------------------------------------------- |
| `/model` | choose what model and reasoning effort to use |
| `/approvals` | choose what Codex can do without approval |
| `/review` | review my current changes and find issues |
| `/new` | start a new chat during a conversation |
| `/init` | create an AGENTS.md file with instructions for Codex |
| `/compact` | summarize conversation to prevent hitting the context limit |
| `/undo` | ask Codex to undo a turn |
| `/diff` | show git diff (including untracked files) |
| `/mention` | mention a file |
| `/status` | show current session configuration and token usage |
| `/mcp` | list configured MCP tools |
| `/logout` | log out of Codex |
| `/quit` | exit Codex |
| `/exit` | exit Codex |
| `/feedback` | send logs to maintainers |
| Command | Purpose |
| --------------- | -------------------------------------------------------------------------- |
| `/model` | choose what model and reasoning effort to use |
| `/approvals` | choose what Codex can do without approval |
| `/review` | review my current changes and find issues |
| `/new` | start a new chat during a conversation |
| `/resume` | resume an old chat |
| `/init` | create an AGENTS.md file with instructions for Codex |
| `/compact` | summarize conversation to prevent hitting the context limit |
| `/undo` | ask Codex to undo a turn |
| `/diff` | show git diff (including untracked files) |
| `/mention` | mention a file |
| `/status` | show current session configuration and token usage |
| `/mcp` | list configured MCP tools |
| `/experimental` | open the experimental menu to enable features from our beta program |
| `/skills` | browse and insert skills (experimental; see [docs/skills.md](./skills.md)) |
| `/logout` | log out of Codex |
| `/quit` | exit Codex |
| `/exit` | exit Codex |
| `/feedback` | send logs to maintainers |
---
+22
View File
@@ -0,0 +1,22 @@
# Windows Sandbox Security Details
For overall context on sandboxing in Codex, see [sandbox.md](./sandbox.md).
## Implementation Overview
When commands run via `codex sandbox windows …` (or when the CLI/TUI calls into the same crate in-process for sandboxed turns), the launcher configures a restricted Windows token and an allowlist policy scoped to the declared workspace roots. Writes are blocked everywhere except inside those roots (plus `%TEMP%` when workspace-write mode is requested), and common escape vectors such as alternate data streams, UNC paths, and device handles are denied proactively. The CLI also injects stub executables (for example, wrapping `ssh`) ahead of the host PATH so we can intercept dangerous tools before they ever leave the sandbox.
## Known Security Limitations
Running `python windows-sandbox-rs/sandbox_smoketests.py` with full filesystem and network access currently results in **37/41** passing cases. The list below focuses on the four high-value failures numbered #32 and higher in the smoketests (earlier tests are less security-focused).
| Test | Purpose |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ADS write denied (#32) | Ensures alternate data streams cannot be written inside the workspace, preventing tools from hiding payloads in ADS. The sandbox currently allows the write (process returns `rc=0`). |
| protected path case-variation denied (#33) | Confirms that protected directories such as `.git` remain blocked even when attackers use case tricks like `.GiT`. The current allowlist treats `.GiT` as distinct, so the write succeeds. |
| PATH stub bypass denied (#35) | Verifies that a workspace-provided `ssh.bat` shim placed ahead of the host PATH runs instead of the real `ssh`. The sandbox exits early before emitting the shim's `stubbed` output, so we cannot prove the interception works. |
| Start-Process https denied (KNOWN FAIL) (#41) | Validates that read-only runs cannot launch the host's default browser via `Start-Process 'https://...'`. Today the command succeeds (exit code 0) because Explorer handles the ShellExecute request outside the sandbox. The failure is captured by `windows-sandbox-rs/sandbox_smoketests.py` (last case). |
## Want to Help?
If you are a security-minded Windows user, help us get these tests passing! Improved implementations that make these smoke tests pass meaningfully reduce Codex's escape surface. After iterating, rerun `python windows-sandbox-rs/sandbox_smoketests.py` to validate the fixes and help us drive the suite toward 41/41.