Skip to content

Latest commit

 

History

History
249 lines (192 loc) · 11.1 KB

File metadata and controls

249 lines (192 loc) · 11.1 KB
title Config
description Global and project JSON config files, supported keys, precedence rules, the agents map, and authentication via env or 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 rather than deep-merged, except that agents and auth merge by key. A project agent entry replaces the entire same-named global entry, and a project auth value replaces the same method's global value. Other global agent and auth entries remain available.

When top-level --cwd or --mcp-config flags repeat, the final occurrence wins. Project configuration comes from that effective cwd, and relative MCP config paths resolve against it regardless of flag order.

Inspect the resolved view:

acpx config show

Create a global template (only writes if the file does not already exist):

acpx config init

On POSIX systems, newly created config files use 0600 permissions and a newly created .acpx directory uses 0700. Existing config files are never replaced.

Supported keys

{
  "defaultAgent": "codex",
  "defaultPermissions": "approve-all",
  "nonInteractivePermissions": "deny",
  "authPolicy": "skip",
  "ttl": 300,
  "timeout": null,
  "format": "text",
  "mcpServers": [
    {
      "name": "local-tools",
      "type": "stdio",
      "command": "./bin/mcp-server"
    }
  ],
  "agents": {
    "my-custom": { "argv": ["./bin/my-acp-server", "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.
mcpServers array [] MCP servers sent to new and loaded ACP sessions. Project values replace global values.
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".

Use --mcp-config <path> when MCP servers belong to a session or automation job rather than the working tree. The file must contain the same top-level mcpServers array shown above; it replaces the project/global mcpServers value for that invocation. Relative paths resolve from --cwd.

MCP env and headers entries use { "name": "…", "value": "…" } pairs. Values are literal strings: empty strings and leading or trailing whitespace are preserved when creating or loading a session. Names must be non-empty and are trimmed.

acpx --cwd /workspace --mcp-config /run/job-mcp.json codex 'use the configured tools'

An existing persistent session cannot switch MCP configurations while its queue owner is live. Close that session first, then retry with the new --mcp-config file.

The agents map

Custom agents and overrides live here:

{
  "agents": {
    "my-agent": {
      "argv": ["./bin/my-acp-server", "acp", "--profile", "ci"]
    },
    "codex": {
      "argv": ["/usr/local/bin/codex-acp", "--mode", "stable"]
    }
  }
}

Rules:

  • Keys are friendly names you would type at acpx <name> ….
  • Names such as constructor and __proto__ work like any other custom name and remain visible in config show.
  • argv is the preferred form and is required for custom agent launches on Windows. Its first item is the executable and every remaining item is passed literally as one argument.
  • Windows batch wrappers, including extensionless commands, resolve from the selected --cwd; relative PATH directories use that same cwd.
  • Legacy { "command": "…", "args": […] } entries migrate when command is an unquoted executable with no whitespace. Quoted executables and inline arguments are rejected as ambiguous; move the complete launch to argv.
  • A legacy command without args remains a raw command string for Unix compatibility. Windows rejects it with migration guidance because inferring argv would corrupt paths and quoting.
  • The raw --agent <command> escape hatch is likewise Unix-only.
  • Windows cannot execute .sh files directly. Name the interpreter explicitly, for example "argv": ["bash", "C:\\tools\\bin\\agent.sh"]; acpx does not discover or infer an interpreter.
  • On Windows, close and recreate custom-agent sessions created by an older acpx release so their records persist structured argv. Known built-in commands migrate automatically.
  • 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": { "argv": ["/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-…" } }

The global and project auth maps merge by method ID. An empty project auth object does not clear global credentials; matching project keys replace the corresponding global values. Matching ACPX_AUTH_* environment variables still take precedence over the merged config map.

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."

When adding authentication aliases to the child environment, acpx preserves inherited values, including empty strings. On Windows, differently cased names refer to the same environment variable; Unix names remain case sensitive.

When an adapter advertises auth methods, acpx invokes authenticate if it finds a matching ACPX_AUTH_* environment variable or auth config value. authPolicy controls what happens when no matching credential is available:

Value Behavior
"skip" Continue without ACP authentication and let the adapter handle auth itself. (default)
"fail" Fail immediately instead of continuing without a matching ACP credential.

Environment variables

ACPX_CLAUDE_INCLUDE_USER_SETTINGS=1 makes built-in claude sessions include Claude Code user settings. By default, they load only project and local settings to avoid globally enabled channel or daemon plugins interfering with spawned ACP sessions.

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.
  • Embedded clients can persist per-session overrides through SessionAgentOptions.env; environment variable names retain their exact casing when saved and reloaded.
  • 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.

Embedded session MCP servers

In acpx/runtime, AcpRuntimeOptions.mcpServers accepts either an array or a synchronous resolver receiving { sessionKey, cwd, agentCommand, agentArgv }. The resolver returns the complete server array for a new connection. ACPX calls it for session creation, reconnection, and controls or close operations that need a new connection. Existing retained connections keep their original servers. Initialization-only health probes do not invoke the resolver.

The runtime does not store the resolver or its result in session records. Hosts must supply it again after restart. Configuration files continue to accept arrays only. See Permissions for turn-owned permission callbacks on a shared runtime.

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.

Embedded hosts can also supply a transient runtime environment without persisting child-process settings in a session.