🆙 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”Deep Dive into Core Concepts
Section titled “Deep Dive into Core Concepts”1. Approval Policy: The Art of Trust
Section titled “1. Approval Policy: The Art of Trust”Codex is not a rogue AI; it knows when to ask for permission. There are four policies in the config file:
approval_policy = "untrusted" # Default: only ask when running "untrusted" commands| Policy | Meaning | When to use |
untrusted | Ask only when running risky commands | Everyday development (recommended) |
on-failure | Ask whether to lift the sandbox and retry after a command fails | Debugging |
on-request | Let the model decide when it needs elevated privileges | When you’re feeling lazy |
never | Fully automatic, never interrupt | CI/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.
2. Sandbox: A Sandbox Is Not a Litter Box
Section titled “2. Sandbox: A Sandbox Is Not a Litter Box”Codex uses an OS-level sandbox to run commands, preventing it from “accidentally” formatting your hard drive.
sandbox_mode = "read-only" # Default: read-only modeComparison of the three modes:
| Mode | Read files | Write files | Network access | When 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.
3. Model: Choose Your Battle Partner
Section titled “3. Model: Choose Your Battle Partner”model = "gpt-5-codex" # Default modelRecommended common models:
o3- Extremely strong reasoning, great for complex tasks (but slow)gpt-5-codex- Optimized for coding, balanced speed and qualitygpt-5- The all-purpose powerhousegpt-4o- Old but reliable
Adjust reasoning depth:
model = "o3"model_reasoning_effort = "high" # minimal | low | medium | highmodel_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: Connecting Codex to Everything
Section titled “MCP: Connecting Codex to Everything”MCP (Model Context Protocol) is the killer feature in Codex 0.46.0. It lets the AI access external tools, services, and data sources.
What Is MCP?
Section titled “What Is MCP?”Think of MCP as the “USB port for AI”:
- Codex = the computer
- MCP Server = external hard drive, printer, camera…
Configuring MCP Servers: Two Ways
Section titled “Configuring MCP Servers: Two Ways”Option 1: STDIO (local process)
Section titled “Option 1: STDIO (local process)”[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 clientexperimental_use_rmcp_client = true
[mcp_servers.figma]url = "http://127.0.0.1:3845/mcp"# Optional: provide a Bearer Token via environment variablebearer_token_env_var = "FIGMA_TOKEN"OAuth login support:
# Log in to an MCP server that supports OAuthcodex mcp login figma
# Log outcodex mcp logout figmaRecommended Popular MCP Servers
Section titled “Recommended Popular MCP Servers”| Server | Use case | Configuration example |
| Context7 | Access the latest development docs | npx @upstash/context7 |
| Figma | Read and manipulate Figma design files | Streamable HTTP + OAuth |
| Playwright | Automated browser testing | npx @playwright/mcp |
| Chrome DevTools | Debug Chrome | STDIO startup |
| GitHub | Manage PRs and Issues (more powerful than git) | npx @github/github-mcp-server |
| Sentry | Access error logs | Streamable HTTP |
MCP CLI Quick Reference
Section titled “MCP CLI Quick Reference”# Add an MCP servercodex mcp add docs -- npx -y docs-server --port 4000
# List all serverscodex mcp list
# View details for a single server (JSON format)codex mcp get docs --json
# Remove a servercodex mcp remove docs
# OAuth login/logoutcodex mcp login figmacodex mcp logout figmaAdvanced MCP Configuration
Section titled “Advanced MCP Configuration”[mcp_servers.my_server]command = "my-server"args = ["--verbose"]# Optional: override the default startup timeoutstartup_timeout_sec = 20 # Default is 10 secondstool_timeout_sec = 120 # Default is 60 seconds# Optional: temporarily disable without deleting the configenabled = false> Debugging tip: If an MCP server fails to start, check the logs in ~/.codex/log/codex-tui.log.
New in 0.46.0: Streamable HTTP
Section titled “New in 0.46.0: Streamable HTTP”Why Is This a Big Deal?
Section titled “Why Is This a Big Deal?”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
Configuration Examples
Section titled “Configuration Examples”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"codex3. OAuth 2.0 login
experimental_use_rmcp_client = true
[mcp_servers.figma]url = "https://mcp.figma.com"# Note: bearer_token_env_var is not neededThen run:
codex mcp login figma# This will open a browser to complete the OAuth loginTroubleshooting Streamable HTTP Issues
Section titled “Troubleshooting Streamable HTTP Issues”If you run into problems, try these steps:
- Check whether the flag is enabled
grep experimental_use_rmcp_client ~/.codex/config.toml# You should see: experimental_use_rmcp_client = true- Test connectivity
curl -v https://mcp.linear.app/mcp# Make sure the server is reachable- Inspect detailed logs
RUST_LOG=debug codextail -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.
Advanced Configuration Tips
Section titled “Advanced Configuration Tips”1. Profiles: Switch Configurations with One Command
Section titled “1. Profiles: Switch Configurations with One Command”# Default configurationmodel = "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"2. Custom Model Providers
Section titled “2. Custom Model Providers”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 headershttp_headers = { "X-Custom-Header" = "value" }# Headers read from environment variablesenv_http_headers = { "X-User-ID" = "MY_USER_ID" }3. Network Tuning (Important!)
Section titled “3. Network Tuning (Important!)”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 tuningrequest_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.
4. Shell Environment Variable Management
Section titled “4. Shell Environment Variable Management”By default, Codex inherits your full environment, but sometimes you want tighter control:
[shell_environment_policy]# Inheritance policy: all | core | noneinherit = "core" # Only inherit HOME, PATH, USER, etc.# Exclude sensitive variables (wildcards supported)exclude = ["AWS_*", "AZURE_*", "*_SECRET"]# Force-set variablesset = { 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"}5. AGENTS.md: A Little Note for the AI
Section titled “5. AGENTS.md: A Little Note for the AI”Codex automatically reads AGENTS.md from three places, merged by priority:
~/.codex/AGENTS.md- global personal preferences- Project root AGENTS.md - project standards
- 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.jsonExample: 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 notificationsnotifications = true
# Or enable only specific typesnotifications = ["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 python3import jsonimport sysimport 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])7. OpenTelemetry: Log Everything
Section titled “7. OpenTelemetry: Log Everything”[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 startcodex.api_request- API requests (including latency)codex.tool_decision- tool-use decisions (approve/reject)codex.tool_result- tool execution results
Deep Guide to Custom API Configuration
Section titled “Deep Guide to Custom API Configuration”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.
1.1 4All API (super low price!)
Section titled “1.1 4All API (super low price!)”Codex integration with 4All API
1.2 LM Studio (GUI-based local models)
Section titled “1.2 LM Studio (GUI-based local models)”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).
1.3 Anthropic Claude (via proxy)
Section titled “1.3 Anthropic Claude (via proxy)”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 proxyenv_key = "ANTHROPIC_API_KEY"wire_api = "chat"Set up the translation proxy (using LiteLLM):
pip install litellm[proxy]
# Start the proxylitellm --model claude-3-5-sonnet-20241022 --port 80802. Self-Hosted Enterprise APIs
Section titled “2. Self-Hosted Enterprise APIs”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 headershttp_headers = { "X-Department" = "engineering", "X-Cost-Center" = "ai-research"}
# Headers read from environment variablesenv_http_headers = { "X-User-ID" = "EMPLOYEE_ID", "X-Session-Token" = "SSO_TOKEN"}
# Network tuning (internal networks may be more stable)request_max_retries = 2stream_idle_timeout_ms = 180000 # 3 minutesSet environment variables:
export COMPANY_API_KEY="your_internal_key"export EMPLOYEE_ID="E12345"export SSO_TOKEN="sso_token_from_login"codex2.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 parametersquery_params = { version = "2024-01", region = "us-east-1", tier = "premium"}Generated URL: [completions?version=2024-01®ion=us-east-1&tier=premium](https://api.example.com/inference/chat/completions?ve