paperctl start codex configures Codex for one terminal launch. The ChatGPT desktop app doesn’t launch from your terminal, so it needs a persistent setup instead: one command that points Codex’s shared config at paperd and delivers the plugin the app loads, covering the desktop app, the IDE extension, and ordinary codex launches alike. Codex keeps using its own ChatGPT sign-in — paperd never holds your OpenAI credential.
Prerequisites: paperctl installed and authenticated, with the daemon running.
Point the app at paperd
Preview what would change, then apply it:
paperctl plugin install codex-app --dry-run
paperctl plugin install codex-app
The command reconciles Codex’s shared config file — $CODEX_HOME/config.toml, or ~/.codex/config.toml when CODEX_HOME is unset — and extracts the Paper plugin the app loads. It sets a Paper-owned provider that routes Codex’s traffic through the local paperd proxy while reusing Codex’s own ChatGPT/OpenAI login. It’s safe to run repeatedly: Paper updates only the values it owns, preserves everything else in the file, and writes only when something actually changed.
codex-desktop is accepted as an alias for codex-app. The terminal Codex CLI needs no plugin — it’s captured by redirection, which is what paperctl start codex does, and asking to install a plugin for it says so.
Finish the two steps in Codex
Codex deliberately gates two steps on you, and the install summary lists them. Until both are done the app is configured but its hooks are inert, so sessions arrive without attribution:
- Enable the plugin. In the ChatGPT app’s plugin directory, enable Paper in the Installed row. The app runs the installed cached copy, not the extracted source directory.
- Trust its hooks. Enabling a plugin does not trust its hooks. Run
/hooksand trust theSessionStart,UserPromptSubmit,Stop,SubagentStart, andSubagentStopentries whose source ispaper-codex. If the app’s/hooksselector doesn’t list them, run/hooksin the codex CLI with the sameCODEX_HOME— trust is shared state recorded inconfig.toml, so doing it once in the CLI covers the app.
Then fully quit and restart the app. Codex reads its config at startup, so sessions started before the restart are not captured.
Trust binds to the exact hook-definition hash, which means every plugin upgrade re-requires it. After a paperctl upgrade that ships new hooks, expect to run /hooks again.
Verify the capture
Start a conversation in the ChatGPT app, then:
paperctl sessions list
The session appears at the top with its turn count, cost, and status, and shows up in paper console moments later. Codex subagents — spawn_agent threads, however deeply nested — appear inside that one session, each under the tool call that spawned it, and the session’s usage and cost totals include them. See How capture works for the full picture.
API-key mode
If you route Codex with an OpenAI API key instead of a ChatGPT sign-in:
paperctl plugin install codex-app --auth api-key
This mode reads OPENAI_API_KEY from the Codex process environment. A normal macOS app launch doesn’t inherit your shell’s environment variables, so prefer the default ChatGPT sign-in mode for the desktop app unless you already manage app environment variables.
Remove it
paperctl plugin uninstall codex-app --dry-run
paperctl plugin uninstall codex-app
This reverses the install in the order that keeps the app working at every step: the Paper provider declaration first, then the Paper-owned handoff files, then the extracted marketplace. Codex’s own cached copy of the plugin is left registered — removing it by spec would also remove a copy you installed by hand — so the command prints how to remove that yourself. It runs even when daemon.toml is unparseable, which is exactly when you tend to want it.
If something’s off
- Sessions from the app aren’t captured: run
paperctl plugin install codex-app --dry-run. If it reports drift — a Codex update can rewrite the config — runpaperctl plugin install codex-appand restart the app. - Sessions arrive but aren’t attributed to you: the hooks are installed but untrusted. Run
/hooksas above; a plugin upgrade silently un-trusts them. - The command reports it repaired settings: restart the app before continuing; the running session keeps its old config and isn’t sent to paper.
- Daemon not running:
paperctl status, then CLI troubleshooting.