Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use Codex (OpenAI's codex app-server) as a full agent provider — planning, tool orchestration, MCP tools, server-side history, session resume — alongside or instead of Claude. ChatGPT subscription or OpenAI API key, vault-only via OneCLI. Per-group via `ncl groups config update --provider codex`. Distinct from using OpenAI as an MCP tool (where Claude remains the planner).
.claude/skills/nanocoai-add-codex/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 11 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 15% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-07 | ✗→✓ | ▲ Improved | -3% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 20% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 29% | 0% |
> Shortcut: pnpm exec tsx setup/index.ts --step provider-auth codex performs this whole install (manifest-driven from the providers branch: files, barrels, CLI manifest entry, image rebuild) plus auth in one command. The steps below are the same operations, for agent-driven or manual application.
NanoClaw selects each group's agent backend from container_configs.provider (default claude). This skill installs the Codex provider: copy the payload from the providers branch, append one import to each of the three provider barrels, add the pinned Codex CLI to the container manifest (container/cli-tools.json), rebuild, then run the vault auth walk-through.
The provider runs codex app-server as a child process speaking JSON-RPC over stdio: native streaming, MCP tools, server-side conversation history (the continuation is a thread id, no on-disk transcript). Credentials are vault-only: OneCLI serves a sentinel auth.json stub into the container and swaps the real ChatGPT token or API key on the wire — no key in .env, nothing readable in the container.
The mechanical steps under Install carry nc: directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it.
Check whether the payload is already wired (a prior apply, or a trunk that still carries it). All of these present means installed — skip to Authenticate:
src/providers/codex.ts and src/providers/codex-agents-md.tscontainer/agent-runner/src/providers/codex.ts and codex-app-server.tssetup/providers/codex.tsimport './codex.js'; in src/providers/index.ts, container/agent-runner/src/providers/index.ts, and setup/providers/index.ts@openai/codex entry in container/cli-tools.jsonFetch the providers branch and copy the Codex payload into all three trees (additive — overwrite each file, never merge the branch). The host files are the provider contribution + AGENTS.md compose + their guards; the container files are the provider runtime (turn loop, JSON-RPC wrapper, native memory SessionStart hook, per-exchange archiver) + their guards; the setup file is the picker entry + vault auth walk-through; container/AGENTS.md is the runtime-contract base the composed AGENTS.md embeds.
nc:copy from-branch:providerssrc/providers/codex.ts src/providers/codex-agents-md.ts src/providers/codex-registration.test.ts src/providers/codex-host-contribution.test.ts src/providers/codex-agents-md.test.ts container/agent-runner/src/providers/codex.ts container/agent-runner/src/providers/codex-app-server.ts container/agent-runner/src/providers/exchange-archive.ts container/agent-runner/src/providers/exchange-archive.test.ts container/agent-runner/src/providers/codex-registration.test.ts container/agent-runner/src/providers/codex.factory.test.ts container/agent-runner/src/providers/codex.turns.test.ts container/agent-runner/src/providers/codex-app-server.test.ts container/agent-runner/src/providers/codex-cli-tools.test.ts setup/providers/codex.ts setup/providers/codex.test.ts setup/providers/codex-registration.test.ts container/AGENTS.md
Append the self-registration import to each of the three provider barrels (skipped if the line is already present). Each barrel-registration test imports its real barrel and asserts codex is registered — they go red the moment a barrel line is missing or drifts.
nc:append to:src/providers/index.tsimport './codex.js';
nc:append to:container/agent-runner/src/providers/index.tsimport './codex.js';
nc:append to:setup/providers/index.tsimport './codex.js';
The agent's global Node CLIs install from container/cli-tools.json (a json-merge seam), not hand-edited Dockerfile layers. Add Codex by appending one entry — idempotent on name, so a re-run is a no-op. @openai/codex has no native postinstall, so no onlyBuilt. The Dockerfile already installs every manifest entry via pinned pnpm install -g; no Dockerfile edit is needed.
nc:json-merge into:container/cli-tools.json key:name{ "name": "@openai/codex", "version": "0.138.0" }
The version (0.138.0) is the canonical pin — this SKILL.md is the source of truth.
nc:run effect:buildpnpm run build pnpm exec tsc -p container/agent-runner/tsconfig.json --noEmit ./container/build.sh
nc:run effect:testpnpm vitest run src/providers/codex-registration.test.ts src/providers/codex-host-contribution.test.ts src/providers/codex-agents-md.test.ts setup/providers/
nc:run effect:testcd container/agent-runner && bun test src/providers/
The registration tests import only the real barrels — they go red if a barrel line is missing, a barrel fails to evaluate, or the payload is broken.
nc:run effect:externalpnpm exec tsx setup/index.ts --step provider-auth codex
The same walk-through fresh installs get from the setup picker: ChatGPT subscription (browser login or device pairing) or an OpenAI API key, landed in the OneCLI vault. Idempotent — it short-circuits when a matching secret already exists. It finishes with the install check.
Per group:
bashncl groups config update --id <group-id> --provider codex ncl groups restart --id <group-id>
Switching is an operator action — run it from the host. Every provider uses the same memory/ tree, so memory carries across automatically. Run /migrate-memory only when upgrading a group that still has legacy .seed.md, CLAUDE.local.md, or unindexed imported memory. See docs/provider-migration.md.
New groups are created on the instance default (DEFAULT_AGENT_PROVIDER in .env, or claude when unset). Installing this skill wires codex in but does NOT change that default — "installed" is not "authenticated", so the default stays claude until you opt in explicitly.
After install, ask the operator before flipping it:
> "Codex is installed. Default new agent groups to codex? Existing groups keep their current provider."
On yes — set it, then restart the host so it takes effect:
bashpnpm exec tsx setup/index.ts --step set-env -- --key DEFAULT_AGENT_PROVIDER --value codex launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS; Linux: systemctl --user restart nanoclaw
This affects only groups created afterward. Per-group ncl groups config update --provider still overrides the default in either direction. Creation itself stays provider-agnostic (no --provider flag — provider is a DB property stamped from the instance default at creation).
grep 'Container exited non-zero' logs/nanoclaw.error.log — the stderrTail carries the reason (e.g. Unknown provider: codex. Registered: claude means the barrels aren't wired in the running build).Error: spawn codex ENOENT on every message: the image predates the manifest entry — re-run ./container/build.sh.pnpm exec tsx setup/index.ts --step provider-auth codex (subscription re-login updates the vault copy).| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 9,631 | 67,012 | +596% | 1 | 1 | 0% | 1,506 | 2,304 | +53% | 0 | 0 | — |
case-02 | fail→fail | 4,194 | 5,461 | +30% | 1 | 1 | 0% | 208 | 2,254 | +984% | 0 | 0 | — |
case-03 | fail→fail | 7,067 | 11,863 | +68% | 1 | 1 | 0% | 243 | 2,269 | +834% | 0 | 0 | — |
case-04 | fail→pass | 14,978 | 7,935 | -47% | 1 | 1 | 0% | 3,015 | 3,465 | +15% | 0 | 0 | — |
case-05 | fail→fail | 12,209 | 7,048 | -42% | 1 | 1 | 0% | 2,154 | 3,294 | +53% | 0 | 0 | — |
case-06 | fail→pass | 9,567 | 2,535 | -74% | 1 | 1 | 0% | 1,498 | 2,464 | +64% | 0 | 0 | — |
case-07 | fail→pass | 14,414 | 2,248 | -84% | 1 | 1 | 0% | 2,460 | 2,391 | -3% | 0 | 0 | — |
case-08 | fail→pass | 14,680 | 4,076 | -72% | 1 | 1 | 0% | 2,219 | 2,662 | +20% | 0 | 0 | — |
case-09 | fail→pass | 11,788 | 2,849 | -76% | 1 | 1 | 0% | 1,869 | 2,418 | +29% | 0 | 0 | — |
case-10 | fail→pass | 8,718 | 2,144 | -75% | 1 | 1 | 0% | 1,490 | 2,328 | +56% | 0 | 0 | — |
case-11 | fail→pass | 7,415 | 3,192 | -57% | 1 | 1 | 0% | 1,251 | 2,277 | +82% | 0 | 0 | — |
case-12 | fail→pass | 6,503 | 2,944 | -55% | 1 | 1 | 0% | 1,301 | 2,465 | +89% | 0 | 0 | — |
case-13 | fail→pass | 8,885 | 2,192 | -75% | 1 | 1 | 0% | 1,882 | 2,448 | +30% | 0 | 0 | — |
case-14 | pass→pass | 9,840 | 2,833 | -71% | 1 | 1 | 0% | 1,668 | 2,507 | +50% | 0 | 0 | — |
case-15 | fail→pass | 10,198 | 10,089 | -1% | 1 | 1 | 0% | 1,003 | 2,731 | +172% | 0 | 0 | — |
case-16 | fail→pass | 12,795 | 5,514 | -57% | 1 | 1 | 0% | 1,818 | 2,431 | +34% | 0 | 0 | — |
case-17 | fail→pass | 8,666 | 2,535 | -71% | 1 | 1 | 0% | 1,272 | 2,328 | +83% | 0 | 0 | — |
case-18 | fail→pass | 10,918 | 4,016 | -63% | 1 | 1 | 0% | 1,737 | 2,658 | +53% | 0 | 0 | — |
case-19 | fail→pass | 13,121 | 4,008 | -69% | 1 | 1 | 0% | 2,472 | 2,931 | +19% | 0 | 0 | — |
case-20 | fail→pass | 7,506 | 2,142 | -71% | 1 | 1 | 0% | 1,304 | 2,386 | +83% | 0 | 0 | — |
case-21 | pass→pass | 9,886 | 1,932 | -80% | 1 | 1 | 0% | 1,735 | 2,384 | +37% | 0 | 0 | — |
case-22 | fail→pass | 11,061 | 3,931 | -64% | 1 | 1 | 0% | 1,587 | 2,328 | +47% | 0 | 0 | — |
case-23 | fail→pass | 12,030 | 4,060 | -66% | 1 | 1 | 0% | 2,036 | 2,736 | +34% | 0 | 0 | — |
case-24 | pass→pass | 4,044 | 1,006 | -75% | 1 | 1 | 0% | 651 | 2,146 | +230% | 0 | 0 | — |
case-25 | fail→pass | 15,653 | 1,907 | -88% | 1 | 1 | 0% | 2,487 | 2,287 | -8% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted, and 22 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +72 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.