Codex agent
Run a self-contained OpenAI Codex agent that answers your Chamade DMs and calls — headless, 24/7, one command. No UI, no human in the loop.
Overview
Claude Code wakes on Chamade's push notifications natively (see Claude Code). Codex doesn't — its harness ignores MCP notifications, and there is no way to inject into a live interactive TUI session. So the Chamade npm shim ships an autonomous launcher: it spawns its own codex app-server, manages the task-scoped threads it owns, drives the Chamade push channel, and injects every inbound DM / call event as a Codex turn. The agent replies through the chamade_* tools. This keeps Chamade a router, not a runtime — it pokes a Codex engine, it doesn't host one.
The result is a background agent: someone DMs your connected Telegram / Discord / Teams / … account, Codex answers, you never touch a terminal.
Prerequisites
- Node.js 22+ (the agent uses Node's built-in WebSocket).
- Codex CLI installed and logged in — run
codex loginonce. The launcher spawns a realcodex app-server, so it needs valid Codex auth in~/.codex. - A Chamade agent key (
chmd_…) from dashboard → Agents, with at least one platform connected. - That Chamade agent must have no AI provider configured. Codex is the brain here. If the agent holding the key also has a provider (Anthropic, OpenAI, …) set in the dashboard, both Codex and Chamade's built-in provider will answer the same DM — double replies.
Quick start recommended
Install the shim and launch the agent. That's it — no codex mcp add step (the launcher injects the Chamade tools into its engine for you).
On startup you'll see the agent hash and chamade push session open. Now DM your connected platform and the agent replies on that channel. The Codex engine starts lazily when the first turn arrives.
The key is saved to ~/.chamade/agents/<hash>.json (mode 0600) on first run, so later launches use chamade-mcp agent run --agent <hash> and keep the key off the process arguments. The default instance is https://chamade.io; pass --url only to target a different Chamade deployment.
Configuring Codex (model, sandbox, persona)
Chamade maintains no Codex settings. The agent spawns a standard codex app-server, so everything is inherited from your own Codex config — the same file the codex CLI uses.
- Model, reasoning effort, personality — set
model,model_reasoning_effort,personalityin~/.codex/config.toml. The agent picks them up on its next turn. - What the agent can do — governed by
sandbox_mode. Wiring Codex to a chat is usually about getting work done — running commands, editing files — soworkspace-write(Codex's agentic default) ordanger-full-accessis what you want. Pickread-onlyonly when you specifically want a read/answer-only assistant. - Persona / instructions — drop an
AGENTS.mdin the agent's working directory (seed it with--cwd /pathon first run). Codex discovers it the same way it does for the CLI.
Anyone who can DM the connected account drives the agent at its sandbox_mode level — with workspace-write or danger-full-access, that means running commands and editing files on the host. Scope who can reach the account accordingly: a private bot, your own account, a trusted channel. If it's reachable by people you don't fully trust, drop to read-only.
Slash-commands don't work over a DM. /model, /approvals and friends are a Codex TUI feature; an inbound DM is injected as plain user text, so the agent just talks about /model rather than switching anything. Configure through the TOML, not by messaging the bot.
Want a different config per agent (e.g. one model for your Telegram agent, another for Discord)? Codex profiles aren't available on the app-server, so use a separate Codex home: CODEX_HOME=/path/to/home chamade-mcp agent run --agent <hash>. That directory needs its own config.toml and an auth.json (run codex login there, or symlink ~/.codex/auth.json).
Keeping it running
The agent self-heals while it runs — if the network blips or the Codex engine crashes, it reconnects and resumes its stored sessions in-process, so you don't lose the conversations. The only thing it can't do alone is start itself after a reboot. Three commands cover the lifecycle:
| Command | What it does |
|---|---|
chamade-mcp agent run --agent <hash> | Resume the stored agent and all of its sessions lazily. Add --fresh to replace only the default Codex session. |
chamade-mcp agent install-service --agent <hash> | Write the OS boot-start unit for this agent (systemd --user on Linux, launchd on macOS, guidance on Windows), then print the one-liner to enable it. |
chamade-mcp agent stop --agent <hash> | Stop exactly that supervisor using its stored PID; no process-name matching. |
Running several agents (multi-key)
One machine can run many agents — one per key. Each gets its own engine process, session registry, and config entry; everything is derived from the key's <hash>, so they never collide. Select which one a command targets with --agent <hash> (or --key the first time).
A second launch on the same key refuses to start (it would answer every DM twice). Different keys are independent.
How it works
The launcher is part of the @chamade/mcp-server shim. It spawns one lazy codex app-server, injects Chamade's MCP tools scoped to your key via Codex -c config overrides (so each agent replies with its own key), manages task-scoped threads, and drives mcp-remote as the push client on the same channel Claude Code uses. Each session is floor-gated (one turn at a time, queued and coalesced while a turn is in flight) so the agent never writes over an in-flight turn. Voice audio is unchanged — see Voice providers for hosted STT/TTS, or the raw-PCM audio WebSocket.
Interactive use (DMs landing in your live Codex TUI session) is not possible today: Codex spawns a private single-client app-server with no injection hook. The autonomous agent is the supported shape.
Troubleshooting
"codex app-server did not become ready" / engine won't start
- Codex not logged in — run
codex loginand confirm~/.codex/auth.jsonexists. codexnot on PATH of the shell that launched the agent (common under a service). Use an absolute path or ensure the unit's environment includes it.- The
could not find bubblewrap on PATHline is a harmless warning — Codex falls back to a bundled sandbox.
The peer gets two replies to every message
The Chamade agent holding this key also has an AI provider configured, so Chamade's built-in dispatcher answers in addition to Codex. Remove the provider from that agent in dashboard → Agents — Codex should be the only brain.
DMs arrive but the agent never answers
- Confirm the agent is live — the log should end with
autonomous agent liveandchamade push session open. - Check the key is in scope for the account: the agent holding it must be active and a member of the connected platform in dashboard → Agents.
- An
already running for this keymessage means another instance owns the lock — only one agent per key.
Context resets after a restart
Relaunch with chamade-mcp agent run --agent <hash>. Stored sessions resume lazily on their next message; --fresh deliberately replaces only the default Codex session. The boot service uses the same resume command.
Still stuck?
Email [email protected] with the launcher's stderr (it logs each step) and a timestamp — we can correlate against server logs.
