Skip to content

🆙 Codex 0.46.0 Advanced Quickstart Tutorial

🆙 Codex 0.46.0 Advanced Getting Started Guide

Section titled “🆙 Codex 0.46.0 Advanced Getting Started Guide”

Codex is not a rogue AI; it knows when to ask for permission. There are four policies in the config file:

~/.codex/config.toml
approval_policy = "untrusted" # Default: only ask when running "untrusted" commands
PolicyMeaningWhen to use
untrustedAsk only when running risky commandsEveryday development (recommended)
on-failureAsk whether to lift the sandbox and retry after a command failsDebugging
on-requestLet the model decide when it needs elevated privilegesWhen you’re feeling lazy
neverFully automatic, never interruptCI/CD, or when you’re feeling brave

> A funny note: never mode is like handing an AI a credit card. It’ll be thrilled; your server may not be.

Codex uses an OS-level sandbox to run commands, preventing it from “accidentally” formatting your hard drive.

sandbox_mode = "read-only" # Default: read-only mode

Comparison of the three modes:

ModeRead filesWrite filesNetwork accessWhen to use
read-only:check_mark_button::cross_mark::cross_mark:Reading and analyzing code
workspace-write:check_mark_button::check_mark_button: (current directory):cross_mark:*Normal development
danger-full-access:check_mark_button::check_mark_button: (entire file system):check_mark_button:Go wild in a Docker container

*Network access can be enabled via configuration

Advanced sandbox configuration:

sandbox_mode = "workspace-write"
[sandbox_workspace_write]
# Allow writes to additional directories (such as a Python virtual environment)
writable_roots = ["/Users/you/.pyenv/shims"]
# Enable network access (use with caution!)
network_access = true
# Exclude the /tmp directory (it is writable by default)
exclude_slash_tmp = false

> Security note: On macOS and Linux, the .git/ folder is read-only by default to prevent AI from messing up your Git history.

model = "gpt-5-codex" # Default model

Recommended common models:

  • o3 - Extremely strong reasoning, great for complex tasks (but slow)
  • gpt-5-codex - Optimized for coding, balanced speed and quality
  • gpt-5 - The all-purpose powerhouse
  • gpt-4o - Old but reliable

Adjust reasoning depth:

model = "o3"
model_reasoning_effort = "high" # minimal | low | medium | high
model_reasoning_summary = "detailed" # auto | concise | detailed | none

> Easter egg: model_reasoning_effort = "high" is like giving the AI three shots of espresso. It thinks deeper, but it also costs more.


MCP (Model Context Protocol) is the killer feature in Codex 0.46.0. It lets the AI access external tools, services, and data sources.

Think of MCP as the “USB port for AI”:

  • Codex = the computer
  • MCP Server = external hard drive, printer, camera…
[mcp_servers.docs]
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/docs"]
env = { API_KEY = "sk-xxxxx" }

Real-world example: Connecting Context7 (a developer docs powerhouse)

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7"]
env = { UPSTASH_API_KEY = "your_key_here" }

Option 2: Streamable HTTP (new in 0.46.0!)

Section titled “Option 2: Streamable HTTP (new in 0.46.0!)”

This is a major update in 0.46.0, allowing connection to remote MCP servers.

# First enable the experimental RMCP client
experimental_use_rmcp_client = true
[mcp_servers.figma]
url = "http://127.0.0.1:3845/mcp"
# Optional: provide a Bearer Token via environment variable
bearer_token_env_var = "FIGMA_TOKEN"

OAuth login support:

# Log in to an MCP server that supports OAuth
codex mcp login figma
# Log out
codex mcp logout figma
ServerUse caseConfiguration example
Context7Access the latest development docsnpx @upstash/context7
FigmaRead and manipulate Figma design filesStreamable HTTP + OAuth
PlaywrightAutomated browser testingnpx @playwright/mcp
Chrome DevToolsDebug ChromeSTDIO startup
GitHubManage PRs and Issues (more powerful than git)npx @github/github-mcp-server
SentryAccess error logsStreamable HTTP
# Add an MCP server
codex mcp add docs -- npx -y docs-server --port 4000
# List all servers
codex mcp list
# View details for a single server (JSON format)
codex mcp get docs --json
# Remove a server
codex mcp remove docs
# OAuth login/logout
codex mcp login figma
codex mcp logout figma
[mcp_servers.my_server]
command = "my-server"
args = ["--verbose"]
# Optional: override the default startup timeout
startup_timeout_sec = 20 # Default is 10 seconds
tool_timeout_sec = 120 # Default is 60 seconds
# Optional: temporarily disable without deleting the config
enabled = false

> Debugging tip: If an MCP server fails to start, check the logs in ~/.codex/log/codex-tui.log.


Previously, MCP could only connect to local processes (STDIO). Now it can connect to any HTTP server. That means:

  • :check_mark_button: Connect to internal company APIs
  • :check_mark_button: Connect to cloud services such as Linear and Figma
  • :check_mark_button: Support OAuth 2.0 login
  • :check_mark_button: Authenticate with Bearer Tokens

