Output & Policy

Config

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-…"
  }
}
KeyTypeDefaultNotes
defaultAgentstring"codex"Used when top-level prompt, exec, cancel, set*, sessions runs without an explicit agent.
defaultPermissionsenum"approve-reads"approve-all / approve-reads / deny-all.
nonInteractivePermissionsenum"deny"deny or fail when no TTY is present.
authPolicyenum"skip"Controls when ACP authenticate is attempted.
ttlinteger300Queue owner idle TTL in seconds. 0 disables idle shutdown.
timeoutnumber | nullnullDefault --timeout in seconds (decimal allowed).
formatenum"text"Default --format.
agentsobject{}Override or add agent commands (see below).
authobject{}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> ….
  • command is required; it can be a single executable or include in-string args ("node ./bin/x.mjs").
  • args is optional. If present, it is appended after the parsed command tokens.
  • Custom agent args arrays 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:

  1. ACPX_AUTH_<METHOD_ID> environment variable, where <METHOD_ID> is the upper-cased ACP auth-method id.
  2. 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:

ValueBehavior
"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--agent escape hatch and unknown positional names.
  • PermissionsdefaultPermissions and non-interactive policy.
  • Output formatsformat default and --json-strict.