Setting up Codex
This walks a self-managed team through turning OpenAI's Codex CLI on your own machine into an AI employee connected to HQ. If cln.work runs your infrastructure, you do not need this page, we set Codex up for you.
Note
Choose Codex as the runtime when you create or reconfigure the AI employee, then generate and download the bundle for your operating system. Everything below assumes you already have that download. See Creating an AI employee for the wizard walkthrough.
What you need
- The Codex CLI installed (
https://developers.openai.com/codex). - An OpenAI account you can log in with.
- The downloaded bundle for this AI employee, extracted somewhere on disk. Codex
reads
AGENTS.mdand the skills under.agents/skills/from the bundle's workspace folder, so keep the extracted folder as the employee's permanent home rather than moving files out of it.
Install
-
Log in to Codex first.
codex loginOr, for an API-key-based setup:
codex login --with-api-key -
Run the install script from the extracted bundle.
bash install.sh # Mac / Linux.\install.ps1 # Windows
The script does the following, in order, and stops with a clear message if a step fails:
- Confirms
codexis on your PATH and that you are logged in. - Prompts for the HQ API key for this employee (from the AI Employees page) and
writes it to
.env, unless it is already set in your environment. - Registers the
hqMCP server with Codex, pointing it at your workspace URL and telling it to read the bearer token from the API key's environment variable rather than storing the token itself. - Marks the bundle's workspace directory trusted in
~/.codex/config.toml, so Codex does not prompt you about it every session. - Runs the MCP verification probe. This calls
codex execwith a prompt that lists every tool thehqserver exposes and calls the heartbeat tool, then checks the output. A green check means Codex can already see your tools and successfully called one. A failure here is an auth or connectivity problem, not a Codex bug, see Troubleshooting below for the two ways it commonly fails. - Registers the scheduled work (heartbeat and any morning brief, end-of-day report, or weekly summary jobs you turned on) with cron on Mac and Linux, or Task Scheduler on Windows.
If you would rather wire things up by hand, merge codex/config-snippet.toml into
~/.codex/config.toml yourself, substituting the real absolute path for the
<WORKSPACE_PATH> placeholder.
Slack
The bundle includes a small Node runner (in runner/) that keeps a real-time Slack
connection open so the employee can respond to DMs and mentions as they happen,
separate from the scheduled heartbeat.
-
Set
SLACK_BOT_TOKEN(xoxb-...) andSLACK_APP_TOKEN(xapp-...) in.env. The app token is required because the runner uses Socket Mode for real-time delivery. -
Start the runner:
bash start-runner.sh # Mac / Linux.\start-runner.ps1 # Windows
Keep the runner running in the background (a terminal tab, a screen/tmux session,
or a service manager of your choice) for Slack messages to arrive in real time. If it
is not running, the employee still works, it just only picks things up on its next
scheduled heartbeat rather than immediately.
Good to know: one task at a time
The runner queues every trigger, Slack messages, the HQ urgent watcher, and incoming
webhooks, and runs one codex exec at a time rather than in parallel. This is
deliberate: concurrent codex exec processes race on ~/.codex/auth.json token
refresh, so running two at once risks corrupting the shared auth state. Requests that
arrive while the employee is busy simply wait their turn in the queue.
If replies seem stuck, check the runner logs first. A hung codex exec invocation is
automatically killed after 10 minutes so it can never block the queue forever, but a
run of slow ticks can still make a reply feel delayed while it waits in line.
Scheduled work
install.sh / install.ps1 register the employee's scheduled jobs for you, so there
is nothing extra to run:
- Mac and Linux: a cron entry per job (heartbeat, and any of morning brief, end-of-day report, or weekly summary you enabled in the wizard).
- Windows: the same jobs registered as Task Scheduler tasks.
Each tick shells out to codex exec with a fixed prompt for that job, gated by a
lightweight pre-check that skips the run entirely if there is no new work, so an idle
employee does not burn tokens on empty heartbeats.
Troubleshooting
Bearer auth fails
If the hq server returns 401, check that the API key environment variable is
actually exported in the shell Codex runs in:
echo $<NAME>_HQ_API_KEY
This should print a value, not nothing. A common mistake is setting the key in .env
but then starting codex from a shell that never sourced it.
Ignore any codex mcp login suggestion Codex prints for the hq server. That
command is for OAuth-based MCP servers only. The hq server uses a static bearer
token, and Codex prompting you to run codex mcp login here is a known upstream bug
(openai/codex#26760). Fix the
environment variable instead, do not attempt to log in.
Connected but zero tools, or the probe fails
Some HTTP MCP servers hit a known Codex issue where codex mcp list shows the hq
server registered, but no tools ever show up in a session
(openai/codex#11284). If you hit
this, fall back to a stdio bridge instead of fighting the native HTTP transport. Keep
the token out of config.toml entirely by passing it through an environment variable
inside a small wrapper script:
cat > hq-mcp-bridge.sh <<'SH'
#!/usr/bin/env sh
exec npx -y supergateway --streamableHttp "<your MCP URL>" --oauth2Bearer "$<NAME>_HQ_API_KEY"
SH
chmod +x hq-mcp-bridge.sh
codex mcp remove hq
codex mcp add hq -- /absolute/path/hq-mcp-bridge.sh
Replace <your MCP URL> with the URL from codex/config-snippet.toml and
<NAME>_HQ_API_KEY with your employee's actual key variable name. The wrapper still
reads the token from your environment at launch time, so it never lands in plaintext
in Codex's config. Keep in mind that while the bridge is running, the resolved token
is visible in the local process list (ps, or Task Manager on Windows) to other users
of the same machine, so use a single-user account if you are on a shared host.
MCP tool calls get cancelled in headless runs
In headless mode (no interactive approver attached), Codex can auto-cancel MCP tool
calls rather than run them, which shows up as tools being listed correctly but the
probe's run_heartbeat call failing or never completing
(openai/codex#16685). Check your
approval configuration (for example --ask-for-approval and your sandbox settings)
and make sure cron/scheduled invocations are not left waiting on an approval that
nobody is there to grant.
Run Codex from the workspace directory
Codex's skills discovery only checks the current working directory when the folder is not a git repository, which the bundle's workspace is not. Always start Codex from inside the extracted bundle:
cd ~/<your-employee-folder>
codex
Running it from anywhere else means .agents/skills/ is invisible and the employee
loses its module playbooks.
Renaming your employee requires a bundle re-download
The API key's environment variable name and the MCP URL slug are both derived from the employee's name at the moment you generate the bundle. Renaming the employee in HQ afterward does not update files already on disk, download a fresh bundle and re-run install rather than hand-editing the old one.
Switching runtimes
If you are moving this employee off Codex onto a different runtime:
- Stop the Slack runner if it is running.
- Remove the MCP registration:
codex mcp remove hq. - Remove the trust entry for the workspace directory from
~/.codex/config.toml. - Switch the runtime in HQ's wizard and download the new bundle.