1. The simplest HTTP MCP

experimental_use_rmcp_client = true
[mcp_servers.linear]
url = "https://mcp.linear.app/mcp"

2. With Bearer Token authentication

experimental_use_rmcp_client = true
[mcp_servers.internal_api]
url = "https://api.mycompany.com/mcp"
bearer_token_env_var = "INTERNAL_API_TOKEN"

Set the environment variable in your shell:

export INTERNAL_API_TOKEN="your_secret_token"
codex

3. OAuth 2.0 login

experimental_use_rmcp_client = true
[mcp_servers.figma]
url = "https://mcp.figma.com"
# Note: bearer_token_env_var is not needed

Then run:

codex mcp login figma
# This will open a browser to complete the OAuth login

If you run into problems, try these steps:

  1. Check whether the flag is enabled
grep experimental_use_rmcp_client ~/.codex/config.toml
# You should see: experimental_use_rmcp_client = true
  1. Test connectivity
curl -v https://mcp.linear.app/mcp
# Make sure the server is reachable
  1. Inspect detailed logs
RUST_LOG=debug codex
tail -f ~/.codex/log/codex-tui.log

> Known issue (see #4707): On Windows, some MCP servers may report a missing field command error. The team is working on a fix.


1. Profiles: Switch Configurations with One Command

Section titled “1. Profiles: Switch Configurations with One Command”
# Default configuration
model = "gpt-5-codex"
approval_policy = "untrusted"
# Profile 1: Focus mode (use o3, high reasoning)
[profiles.focus]
model = "o3"
model_reasoning_effort = "high"
approval_policy = "never"
sandbox_mode = "workspace-write"
# Profile 2: Safe mode (read-only + approval required)
[profiles.safe]
model = "gpt-4o"
approval_policy = "untrusted"
sandbox_mode = "read-only"
# Profile 3: Rapid prototyping (fully automatic)
[profiles.prototype]
model = "gpt-5-codex"
approval_policy = "never"
sandbox_mode = "workspace-write"

Usage:

codex --profile focus "Optimize this algorithm"
codex --profile safe "Review this security vulnerability"
codex --profile prototype "Create a TODO app"

Example 1: Local Ollama

model = "mistral"
model_provider = "ollama"
[model_providers.ollama]
name = "Ollama"
base_url = "http://localhost:11434/v1"
wire_api = "chat"

Example 2: Azure OpenAI

model = "gpt-4o"
model_provider = "azure"
[model_providers.azure]
name = "Azure"
base_url = "https://YOUR_PROJECT.openai.azure.com/openai"
env_key = "AZURE_OPENAI_API_KEY"
query_params = { api-version = "2025-04-01-preview" }
wire_api = "responses"

Example 3: Third-party API (such as Mistral AI)

model = "mistral-large"
model_provider = "mistral"
[model_providers.mistral]
name = "Mistral"
base_url = "https://api.mistral.ai/v1"
env_key = "MISTRAL_API_KEY"
wire_api = "chat"
# Custom HTTP headers
http_headers = { "X-Custom-Header" = "value" }
# Headers read from environment variables
env_http_headers = { "X-User-ID" = "MY_USER_ID" }

Each model provider can be configured with its own network settings:

[model_providers.openai]
name = "OpenAI"
base_url = "https://api.4allapi.com/v1"
env_key = "OPENAI_API_KEY"
# Network tuning
request_max_retries = 4 # Number of retries (default 4)
stream_max_retries = 10 # Number of reconnect attempts after a stream disconnects (default 5)
stream_idle_timeout_ms = 600000 # Idle timeout of 10 minutes (default 5 minutes)

> Use case: In unstable network environments, such as café Wi‑Fi, increase retry counts and timeouts.

By default, Codex inherits your full environment, but sometimes you want tighter control:

[shell_environment_policy]
# Inheritance policy: all | core | none
inherit = "core" # Only inherit HOME, PATH, USER, etc.
# Exclude sensitive variables (wildcards supported)
exclude = ["AWS_*", "AZURE_*", "*_SECRET"]
# Force-set variables
set = { CI = "1", NODE_ENV = "test" }
# Whitelist mode (if set, only these are kept)
include_only = ["PATH", "HOME", "USER"]

Real-world case: CI/CD environment

[shell_environment_policy]
inherit = "none"
set = {
PATH = "/usr/bin:/bin",
CI = "true",
NODE_ENV = "production"
}

Codex automatically reads AGENTS.md from three places, merged by priority:

  1. ~/.codex/AGENTS.md - global personal preferences
  2. Project root AGENTS.md - project standards
  3. Current directory AGENTS.md - local instructions

Example: /.codex/AGENTS.md** (personal style)**

# My coding style
## General rules
- Use TypeScript instead of JavaScript
- Use camelCase for function names
- Use Jest for tests, not other frameworks
## Python projects
- Use Black for formatting
- Write tests with pytest
- Include full type annotations
## Do not
- Do not install dependencies automatically; ask me first
- Do not change the version number in package.json

Example: Project root AGENTS.md (team standards)

# Project Guide
## Architecture
- Backend: Django + PostgreSQL
- Frontend: React + TailwindCSS
- API: RESTful, with /api/v1/ as the version prefix
## Code review checklist
- [ ] All APIs have unit tests
- [ ] Database migration files have been generated
- [ ] README has been updated
## Special conventions
- Use ISO 8601 for all dates
- Error code ranges: 4000-4999 client errors, 5000-5999 server errors

> Pro Tip: You can configure fallback filenames, for example if your company uses CLAUDE.md: > > TOML > project_doc_fallback_filenames = ["CLAUDE.md", ".agentrules"] >

6. Notification System: Let Codex Tell You When It’s Done

Section titled “6. Notification System: Let Codex Tell You When It’s Done”

Option 1: Built-in TUI notifications (easy)

[tui]
# Enable all notifications
notifications = true
# Or enable only specific types
notifications = ["agent-turn-complete", "approval-requested"]

Supported terminals: iTerm2, Ghostty, WezTerm (macOS Terminal and VS Code terminal are not supported).

Option 2: External script notifications (advanced)

notify = ["python3", "/Users/you/.codex/notify.py"]

Create notify.py:

#!/usr/bin/env python3
import json
import sys
import subprocess
notification = json.loads(sys.argv[1])
if notification["type"] == "agent-turn-complete":
message = notification.get("last-assistant-message", "Task completed!")
# macOS notification
subprocess.run([
"osascript", "-e",
f'display notification "{message}" with title "Codex"'
])
# Or use terminal-notifier
# subprocess.run(["terminal-notifier", "-title", "Codex", "-message", message])
[otel]
environment = "production"
exporter = { otlp-http = {
endpoint = "https://otel.mycompany.com/v1/logs",
protocol = "binary",
headers = { "x-api-key" = "${OTEL_TOKEN}" }
}}
log_user_prompt = false # Do not log user input (privacy protection)

Events that will be logged:

  • codex.conversation_starts - conversation start
  • codex.api_request - API requests (including latency)
  • codex.tool_decision - tool-use decisions (approve/reject)
  • codex.tool_result - tool execution results

One of Codex’s strengths is that it not only supports OpenAI, but can also connect to almost any compatible API provider. This section dives into various custom API scenarios.

1. Providers Compatible with the OpenAI API

Section titled “1. Providers Compatible with the OpenAI API”

As long as the API follows OpenAI’s interface spec, it can be configured directly.

Codex integration with 4All API

model = "lmstudio-community/Meta-Llama-3-8B-Instruct-GGUF"
model_provider = "lmstudio"
[model_providers.lmstudio]
name = "LM Studio"
base_url = "http://localhost:1234/v1"
wire_api = "chat"

> Tip: Enable the API Server in LM Studio (Settings → Developer → Enable API Server).

Codex does not natively support the Anthropic API, but you can use a translation proxy:

model = "claude-3-5-sonnet-20241022"
model_provider = "anthropic-proxy"
[model_providers.anthropic-proxy]
name = "Anthropic Claude (via Proxy)"
base_url = "https://localhost:8080/v1" # Run the translation proxy
env_key = "ANTHROPIC_API_KEY"
wire_api = "chat"

Set up the translation proxy (using LiteLLM):

pip install litellm[proxy]
# Start the proxy
litellm --model claude-3-5-sonnet-20241022 --port 8080

2.1 Internal network API (with custom authentication)

Section titled “2.1 Internal network API (with custom authentication)”
model = "company-gpt-4"
model_provider = "internal"
[model_providers.internal]
name = "Company Internal API"
base_url = "https://ai.company.internal/v1"
env_key = "COMPANY_API_KEY"
wire_api = "chat"
# Custom HTTP headers
http_headers = {
"X-Department" = "engineering",
"X-Cost-Center" = "ai-research"
}
# Headers read from environment variables
env_http_headers = {
"X-User-ID" = "EMPLOYEE_ID",
"X-Session-Token" = "SSO_TOKEN"
}
# Network tuning (internal networks may be more stable)
request_max_retries = 2
stream_idle_timeout_ms = 180000 # 3 minutes

Set environment variables:

export COMPANY_API_KEY="your_internal_key"
export EMPLOYEE_ID="E12345"
export SSO_TOKEN="sso_token_from_login"
codex

2.2 APIs that require additional query parameters

Section titled “2.2 APIs that require additional query parameters”
[model_providers.custom_with_params]
name = "Custom API with Query Params"
base_url = "https://api.example.com/inference"
env_key = "CUSTOM_API_KEY"
wire_api = "chat"
# Add query parameters
query_params = {
version = "2024-01",
region = "us-east-1",
tier = "premium"
}

Generated URL: [completions?version=2024-01&region=us-east-1&tier=premium](https://api.example.com/inference/chat/completions?ve