Skip to content

Commit 14c28b5

Browse files
committed
docs: split the config-related portion of codex-rs/README.md into its own config.md file
1 parent 92957c4 commit 14c28b5

2 files changed

Lines changed: 378 additions & 367 deletions

File tree

codex-rs/README.md

Lines changed: 1 addition & 367 deletions
Original file line numberDiff line numberDiff line change
@@ -23,370 +23,4 @@ This folder is the root of a Cargo workspace. It contains quite a bit of experim
2323

2424
## Config
2525

26-
The CLI can be configured via a file named `config.toml`. By default, configuration is read from `~/.codex/config.toml`, though the `CODEX_HOME` environment variable can be used to specify a directory other than `~/.codex`.
27-
28-
The `config.toml` file supports the following options:
29-
30-
### model
31-
32-
The model that Codex should use.
33-
34-
```toml
35-
model = "o3" # overrides the default of "o4-mini"
36-
```
37-
38-
### model_provider
39-
40-
Codex comes bundled with a number of "model providers" predefined. This config value is a string that indicates which provider to use. You can also define your own providers via `model_providers`.
41-
42-
For example, if you are running ollama with Mistral locally, then you would need to add the following to your config:
43-
44-
```toml
45-
model = "mistral"
46-
model_provider = "ollama"
47-
```
48-
49-
because the following definition for `ollama` is included in Codex:
50-
51-
```toml
52-
[model_providers.ollama]
53-
name = "Ollama"
54-
base_url = "http://localhost:11434/v1"
55-
wire_api = "chat"
56-
```
57-
58-
This option defaults to `"openai"` and the corresponding provider is defined as follows:
59-
60-
```toml
61-
[model_providers.openai]
62-
name = "OpenAI"
63-
base_url = "https://api.openai.com/v1"
64-
env_key = "OPENAI_API_KEY"
65-
wire_api = "responses"
66-
```
67-
68-
### model_providers
69-
70-
This option lets you override and amend the default set of model providers bundled with Codex. This value is a map where the key is the value to use with `model_provider` to select the correspodning provider.
71-
72-
For example, if you wanted to add a provider that uses the OpenAI 4o model via the chat completions API, then you
73-
74-
```toml
75-
# Recall that in TOML, root keys must be listed before tables.
76-
model = "gpt-4o"
77-
model_provider = "openai-chat-completions"
78-
79-
[model_providers.openai-chat-completions]
80-
# Name of the provider that will be displayed in the Codex UI.
81-
name = "OpenAI using Chat Completions"
82-
# The path `/chat/completions` will be amended to this URL to make the POST
83-
# request for the chat completions.
84-
base_url = "https://api.openai.com/v1"
85-
# If `env_key` is set, identifies an environment variable that must be set when
86-
# using Codex with this provider. The value of the environment variable must be
87-
# non-empty and will be used in the `Bearer TOKEN` HTTP header for the POST request.
88-
env_key = "OPENAI_API_KEY"
89-
# valid values for wire_api are "chat" and "responses".
90-
wire_api = "chat"
91-
```
92-
93-
### approval_policy
94-
95-
Determines when the user should be prompted to approve whether Codex can execute a command:
96-
97-
```toml
98-
# This is analogous to --suggest in the TypeScript Codex CLI
99-
approval_policy = "unless-allow-listed"
100-
```
101-
102-
```toml
103-
# If the command fails when run in the sandbox, Codex asks for permission to
104-
# retry the command outside the sandbox.
105-
approval_policy = "on-failure"
106-
```
107-
108-
```toml
109-
# User is never prompted: if the command fails, Codex will automatically try
110-
# something out. Note the `exec` subcommand always uses this mode.
111-
approval_policy = "never"
112-
```
113-
114-
### profiles
115-
116-
A _profile_ is a collection of configuration values that can be set together. Multiple profiles can be defined in `config.toml` and you can specify the one you
117-
want to use at runtime via the `--profile` flag.
118-
119-
Here is an example of a `config.toml` that defines multiple profiles:
120-
121-
```toml
122-
model = "o3"
123-
approval_policy = "unless-allow-listed"
124-
sandbox_permissions = ["disk-full-read-access"]
125-
disable_response_storage = false
126-
127-
# Setting `profile` is equivalent to specifying `--profile o3` on the command
128-
# line, though the `--profile` flag can still be used to override this value.
129-
profile = "o3"
130-
131-
[model_providers.openai-chat-completions]
132-
name = "OpenAI using Chat Completions"
133-
base_url = "https://api.openai.com/v1"
134-
env_key = "OPENAI_API_KEY"
135-
wire_api = "chat"
136-
137-
[profiles.o3]
138-
model = "o3"
139-
model_provider = "openai"
140-
approval_policy = "never"
141-
142-
[profiles.gpt3]
143-
model = "gpt-3.5-turbo"
144-
model_provider = "openai-chat-completions"
145-
146-
[profiles.zdr]
147-
model = "o3"
148-
model_provider = "openai"
149-
approval_policy = "on-failure"
150-
disable_response_storage = true
151-
```
152-
153-
Users can specify config values at multiple levels. Order of precedence is as follows:
154-
155-
1. custom command-line argument, e.g., `--model o3`
156-
2. as part of a profile, where the `--profile` is specified via a CLI (or in the config file itself)
157-
3. as an entry in `config.toml`, e.g., `model = "o3"`
158-
4. the default value that comes with Codex CLI (i.e., Codex CLI defaults to `o4-mini`)
159-
160-
### sandbox_permissions
161-
162-
List of permissions to grant to the sandbox that Codex uses to execute untrusted commands:
163-
164-
```toml
165-
# This is comparable to --full-auto in the TypeScript Codex CLI, though
166-
# specifying `disk-write-platform-global-temp-folder` adds /tmp as a writable
167-
# folder in addition to $TMPDIR.
168-
sandbox_permissions = [
169-
"disk-full-read-access",
170-
"disk-write-platform-user-temp-folder",
171-
"disk-write-platform-global-temp-folder",
172-
"disk-write-cwd",
173-
]
174-
```
175-
176-
To add additional writable folders, use `disk-write-folder`, which takes a parameter (this can be specified multiple times):
177-
178-
```toml
179-
sandbox_permissions = [
180-
# ...
181-
"disk-write-folder=/Users/mbolin/.pyenv/shims",
182-
]
183-
```
184-
185-
### mcp_servers
186-
187-
Defines the list of MCP servers that Codex can consult for tool use. Currently, only servers that are launched by executing a program that communicate over stdio are supported. For servers that use the SSE transport, consider an adapter like [mcp-proxy](https://github.com/sparfenyuk/mcp-proxy).
188-
189-
**Note:** Codex may cache the list of tools and resources from an MCP server so that Codex can include this information in context at startup without spawning all the servers. This is designed to save resources by loading MCP servers lazily.
190-
191-
This config option is comparable to how Claude and Cursor define `mcpServers` in their respective JSON config files, though because Codex uses TOML for its config language, the format is slightly different. For example, the following config in JSON:
192-
193-
```json
194-
{
195-
"mcpServers": {
196-
"server-name": {
197-
"command": "npx",
198-
"args": ["-y", "mcp-server"],
199-
"env": {
200-
"API_KEY": "value"
201-
}
202-
}
203-
}
204-
}
205-
```
206-
207-
Should be represented as follows in `~/.codex/config.toml`:
208-
209-
```toml
210-
# IMPORTANT: the top-level key is `mcp_servers` rather than `mcpServers`.
211-
[mcp_servers.server-name]
212-
command = "npx"
213-
args = ["-y", "mcp-server"]
214-
env = { "API_KEY" = "value" }
215-
```
216-
217-
### disable_response_storage
218-
219-
Currently, customers whose accounts are set to use Zero Data Retention (ZDR) must set `disable_response_storage` to `true` so that Codex uses an alternative to the Responses API that works with ZDR:
220-
221-
```toml
222-
disable_response_storage = true
223-
```
224-
225-
### shell_environment_policy
226-
227-
Codex spawns subprocesses (e.g. when executing a `local_shell` tool-call suggested by the assistant). By default it passes **only a minimal core subset** of your environment to those subprocesses to avoid leaking credentials. You can tune this behavior via the **`shell_environment_policy`** block in
228-
`config.toml`:
229-
230-
```toml
231-
[shell_environment_policy]
232-
# inherit can be "core" (default), "all", or "none"
233-
inherit = "core"
234-
# set to true to *skip* the filter for `"*KEY*"` and `"*TOKEN*"`
235-
ignore_default_excludes = false
236-
# exclude patterns (case-insensitive globs)
237-
exclude = ["AWS_*", "AZURE_*"]
238-
# force-set / override values
239-
set = { CI = "1" }
240-
# if provided, *only* vars matching these patterns are kept
241-
include_only = ["PATH", "HOME"]
242-
```
243-
244-
| Field | Type | Default | Description |
245-
| ------------------------- | -------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
246-
| `inherit` | string | `core` | Starting template for the environment:<br>`core` (`HOME`, `PATH`, `USER`, …), `all` (clone full parent env), or `none` (start empty). |
247-
| `ignore_default_excludes` | boolean | `false` | When `false`, Codex removes any var whose **name** contains `KEY`, `SECRET`, or `TOKEN` (case-insensitive) before other rules run. |
248-
| `exclude` | array&lt;string&gt; | `[]` | Case-insensitive glob patterns to drop after the default filter.<br>Examples: `"AWS_*"`, `"AZURE_*"`. |
249-
| `set` | table&lt;string,string&gt; | `{}` | Explicit key/value overrides or additions – always win over inherited values. |
250-
| `include_only` | array&lt;string&gt; | `[]` | If non-empty, a whitelist of patterns; only variables that match _one_ pattern survive the final step. (Generally used with `inherit = "all"`.) |
251-
252-
The patterns are **glob style**, not full regular expressions: `*` matches any
253-
number of characters, `?` matches exactly one, and character classes like
254-
`[A-Z]`/`[^0-9]` are supported. Matching is always **case-insensitive**. This
255-
syntax is documented in code as `EnvironmentVariablePattern` (see
256-
`core/src/config_types.rs`).
257-
258-
If you just need a clean slate with a few custom entries you can write:
259-
260-
```toml
261-
[shell_environment_policy]
262-
inherit = "none"
263-
set = { PATH = "/usr/bin", MY_FLAG = "1" }
264-
```
265-
266-
Currently, `CODEX_SANDBOX_NETWORK_DISABLED=1` is also added to the environment, assuming network is disabled. This is not configurable.
267-
268-
### notify
269-
270-
Specify a program that will be executed to get notified about events generated by Codex. Note that the program will receive the notification argument as a string of JSON, e.g.:
271-
272-
```json
273-
{
274-
"type": "agent-turn-complete",
275-
"turn-id": "12345",
276-
"input-messages": ["Rename `foo` to `bar` and update the callsites."],
277-
"last-assistant-message": "Rename complete and verified `cargo build` succeeds."
278-
}
279-
```
280-
281-
The `"type"` property will always be set. Currently, `"agent-turn-complete"` is the only notification type that is supported.
282-
283-
As an example, here is a Python script that parses the JSON and decides whether to show a desktop push notification using [terminal-notifier](https://github.com/julienXX/terminal-notifier) on macOS:
284-
285-
```python
286-
#!/usr/bin/env python3
287-
288-
import json
289-
import subprocess
290-
import sys
291-
292-
293-
def main() -> int:
294-
if len(sys.argv) != 2:
295-
print("Usage: notify.py <NOTIFICATION_JSON>")
296-
return 1
297-
298-
try:
299-
notification = json.loads(sys.argv[1])
300-
except json.JSONDecodeError:
301-
return 1
302-
303-
match notification_type := notification.get("type"):
304-
case "agent-turn-complete":
305-
assistant_message = notification.get("last-assistant-message")
306-
if assistant_message:
307-
title = f"Codex: {assistant_message}"
308-
else:
309-
title = "Codex: Turn Complete!"
310-
input_messages = notification.get("input_messages", [])
311-
message = " ".join(input_messages)
312-
title += message
313-
case _:
314-
print(f"not sending a push notification for: {notification_type}")
315-
return 0
316-
317-
subprocess.check_output(
318-
[
319-
"terminal-notifier",
320-
"-title",
321-
title,
322-
"-message",
323-
message,
324-
"-group",
325-
"codex",
326-
"-ignoreDnD",
327-
"-activate",
328-
"com.googlecode.iterm2",
329-
]
330-
)
331-
332-
return 0
333-
334-
335-
if __name__ == "__main__":
336-
sys.exit(main())
337-
```
338-
339-
To have Codex use this script for notifications, you would configure it via `notify` in `~/.codex/config.toml` using the appropriate path to `notify.py` on your computer:
340-
341-
```toml
342-
notify = ["python3", "/Users/mbolin/.codex/notify.py"]
343-
```
344-
345-
### history
346-
347-
By default, Codex CLI records messages sent to the model in `$CODEX_HOME/history.jsonl`. Note that on UNIX, the file permissions are set to `o600`, so it should only be readable and writable by the owner.
348-
349-
To disable this behavior, configure `[history]` as follows:
350-
351-
```toml
352-
[history]
353-
persistence = "none" # "save-all" is the default value
354-
```
355-
356-
### file_opener
357-
358-
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.
359-
360-
For example, if the model output includes a reference such as `【F:/home/user/project/main.py†L42-L50】`, then this would be rewritten to link to the URI `vscode://file/home/user/project/main.py:42`.
361-
362-
Note this is **not** a general editor setting (like `$EDITOR`), as it only accepts a fixed set of values:
363-
364-
- `"vscode"` (default)
365-
- `"vscode-insiders"`
366-
- `"windsurf"`
367-
- `"cursor"`
368-
- `"none"` to explicitly disable this feature
369-
370-
Currently, `"vscode"` is the default, though Codex does not verify VS Code is installed. As such, `file_opener` may default to `"none"` or something else in the future.
371-
372-
### project_doc_max_bytes
373-
374-
Maximum number of bytes to read from an `AGENTS.md` file to include in the instructions sent with the first turn of a session. Defaults to 32 KiB.
375-
376-
### tui
377-
378-
Options that are specific to the TUI.
379-
380-
```toml
381-
[tui]
382-
# This will make it so that Codex does not try to process mouse events, which
383-
# means your Terminal's native drag-to-text to text selection and copy/paste
384-
# should work. The tradeoff is that Codex will not receive any mouse events, so
385-
# it will not be possible to use the mouse to scroll conversation history.
386-
#
387-
# Note that most terminals support holding down a modifier key when using the
388-
# mouse to support text selection. For example, even if Codex mouse capture is
389-
# enabled (i.e., this is set to `false`), you can still hold down alt while
390-
# dragging the mouse to select text.
391-
disable_mouse_capture = true # defaults to `false`
392-
```
26+
Codex supports a rich set of configuration options. See [`config.md`](./config.md) for details.

0 commit comments

Comments
 (0)