Codex CLI: OpenAI’s Open Agent Harness — Installation, Commands, and CI Integration
Matt MickiewiczPublished inAI·Programming·
August 20, 2026
The AI briefing for Developers
Stay up to date with AI tools, model releases, and developer workflows that matter.
Weekly. Free. One click to leave.
SitePoint Premium
Stay Relevant and Grow Your Career in Tech
- Premium Results
- Publish articles on SitePoint
- Daily curated jobs
- Learning Paths
- Discounts to dev tools
7 Day Free Trial. Cancel Anytime.
Codex CLI is OpenAI’s open-I coding agents interactively, programmatically, and inside CI pipelines. Released under the Apache 2.0 license and built on Node.js, it adds non-interactive execution and HTTP embedding on top of the chat-mode interface that dominates most coverage
Recent releases introduced the codex exec subcommand and the Codex app-server module, two capabilities that turn this tool from a conversational novelty into a scriptable, embeddable <a href="https://tooltechblog.com/if-waymo-cars-are-level-4-automation-what-does-it-take-to-be-a-level-5/” title=”If Waymo cars are Level 4 automation, what does it take to be a Level 5?”>automation engine. This article covers every installation path, core command pattern, and CI integration step with runnable examples.
Note: The features described below, including
codex exec,codex serve, and the programmatic SDK, reflect capabilities announced for recent releases. Before following any example, confirm that your installed version supports these features by runningcodex --helpand checking the Codex CLI changelog. Per-section version disclaimers are omitted where this top-level check already applies.
Table of Contents
What Is Codex CLI and Why It Isn’t Just a Chat Interface
The Three Runtime Modes: Interactive CLI, Programmatic SDK, App-Server
Codex CLI exposes three distinct runtime modes, each suited to a different stage of adoption.
Launch codex in a terminal and you get Interactive CLI, the default mode. A prompt-driven session lets developers issue natural-language instructions, review proposed changes, and approve or reject edits one at a time. Most tutorials demonstrate this mode. It works well for exploratory tasks and pair-programming workflows.
Programmatic SDK exposes the same agent logic as a Node.js module. Import the agent class from the @openai/codex package, instantiate it, and call methods directly in application code. Pick this mode when Codex needs orchestration by another service or integration into a larger automation script.
Running codex serve starts the App-Server, the newest surface. It accepts task payloads on an /exec endpoint over HTTP. Products can embed Codex behind their own UIs or API gateways without shelling out to a CLI process.
Because the project ships under the Apache 2.0 license, all three modes are fork-friendly and commercially embeddable with no copyleft obligations.
What Changed in Recent Releases
Recent releases introduced three significant changes:
codex execenables non-interactive, one-shot task execution with deterministic exit codes, making it suitable for scripts, pipelines, and any context where no human sits at the terminal.- The app-server module exposes the agent over HTTP, enabling direct embedding in web applications and backend services.
- The sandbox now enforces stricter isolation (for example, restricting mount points and blocking additional syscalls), reducing unintended filesystem writes during
auto-editandfull-autoruns.
Consult the changelog for exact version numbers and release dates.
Installation: Every Supported Method
npm (Global Install)
The fastest path to a working binary on any platform with Node.js 18 or later. First, confirm the package is published:
npm show @openai/codex versionnpminstall-g @openai/codex@0.1.0codex --versionThe global install places the codex binary on the system PATH. Node 18 is the minimum supported runtime (check the engines field in the package’s package.json for the authoritative constraint); Node 20 LTS is recommended for best compatibility with the sandbox subsystem.
Homebrew (macOS / Linux)
For developers who prefer Homebrew for CLI tool management:
brew tap openai/tapbrew install openai/tap/codexcodex --versionIf the tap is unavailable: If
brew tap openai/tapreturns an error, the Homebrew formula may not yet be published. Use the npm method above instead.
On Apple Silicon Macs, Homebrew installs the native arm64 build when available.
Building from
Contributors or anyone who needs to patch the agent locally can build from the GitHub repository:
git clone https://github.com/openai/codex.gitcd codexnpm cinpm run buildnpmlinknpm ci performs a clean install of exact dependency versions from the lockfile. npm run build compiles the TypeScripte_modules, making codex available system-wide. After linking, run codex –version to confirm the build matches the expected commit
nvm / volta users:
npm linkinstalls into the active Node version’s global directory. If you switch Node versions, re-runnpm linkto restore the symlink.
Setting Your API Key
Codex CLI requires an OpenAI API key. The most portable approach is exporting the key in a shell configuration file:
exportOPENAI_API_KEY="sk-proj-your-key-here"Alternatively, the built-in auth shortcut stores the key in Codex CLI’s own config directory:
codex authFor project-scoped usage, placing OPENAI_API_KEY=sk-proj-... in a .env file may also work if your version supports it. Ensure .env is in .gitignore before using this approach; never commit API keys to version control. Check your version’s documentation or run codex --help to confirm whether .env auto-loading is supported; otherwise, export the key explicitly in your shell.
Interactive Mode: Core Commands and Workflow
Starting a Session
A bare invocation opens an interactive session using the default model:
codexTo select a specific model, pass the --model flag:
codex --model o3The prompt UI displays the active model, current working directory, and approval policy. Type a natural-language instruction to start the agent loop.
Essential In-Session Commands
Once inside an interactive session, these slash commands control the workflow:
| Command | Description |
|---|---|
| /edit | Opens the proposed file change in the system editor |
| /diff | Displays a unified diff of all pending changes |
| /approve | Accepts the current set of proposed changes |
| /undo | Reverts the most recent approved change |
| /context | Adds a file or directory to the agent’s context window |
| /quit | Ends the interactive session without applying changes |
These commands map to the agent’s internal state machine. /diff is particularly useful before /approve to verify that the model’s proposed edits match expectations. /undo reverts the most recent agent-applied change on git-tracked files. It requires a clean working tree for the affected files and a git repository; newly created files may not be fully reverted. Type /help in a session to confirm the full list of available commands for your version.
Approval Policies: suggest, auto-edit, full-auto
The approval policy controls how much you must approve before the agent acts:
codex --approval-policy auto-edit "Refactor utils.ts to use ES modules"suggest (default) shows proposed changes but applies nothing without explicit /approve commands. This is the safest mode for unfamiliar codebases. auto-edit lets the agent write file changes automatically but still requires approval before executing any shell commands; the sandbox prevents writes outside the working directory. In contrast, full-auto grants permission to both edit files and run shell commands without prompts. Sandbox guardrails restrict network access and filesystem writes to the project root. Consult the sandbox documentation for the full list of blocked system calls under each policy. This policy targets CI and trusted automation contexts where no human is present to approve each step.
codex execruns a single task to completion and exits, making it suitable for scripts, cron jobs, and pipeline steps.
codex exec: One-Shot Execution for Scripts and Automation
Anatomy of a codex exec Command
codex exec"Add JSDoc comments to every exported function in src/"Exit codes: Verify exact exit code semantics with
codex exec --helpfor your installed version, as codes may differ across releases. Some versions may use exit code 2 for timeout; confirm before branching CI logic on specific codes.
codex exec inherits the working directory, API key, and model settings from the environment. Unlike interactive mode, there is no prompt UI; the task description is the sole input.
Useful Flags for Deterministic Runs
For reproducible automation, compose the following flags into a single invocation:
codex exec--approval-policy full-auto --max-turns 20--timeout300--sandbox strict "Generate unit tests for lib/parser.ts"--approval-policy full-auto eliminates interactive prompts. --max-turns 20 caps the number of agent reasoning-action cycles, preventing runaway loops. --timeout 300 sets a hard wall-clock limit of 300 seconds. --sandbox strict enforces the tightest isolation, blocking all network access and restricting filesystem writes to the current directory tree.
These flags fix exit codes, turn counts, and timeouts. Model output still varies across runs because of sampling temperature and non-deterministic decoding, so treat text output as advisory and branch CI logic only on exit codes.
Chaining codex exec with Shell Pipelines
codex exec composes with standard Unix tooling. Piping a file list through xargs distributes work across multiple agent invocations:
gitdiff-z --name-only HEAD~1 -- 2>/dev/null |xargs-0-I{} codex exec--approval-policy full-auto --output-format json "Review {} for potential bugs and suggest fixes"git diff --name-only HEAD~1fails on repositories with only one commit. Add2>/dev/nullor guard with a commit-count check.- The example above uses null-delimited output (
git diff -z) paired withxargs -0to correctly handle filenames containing spaces or special characters. Always keep these two flags in sync. - Avoid adding
-P(parallel execution) toxargswithout also setting--max-turnsand monitoring rate limits. Each parallel invocation consumes separate API quota and can exhaust rate limits or generate unexpected costs.
The --output-format json flag (if supported) structures the agent’s output as a JSON object per invocation, with fields for the task, files modified, and a summary. This makes downstream processing straightforward, whether that means piping into jq for filtering, appending to a JSONL log, or posting results to a webhook.
CI Pipeline Integration: GitHub Actions, GitLab CI, and Generic Runners
GitHub Actions Workflow
The following workflow installs Codex CLI, runs codex exec against files changed in a pull request, and posts a summary comment:
name: Codex PR Reviewon:pull_request:types:[opened, synchronize]permissions:contents: readissues: writepull-requests: writejobs:codex-review:runs-on: ubuntu-lateststeps:-uses: actions/checkout@v4with:fetch-depth:0-uses: actions/setup-node@v4with:node-version:'20'-name: Install Codex CLIrun: npm install -g @openai/codex@0.1.0-name: Run Codex Reviewenv:OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}run:|# Write changed files to a temp filegit diff --name-only origin/${{ github.base_ref }}...HEAD -- > /tmp/changed_files.txtecho "" > review-output.jsonlwhile IFS= read -r file; do[-z "$file" ]&& continueif ![[ "$file" =~ ^[a-zA-Z0-9_./-]+$ ]]; thenecho "Skipping file with unsafe characters: $file" >&2continueficodex exec --approval-policy full-auto --max-turns 15 --timeout 240 --output-format json "Review this file for bugs and style issues: $file" | tr -d '' >> review-output.jsonlecho "" >> review-output.jsonldone < /tmp/changed_files.txt-name: Post Review Commentuses: actions/github-script@v7with:script:|const fs = require('fs');const path = 'review-output.jsonl';let body = '';if (!fs.existsSync(path)|| fs.statSync(path).size === 0) {body += '_No files reviewed (empty diff or no output)._';} else {const lines = fs.readFileSync(path, 'utf8').split('').filter(l => l.trim().length > 0);const preview = lines.slice(0, 20).join('');body += '```json' + preview + '```';if (lines.length > 20) body += `_…and ${lines.length -20} more records._`;}await github.rest.issues.createComment({owner: context.repo.owner,repo: context.repo.repo,issue_number: context.issue.number,body,});Security note: The workflow validates filenames against a strict character allowlist before interpolation. This prevents shell injection from crafted filenames in external PRs. The output uses JSONL (one JSON object per line) so that each record is independently parseable.
Store OPENAI_API_KEY in the repository’s Actions secrets. The fetch-depth: 0 ensures the full git history is available for the diff.
GitLab CI Job
This stage runs codex exec for automated documentation generation on merges to main:
codex-docs:stage: post-mergeimage: node:20-bullseye-slimrules:-if:'$CI_COMMIT_BRANCH == "main"'script:- npm install -g @openai/codex@0.1.0- codex exec --approval-policy full-auto --max-turns 10 --timeout 180"Generate or update README documentation for all modules in src/"- git config user.name "Codex Bot"- git config user.email "${CODEX_BOT_EMAIL:-codex@ci.local}"- git add -A- git diff --cached --quiet && echo "No changes to commit." && exit 0-git commit -m "docs: auto-update via Codex CLI"- git config credential.helper store-|printf 'https://oauth2:%s@%s' "${CI_PUSH_TOKEN}" "${CI_SERVER_HOST}" > ~/.git-credentials- git push origin HEAD:docs/codex-auto-updatevariables:OPENAI_API_KEY: $OPENAI_API_KEYCODEX_BOT_EMAIL: $CODEX_BOT_EMAIL- Define
OPENAI_API_KEYas a masked, protected CI/CD variable in GitLab project settings under Settings → CI/CD → Variables. - Define
CI_PUSH_TOKENwithwrite_repositoryscope (also masked and protected). - This job pushes to a
docs/codex-auto-updatebranch. Open a merge request from that branch to preserve branch protection and code review workflows. - Add a concurrency lock or resource group to prevent race conditions from concurrent pipeline runs.
The git diff --cached --quiet guard prevents empty commits when no documentation changes are generated. The credential store approach keeps the push token out of the git remote URL, process list, and runner debug logs.
Generic CI (Jenkins, CircleCI, etc.)
A portable shell script works on any runner that provides Node.js:
#!/usr/bin/env bashset-euo pipefailSCRIPT_NAME="$(basename"$0")"npminstall-g @openai/codex@0.1.0if[-z"${OPENAI_API_KEY:-}"];thenecho"${SCRIPT_NAME}: OPENAI_API_KEY is not set. Add it to CI secrets.">&2exit1fiEXIT_CODE=0codex exec--approval-policy full-auto --max-turns 10--timeout120"Lint all TypeScript files in src/ and fix any issues in place"||EXIT_CODE=$?case"$EXIT_CODE"in0)echo"Codex lint completed successfully.";;2)echo"${SCRIPT_NAME}: Codex lint timed out.">&2;exit1;;*)echo"${SCRIPT_NAME}: Codex lint failed (exit ${EXIT_CODE}).">&2;exit"$EXIT_CODE";;esacMake the script executable with chmod +x ci/codex-lint.sh and invoke it from any CI configuration.
Cost and Rate-Limit Considerations
Every codex exec invocation consumes API tokens proportional to the context window and the number of agent turns. In CI, unbounded runs can generate surprising bills. The --max-turns flag caps agent loop iterations, but input context size (files passed to the agent) can dominate token costs. Control both.
Model selection also affects cost. Use a smaller model for routine linting or documentation tasks and reserve larger models for complex refactoring to keep token spend proportional to task complexity. Run one representative task, then check the OpenAI dashboard to establish a per-run baseline before scaling to more repositories. Refer to the OpenAI pricing page for current per-token rates.
Programmatic SDK and App-Server Embedding (Quick Start)
Using the Node.js SDK
The same @openai/codex package exports a programmatic API:
import{CodexAgent}from"@openai/codex";asyncfunctionrunAgent(){const agent =newCodexAgent({apiKey: process.env.OPENAI_API_KEY,approvalPolicy:"full-auto",maxTurns:10,});try{const result =await agent.exec("Add input validation to all route handlers in src/routes/");console.log(result.summary);console.log("Files modified:", result.filesModified);}catch(err){console.error("Codex agent error:", err.message);throw err;}}runAgent().catch(()=>{process.exitCode=1;});API verification: The class name (CodexAgent), method names, and result field names (result.summary, result.filesModified) reflect the expected API. Run the verification comment at the top of the snippet to confirm the actual exports in your installed version. This file must be saved as .mjs or your package.json must include "type": "module" for top-level await and ESM import to work.
The exec method returns a promise that resolves with a result object containing the task summary, list of modified files, and the agent’s exit status.
Spinning Up the App-Server
The app-server module exposes an HTTP interface:
codex serve --helpcodex serve --port4200Security: Check whether codex serve binds to localhost only by default. If it binds to 0.0.0.0, the server is exposed to the network without authentication. Add --host 127.0.0.1 if supported, and always place the server behind your own authentication and rate-limiting layer in production.
curl --max-time 30-X POST http://localhost:4200/exec -H"Content-Type: application/json"-H"Authorization: Bearer ${CODEX_SERVER_TOKEN}"-d'{"task": "Refactor database queries in src/db/ to use parameterized statements","approvalPolicy": "full-auto","maxTurns": 15}'Note: The --max-time 30 flag prevents the request from blocking indefinitely if the server hangs. The Authorization header ensures the endpoint is not called without credentials. If codex serve does not enforce token validation, place it behind a reverse proxy that does.
The server returns a JSON payload that matches the SDK result structure. This lets product teams embed Codex behind their own authentication and rate-limiting layers without managing CLI processes.
The three runtime modes map to a three-step adoption path: try it interactively, script it with
codex exec, then embed the SDK or app-server into products and internal tools.
Implementation Checklist
Install and Authenticate
- Confirm the package is published:
npm show @openai/codex version. - Install Codex CLI via npm (
npm install -g @openai/codex@0.1.0, pin the version) or Homebrew (brew install openai/tap/codex, confirm the tap exists first). - Authenticate using
codex author by exportingOPENAI_API_KEYin your shell profile. If using a.envfile, ensure it is listed in.gitignore. - Verify the installation with
codex --version.
Validate and Explore
- Confirm
codex execis available:codex exec --help. - Run a first interactive session with
codexto familiarize yourself with the prompt UI and slash commands. - Test
codex execone-shot on a sample repository with a low-risk task like generating documentation.
Integrate and Monitor
- Choose an approval policy (
suggest,auto-edit, orfull-auto) matched to your trust level and automation context. - Add the appropriate CI workflow file (GitHub Actions YAML, GitLab CI YAML, or portable shell script) to your repository.
- Store
OPENAI_API_KEYin your CI platform’s secrets manager, never in the repository itself. - Set
--max-turnsand--timeoutbudget limits on every CI invocation to control cost and prevent runaway runs. - Monitor token usage in the OpenAI dashboard after the first CI run to establish a cost baseline before scaling.
Where Codex CLI Fits in Your Toolchain
The most practical next step is adding a single codex exec task to an existing CI pipeline this week, whether that is a PR review, a documentation pass, or a lint-and-fix job. Run one task, check token consumption on the OpenAI dashboard, and extrapolate before scaling to production pipelines. The exit codes integrate cleanly with any runner.
The fullI GitHub repository and the official OpenAI documentation
Matt is the co-founder of SitePoint, 99designs and Flippa. He lives in Vancouver, Canada.


