acpx is configurable through two JSON files. CLI flags always win over config, and project config wins over global.
#Files and precedence
1. Global ~/.acpx/config.json
2. Project <cwd>/.acpxrc.json
3. CLI flags
Each layer is a partial override merged on top of the previous one. Missing keys inherit; arrays and objects are replaced, not deep-merged (with the exception of the agents map, where keys merge and per-agent objects replace wholesale).
Inspect the resolved view:
acpx config show
Create a global template (only writes if the file does not already exist):
acpx config init
#Supported keys
{
"defaultAgent": "codex",
"defaultPermissions": "approve-all",
"nonInteractivePermissions": "deny",
"authPolicy": "skip",
"ttl": 300,
"timeout": null,
"format": "text",
"agents": {
"my-custom": { "command": "./bin/my-acp-server", "args": ["acp"] }
},
"auth": {
"openai_api_key": "sk-…"
}
}
| Key | Type | Default | Notes |
|---|---|---|---|
defaultAgent | string | "codex" | Used when top-level prompt, exec, cancel, set*, sessions runs without an explicit agent. |
defaultPermissions | enum | "approve-reads" | approve-all / approve-reads / deny-all. |
nonInteractivePermissions | enum | "deny" | deny or fail when no TTY is present. |
authPolicy | enum | "skip" | Controls when ACP authenticate is attempted. |
ttl | integer | 300 | Queue owner idle TTL in seconds. 0 disables idle shutdown. |
timeout | number | null | null | Default --timeout in seconds (decimal allowed). |
format | enum | "text" | Default --format. |
agents | object | {} | Override or add agent commands (see below). |
auth | object | {} | ACP auth-method credential map (see below). |
CLI flags always override these values. For example, --approve-all wins over defaultPermissions: "deny-all".
#The agents map
Custom agents and overrides live here:
{
"agents": {
"my-agent": {
"command": "./bin/my-acp-server",
"args": ["acp", "--profile", "ci"]
},
"codex": {
"command": "/usr/local/bin/codex-acp",
"args": ["--mode", "stable"]
}
}
}
Rules:
- Keys are friendly names you would type at
acpx <name> …. commandis required; it can be a single executable or include in-string args ("node ./bin/x.mjs").argsis optional. If present, it is appended after the parsedcommandtokens.- Custom agent
argsarrays are honored — required adapter sub-commands are no longer dropped silently. - An entry that shares a name with a built-in replaces the built-in for that name.
Project config can shadow global config by re-declaring the same key:
{ "agents": { "codex": { "command": "/usr/local/bin/codex-acp" } } }
Use this to point a particular repo at a vendored or pinned adapter.
#Authentication
ACP authenticate handshakes need credentials. acpx resolves them from two sources, in order:
ACPX_AUTH_<METHOD_ID>environment variable, where<METHOD_ID>is the upper-cased ACP auth-method id.auth.<methodId>value in config.
ACPX_AUTH_OPENAI_API_KEY=sk-… acpx codex 'do the thing'
{ "auth": { "openai_api_key": "sk-…" } }
Ambient provider env vars like OPENAI_API_KEY are still passed through to child agents in their environment, but they do not trigger ACP auth-method selection on their own. This is intentional — it avoids surprise login flows in adapters that interpret an ambient key as "go ahead and authenticate."
authPolicy controls when acpx invokes authenticate at all:
| Value | Behavior |
|---|---|
"skip" | Do not call authenticate. Adapters that need auth must already be logged in. (default) |
"auto" | Call authenticate when the adapter advertises required auth methods. |
#Environment variables
acpx does not define new env vars beyond ACPX_AUTH_*. Other ACP-relevant behavior:
- Session storage path is derived from the OS home directory (
~/.acpx/sessions). - Child adapter processes inherit the current environment by default.
- Some adapters look at their own env vars (e.g.,
QODER_PERSONAL_ACCESS_TOKEN) — see Agents for per-adapter notes.
#Practical config recipes
#Make CI fail rather than deny
{
"defaultPermissions": "approve-reads",
"nonInteractivePermissions": "fail",
"format": "json"
}
#Default to Claude with a longer timeout
{
"defaultAgent": "claude",
"timeout": 1800,
"ttl": 0
}
#Vendor an internal Codex build for one repo
<repo>/.acpxrc.json:
{
"agents": {
"codex": {
"command": "/opt/internal/codex-acp",
"args": ["--profile", "internal-stable"]
}
}
}
#Pin a custom agent name without colliding with a built-in
{
"agents": {
"ci-bot": {
"command": "node ./scripts/ci-acp-bridge.mjs"
}
}
}
Then acpx ci-bot 'run sanity checks' resolves through the registry without any --agent flag.
#See also
- Agents — built-in registry and per-agent notes.
- Custom agents —
--agentescape hatch and unknown positional names. - Permissions —
defaultPermissionsand non-interactive policy. - Output formats —
formatdefault and--json-strict.